1 /* 2 * security/tomoyo/group.c 3 * 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION 5 */ 6 7 #include <linux/slab.h> 8 #include "common.h" 9 10 /** 11 * tomoyo_same_path_group - Check for duplicated "struct tomoyo_path_group" entry. 12 * 13 * @a: Pointer to "struct tomoyo_acl_head". 14 * @b: Pointer to "struct tomoyo_acl_head". 15 * 16 * Returns true if @a == @b, false otherwise. 17 */ 18 static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a, 19 const struct tomoyo_acl_head *b) 20 { 21 return container_of(a, struct tomoyo_path_group, head)->member_name == 22 container_of(b, struct tomoyo_path_group, head)->member_name; 23 } 24 25 /** 26 * tomoyo_same_number_group - Check for duplicated "struct tomoyo_number_group" entry. 27 * 28 * @a: Pointer to "struct tomoyo_acl_head". 29 * @b: Pointer to "struct tomoyo_acl_head". 30 * 31 * Returns true if @a == @b, false otherwise. 32 */ 33 static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a, 34 const struct tomoyo_acl_head *b) 35 { 36 return !memcmp(&container_of(a, struct tomoyo_number_group, head) 37 ->number, 38 &container_of(b, struct tomoyo_number_group, head) 39 ->number, 40 sizeof(container_of(a, struct tomoyo_number_group, head) 41 ->number)); 42 } 43 44 /** 45 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list. 46 * 47 * @param: Pointer to "struct tomoyo_acl_param". 48 * @type: Type of this group. 49 * 50 * Returns 0 on success, negative value otherwise. 51 */ 52 int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type) 53 { 54 struct tomoyo_group *group = tomoyo_get_group(param, type); 55 int error = -EINVAL; 56 if (!group) 57 return -ENOMEM; 58 param->list = &group->member_list; 59 if (type == TOMOYO_PATH_GROUP) { 60 struct tomoyo_path_group e = { }; 61 e.member_name = tomoyo_get_name(tomoyo_read_token(param)); 62 if (!e.member_name) { 63 error = -ENOMEM; 64 goto out; 65 } 66 error = tomoyo_update_policy(&e.head, sizeof(e), param, 67 tomoyo_same_path_group); 68 tomoyo_put_name(e.member_name); 69 } else if (type == TOMOYO_NUMBER_GROUP) { 70 struct tomoyo_number_group e = { }; 71 if (param->data[0] == '@' || 72 !tomoyo_parse_number_union(param, &e.number)) 73 goto out; 74 error = tomoyo_update_policy(&e.head, sizeof(e), param, 75 tomoyo_same_number_group); 76 /* 77 * tomoyo_put_number_union() is not needed because 78 * param->data[0] != '@'. 79 */ 80 } 81 out: 82 tomoyo_put_group(group); 83 return error; 84 } 85 86 /** 87 * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group. 88 * 89 * @pathname: The name of pathname. 90 * @group: Pointer to "struct tomoyo_path_group". 91 * 92 * Returns matched member's pathname if @pathname matches pathnames in @group, 93 * NULL otherwise. 94 * 95 * Caller holds tomoyo_read_lock(). 96 */ 97 const struct tomoyo_path_info * 98 tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, 99 const struct tomoyo_group *group) 100 { 101 struct tomoyo_path_group *member; 102 list_for_each_entry_rcu(member, &group->member_list, head.list) { 103 if (member->head.is_deleted) 104 continue; 105 if (!tomoyo_path_matches_pattern(pathname, member->member_name)) 106 continue; 107 return member->member_name; 108 } 109 return NULL; 110 } 111 112 /** 113 * tomoyo_number_matches_group - Check whether the given number matches members of the given number group. 114 * 115 * @min: Min number. 116 * @max: Max number. 117 * @group: Pointer to "struct tomoyo_number_group". 118 * 119 * Returns true if @min and @max partially overlaps @group, false otherwise. 120 * 121 * Caller holds tomoyo_read_lock(). 122 */ 123 bool tomoyo_number_matches_group(const unsigned long min, 124 const unsigned long max, 125 const struct tomoyo_group *group) 126 { 127 struct tomoyo_number_group *member; 128 bool matched = false; 129 list_for_each_entry_rcu(member, &group->member_list, head.list) { 130 if (member->head.is_deleted) 131 continue; 132 if (min > member->number.values[1] || 133 max < member->number.values[0]) 134 continue; 135 matched = true; 136 break; 137 } 138 return matched; 139 } 140