Skip to content

Commit

Permalink
TOMOYO: Add numeric values grouping support.
Browse files Browse the repository at this point in the history
This patch adds numeric values grouping support, which is useful for grouping
numeric values such as file's UID, DAC's mode, ioctl()'s cmd number.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
  • Loading branch information
Tetsuo Handa authored and James Morris committed Aug 2, 2010
1 parent babcd37 commit 4c3e9e2
Show file tree
Hide file tree
Showing 6 changed files with 454 additions and 1 deletion.
2 changes: 1 addition & 1 deletion security/tomoyo/Makefile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
obj-y = common.o realpath.o tomoyo.o domain.o file.o gc.o path_group.o
obj-y = common.o realpath.o tomoyo.o domain.o file.o gc.o path_group.o number_group.o
161 changes: 161 additions & 0 deletions security/tomoyo/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,159 @@ static bool tomoyo_print_name_union(struct tomoyo_io_buffer *head,
return tomoyo_io_printf(head, " %s", ptr->filename->name);
}

/**
* tomoyo_parse_ulong - Parse an "unsigned long" value.
*
* @result: Pointer to "unsigned long".
* @str: Pointer to string to parse.
*
* Returns value type on success, 0 otherwise.
*
* The @src is updated to point the first character after the value
* on success.
*/
u8 tomoyo_parse_ulong(unsigned long *result, char **str)
{
const char *cp = *str;
char *ep;
int base = 10;
if (*cp == '0') {
char c = *(cp + 1);
if (c == 'x' || c == 'X') {
base = 16;
cp += 2;
} else if (c >= '0' && c <= '7') {
base = 8;
cp++;
}
}
*result = simple_strtoul(cp, &ep, base);
if (cp == ep)
return 0;
*str = ep;
switch (base) {
case 16:
return TOMOYO_VALUE_TYPE_HEXADECIMAL;
case 8:
return TOMOYO_VALUE_TYPE_OCTAL;
default:
return TOMOYO_VALUE_TYPE_DECIMAL;
}
}

/**
* tomoyo_print_ulong - Print an "unsigned long" value.
*
* @buffer: Pointer to buffer.
* @buffer_len: Size of @buffer.
* @value: An "unsigned long" value.
* @type: Type of @value.
*
* Returns nothing.
*/
void tomoyo_print_ulong(char *buffer, const int buffer_len,
const unsigned long value, const u8 type)
{
if (type == TOMOYO_VALUE_TYPE_DECIMAL)
snprintf(buffer, buffer_len, "%lu", value);
else if (type == TOMOYO_VALUE_TYPE_OCTAL)
snprintf(buffer, buffer_len, "0%lo", value);
else if (type == TOMOYO_VALUE_TYPE_HEXADECIMAL)
snprintf(buffer, buffer_len, "0x%lX", value);
else
snprintf(buffer, buffer_len, "type(%u)", type);
}

/**
* tomoyo_print_number_union - Print a tomoyo_number_union.
*
* @head: Pointer to "struct tomoyo_io_buffer".
* @ptr: Pointer to "struct tomoyo_number_union".
*
* Returns true on success, false otherwise.
*/
bool tomoyo_print_number_union(struct tomoyo_io_buffer *head,
const struct tomoyo_number_union *ptr)
{
unsigned long min;
unsigned long max;
u8 min_type;
u8 max_type;
if (!tomoyo_io_printf(head, " "))
return false;
if (ptr->is_group)
return tomoyo_io_printf(head, "@%s",
ptr->group->group_name->name);
min_type = ptr->min_type;
max_type = ptr->max_type;
min = ptr->values[0];
max = ptr->values[1];
switch (min_type) {
case TOMOYO_VALUE_TYPE_HEXADECIMAL:
if (!tomoyo_io_printf(head, "0x%lX", min))
return false;
break;
case TOMOYO_VALUE_TYPE_OCTAL:
if (!tomoyo_io_printf(head, "0%lo", min))
return false;
break;
default:
if (!tomoyo_io_printf(head, "%lu", min))
return false;
break;
}
if (min == max && min_type == max_type)
return true;
switch (max_type) {
case TOMOYO_VALUE_TYPE_HEXADECIMAL:
return tomoyo_io_printf(head, "-0x%lX", max);
case TOMOYO_VALUE_TYPE_OCTAL:
return tomoyo_io_printf(head, "-0%lo", max);
default:
return tomoyo_io_printf(head, "-%lu", max);
}
}

/**
* tomoyo_parse_number_union - Parse a tomoyo_number_union.
*
* @data: Number or number range or number group.
* @ptr: Pointer to "struct tomoyo_number_union".
*
* Returns true on success, false otherwise.
*/
bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num)
{
u8 type;
unsigned long v;
memset(num, 0, sizeof(*num));
if (data[0] == '@') {
if (!tomoyo_is_correct_path(data, 0, 0, 0))
return false;
num->group = tomoyo_get_number_group(data + 1);
num->is_group = true;
return num->group != NULL;
}
type = tomoyo_parse_ulong(&v, &data);
if (!type)
return false;
num->values[0] = v;
num->min_type = type;
if (!*data) {
num->values[1] = v;
num->max_type = type;
return true;
}
if (*data++ != '-')
return false;
type = tomoyo_parse_ulong(&v, &data);
if (!type || *data)
return false;
num->values[1] = v;
num->max_type = type;
return true;
}

/**
* tomoyo_is_byte_range - Check whether the string isa \ooo style octal value.
*
Expand Down Expand Up @@ -1750,6 +1903,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
return tomoyo_write_no_rewrite_policy(data, is_delete);
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_PATH_GROUP))
return tomoyo_write_path_group_policy(data, is_delete);
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NUMBER_GROUP))
return tomoyo_write_number_group_policy(data, is_delete);
return -EINVAL;
}

Expand Down Expand Up @@ -1812,6 +1967,12 @@ static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
head->read_var2 = NULL;
head->read_step = 10;
case 10:
if (!tomoyo_read_number_group_policy(head))
break;
head->read_var1 = NULL;
head->read_var2 = NULL;
head->read_step = 11;
case 11:
head->read_eof = true;
break;
default:
Expand Down
61 changes: 61 additions & 0 deletions security/tomoyo/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,20 @@ struct linux_binprm;
#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
#define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
#define TOMOYO_KEYWORD_PATH_GROUP "path_group "
#define TOMOYO_KEYWORD_NUMBER_GROUP "number_group "
#define TOMOYO_KEYWORD_SELECT "select "
#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
/* A domain definition starts with <kernel>. */
#define TOMOYO_ROOT_NAME "<kernel>"
#define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1)

/* Value type definition. */
#define TOMOYO_VALUE_TYPE_INVALID 0
#define TOMOYO_VALUE_TYPE_DECIMAL 1
#define TOMOYO_VALUE_TYPE_OCTAL 2
#define TOMOYO_VALUE_TYPE_HEXADECIMAL 3

/* Index numbers for Access Controls. */
enum tomoyo_mac_index {
TOMOYO_MAC_FOR_FILE, /* domain_policy.conf */
Expand Down Expand Up @@ -211,6 +218,14 @@ struct tomoyo_name_union {
u8 is_group;
};

struct tomoyo_number_union {
unsigned long values[2];
struct tomoyo_number_group *group;
u8 min_type;
u8 max_type;
u8 is_group;
};

/* Structure for "path_group" directive. */
struct tomoyo_path_group {
struct list_head list;
Expand All @@ -219,13 +234,28 @@ struct tomoyo_path_group {
atomic_t users;
};

/* Structure for "number_group" directive. */
struct tomoyo_number_group {
struct list_head list;
const struct tomoyo_path_info *group_name;
struct list_head member_list;
atomic_t users;
};

/* Structure for "path_group" directive. */
struct tomoyo_path_group_member {
struct list_head list;
bool is_deleted;
const struct tomoyo_path_info *member_name;
};

/* Structure for "number_group" directive. */
struct tomoyo_number_group_member {
struct list_head list;
bool is_deleted;
struct tomoyo_number_union number;
};

/*
* tomoyo_acl_info is a structure which is used for holding
*
Expand Down Expand Up @@ -554,9 +584,18 @@ bool tomoyo_parse_name_union(const char *filename,
bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
const struct tomoyo_path_group *group,
const bool may_use_pattern);
/* Check whether the given value matches the given number_group. */
bool tomoyo_number_matches_group(const unsigned long min,
const unsigned long max,
const struct tomoyo_number_group *group);
/* Check whether the given filename matches the given pattern. */
bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
const struct tomoyo_path_info *pattern);

bool tomoyo_print_number_union(struct tomoyo_io_buffer *head,
const struct tomoyo_number_union *ptr);
bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num);

/* Read "alias" entry in exception policy. */
bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head);
/*
Expand All @@ -570,6 +609,8 @@ bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head);
bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head);
/* Read "path_group" entry in exception policy. */
bool tomoyo_read_path_group_policy(struct tomoyo_io_buffer *head);
/* Read "number_group" entry in exception policy. */
bool tomoyo_read_number_group_policy(struct tomoyo_io_buffer *head);
/* Read "allow_read" entry in exception policy. */
bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head);
/* Read "deny_rewrite" entry in exception policy. */
Expand Down Expand Up @@ -614,6 +655,8 @@ int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete);
int tomoyo_write_pattern_policy(char *data, const bool is_delete);
/* Create "path_group" entry in exception policy. */
int tomoyo_write_path_group_policy(char *data, const bool is_delete);
/* Create "number_group" entry in exception policy. */
int tomoyo_write_number_group_policy(char *data, const bool is_delete);
/* Find a domain by the given name. */
struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
/* Find or create a domain by the given name. */
Expand All @@ -623,6 +666,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *

/* Allocate memory for "struct tomoyo_path_group". */
struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name);
struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name);

/* Check mode for specified functionality. */
unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
Expand All @@ -632,6 +676,8 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
/* Run policy loader when /sbin/init starts. */
void tomoyo_load_policy(const char *filename);

void tomoyo_put_number_union(struct tomoyo_number_union *ptr);

/* Convert binary string to ascii string. */
int tomoyo_encode(char *buffer, int buflen, const char *str);

Expand Down Expand Up @@ -697,6 +743,7 @@ extern struct srcu_struct tomoyo_ss;
extern struct list_head tomoyo_domain_list;

extern struct list_head tomoyo_path_group_list;
extern struct list_head tomoyo_number_group_list;
extern struct list_head tomoyo_domain_initializer_list;
extern struct list_head tomoyo_domain_keeper_list;
extern struct list_head tomoyo_alias_list;
Expand Down Expand Up @@ -773,6 +820,12 @@ static inline void tomoyo_put_path_group(struct tomoyo_path_group *group)
atomic_dec(&group->users);
}

static inline void tomoyo_put_number_group(struct tomoyo_number_group *group)
{
if (group)
atomic_dec(&group->users);
}

static inline struct tomoyo_domain_info *tomoyo_domain(void)
{
return current_cred()->security;
Expand All @@ -797,6 +850,14 @@ static inline bool tomoyo_is_same_name_union
p1->is_group == p2->is_group;
}

static inline bool tomoyo_is_same_number_union
(const struct tomoyo_number_union *p1, const struct tomoyo_number_union *p2)
{
return p1->values[0] == p2->values[0] && p1->values[1] == p2->values[1]
&& p1->group == p2->group && p1->min_type == p2->min_type &&
p1->max_type == p2->max_type && p1->is_group == p2->is_group;
}

static inline bool tomoyo_is_same_path_acl(const struct tomoyo_path_acl *p1,
const struct tomoyo_path_acl *p2)
{
Expand Down
14 changes: 14 additions & 0 deletions security/tomoyo/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ static bool tomoyo_compare_name_union_pattern(const struct tomoyo_path_info
return false;
}

void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
{
if (ptr && ptr->is_group)
tomoyo_put_number_group(ptr->group);
}

bool tomoyo_compare_number_union(const unsigned long value,
const struct tomoyo_number_union *ptr)
{
if (ptr->is_group)
return tomoyo_number_matches_group(value, value, ptr->group);
return value >= ptr->values[0] && value <= ptr->values[1];
}

/**
* tomoyo_path2keyword - Get the name of single path operation.
*
Expand Down
Loading

0 comments on commit 4c3e9e2

Please sign in to comment.