1 // SPDX-License-Identifier: GPL-2.0 << 2 /* 1 /* 3 * security/tomoyo/group.c 2 * security/tomoyo/group.c 4 * 3 * 5 * Copyright (C) 2005-2011 NTT DATA CORPORATI 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION 6 */ 5 */ 7 6 8 #include <linux/slab.h> 7 #include <linux/slab.h> 9 #include <linux/rculist.h> << 10 << 11 #include "common.h" 8 #include "common.h" 12 9 13 /** 10 /** 14 * tomoyo_same_path_group - Check for duplicat 11 * tomoyo_same_path_group - Check for duplicated "struct tomoyo_path_group" entry. 15 * 12 * 16 * @a: Pointer to "struct tomoyo_acl_head". 13 * @a: Pointer to "struct tomoyo_acl_head". 17 * @b: Pointer to "struct tomoyo_acl_head". 14 * @b: Pointer to "struct tomoyo_acl_head". 18 * 15 * 19 * Returns true if @a == @b, false otherwise. 16 * Returns true if @a == @b, false otherwise. 20 */ 17 */ 21 static bool tomoyo_same_path_group(const struc 18 static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a, 22 const struc 19 const struct tomoyo_acl_head *b) 23 { 20 { 24 return container_of(a, struct tomoyo_p 21 return container_of(a, struct tomoyo_path_group, head)->member_name == 25 container_of(b, struct tomoyo_ 22 container_of(b, struct tomoyo_path_group, head)->member_name; 26 } 23 } 27 24 28 /** 25 /** 29 * tomoyo_same_number_group - Check for duplic 26 * tomoyo_same_number_group - Check for duplicated "struct tomoyo_number_group" entry. 30 * 27 * 31 * @a: Pointer to "struct tomoyo_acl_head". 28 * @a: Pointer to "struct tomoyo_acl_head". 32 * @b: Pointer to "struct tomoyo_acl_head". 29 * @b: Pointer to "struct tomoyo_acl_head". 33 * 30 * 34 * Returns true if @a == @b, false otherwise. 31 * Returns true if @a == @b, false otherwise. 35 */ 32 */ 36 static bool tomoyo_same_number_group(const str 33 static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a, 37 const str 34 const struct tomoyo_acl_head *b) 38 { 35 { 39 return !memcmp(&container_of(a, struct 36 return !memcmp(&container_of(a, struct tomoyo_number_group, head) 40 ->number, 37 ->number, 41 &container_of(b, struct 38 &container_of(b, struct tomoyo_number_group, head) 42 ->number, 39 ->number, 43 sizeof(container_of(a, 40 sizeof(container_of(a, struct tomoyo_number_group, head) 44 ->number)); 41 ->number)); 45 } 42 } 46 43 47 /** 44 /** 48 * tomoyo_same_address_group - Check for dupli 45 * tomoyo_same_address_group - Check for duplicated "struct tomoyo_address_group" entry. 49 * 46 * 50 * @a: Pointer to "struct tomoyo_acl_head". 47 * @a: Pointer to "struct tomoyo_acl_head". 51 * @b: Pointer to "struct tomoyo_acl_head". 48 * @b: Pointer to "struct tomoyo_acl_head". 52 * 49 * 53 * Returns true if @a == @b, false otherwise. 50 * Returns true if @a == @b, false otherwise. 54 */ 51 */ 55 static bool tomoyo_same_address_group(const st 52 static bool tomoyo_same_address_group(const struct tomoyo_acl_head *a, 56 const st 53 const struct tomoyo_acl_head *b) 57 { 54 { 58 const struct tomoyo_address_group *p1 55 const struct tomoyo_address_group *p1 = container_of(a, typeof(*p1), 59 56 head); 60 const struct tomoyo_address_group *p2 57 const struct tomoyo_address_group *p2 = container_of(b, typeof(*p2), 61 58 head); 62 59 63 return tomoyo_same_ipaddr_union(&p1->a 60 return tomoyo_same_ipaddr_union(&p1->address, &p2->address); 64 } 61 } 65 62 66 /** 63 /** 67 * tomoyo_write_group - Write "struct tomoyo_p 64 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list. 68 * 65 * 69 * @param: Pointer to "struct tomoyo_acl_param 66 * @param: Pointer to "struct tomoyo_acl_param". 70 * @type: Type of this group. 67 * @type: Type of this group. 71 * 68 * 72 * Returns 0 on success, negative value otherw 69 * Returns 0 on success, negative value otherwise. 73 */ 70 */ 74 int tomoyo_write_group(struct tomoyo_acl_param 71 int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type) 75 { 72 { 76 struct tomoyo_group *group = tomoyo_ge 73 struct tomoyo_group *group = tomoyo_get_group(param, type); 77 int error = -EINVAL; 74 int error = -EINVAL; 78 << 79 if (!group) 75 if (!group) 80 return -ENOMEM; 76 return -ENOMEM; 81 param->list = &group->member_list; 77 param->list = &group->member_list; 82 if (type == TOMOYO_PATH_GROUP) { 78 if (type == TOMOYO_PATH_GROUP) { 83 struct tomoyo_path_group e = { 79 struct tomoyo_path_group e = { }; 84 << 85 e.member_name = tomoyo_get_nam 80 e.member_name = tomoyo_get_name(tomoyo_read_token(param)); 86 if (!e.member_name) { 81 if (!e.member_name) { 87 error = -ENOMEM; 82 error = -ENOMEM; 88 goto out; 83 goto out; 89 } 84 } 90 error = tomoyo_update_policy(& 85 error = tomoyo_update_policy(&e.head, sizeof(e), param, 91 tomo 86 tomoyo_same_path_group); 92 tomoyo_put_name(e.member_name) 87 tomoyo_put_name(e.member_name); 93 } else if (type == TOMOYO_NUMBER_GROUP 88 } else if (type == TOMOYO_NUMBER_GROUP) { 94 struct tomoyo_number_group e = 89 struct tomoyo_number_group e = { }; 95 << 96 if (param->data[0] == '@' || 90 if (param->data[0] == '@' || 97 !tomoyo_parse_number_union 91 !tomoyo_parse_number_union(param, &e.number)) 98 goto out; 92 goto out; 99 error = tomoyo_update_policy(& 93 error = tomoyo_update_policy(&e.head, sizeof(e), param, 100 tomo 94 tomoyo_same_number_group); 101 /* 95 /* 102 * tomoyo_put_number_union() i 96 * tomoyo_put_number_union() is not needed because 103 * param->data[0] != '@'. 97 * param->data[0] != '@'. 104 */ 98 */ 105 } else { 99 } else { 106 struct tomoyo_address_group e 100 struct tomoyo_address_group e = { }; 107 101 108 if (param->data[0] == '@' || 102 if (param->data[0] == '@' || 109 !tomoyo_parse_ipaddr_union 103 !tomoyo_parse_ipaddr_union(param, &e.address)) 110 goto out; 104 goto out; 111 error = tomoyo_update_policy(& 105 error = tomoyo_update_policy(&e.head, sizeof(e), param, 112 t 106 tomoyo_same_address_group); 113 } 107 } 114 out: 108 out: 115 tomoyo_put_group(group); 109 tomoyo_put_group(group); 116 return error; 110 return error; 117 } 111 } 118 112 119 /** 113 /** 120 * tomoyo_path_matches_group - Check whether t 114 * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group. 121 * 115 * 122 * @pathname: The name of pathname. 116 * @pathname: The name of pathname. 123 * @group: Pointer to "struct tomoyo_path_g 117 * @group: Pointer to "struct tomoyo_path_group". 124 * 118 * 125 * Returns matched member's pathname if @pathn 119 * Returns matched member's pathname if @pathname matches pathnames in @group, 126 * NULL otherwise. 120 * NULL otherwise. 127 * 121 * 128 * Caller holds tomoyo_read_lock(). 122 * Caller holds tomoyo_read_lock(). 129 */ 123 */ 130 const struct tomoyo_path_info * 124 const struct tomoyo_path_info * 131 tomoyo_path_matches_group(const struct tomoyo_ 125 tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, 132 const struct tomoyo_ 126 const struct tomoyo_group *group) 133 { 127 { 134 struct tomoyo_path_group *member; 128 struct tomoyo_path_group *member; 135 !! 129 list_for_each_entry_rcu(member, &group->member_list, head.list) { 136 list_for_each_entry_rcu(member, &group << 137 srcu_read_lock << 138 if (member->head.is_deleted) 130 if (member->head.is_deleted) 139 continue; 131 continue; 140 if (!tomoyo_path_matches_patte 132 if (!tomoyo_path_matches_pattern(pathname, member->member_name)) 141 continue; 133 continue; 142 return member->member_name; 134 return member->member_name; 143 } 135 } 144 return NULL; 136 return NULL; 145 } 137 } 146 138 147 /** 139 /** 148 * tomoyo_number_matches_group - Check whether 140 * tomoyo_number_matches_group - Check whether the given number matches members of the given number group. 149 * 141 * 150 * @min: Min number. 142 * @min: Min number. 151 * @max: Max number. 143 * @max: Max number. 152 * @group: Pointer to "struct tomoyo_number_gr 144 * @group: Pointer to "struct tomoyo_number_group". 153 * 145 * 154 * Returns true if @min and @max partially ove 146 * Returns true if @min and @max partially overlaps @group, false otherwise. 155 * 147 * 156 * Caller holds tomoyo_read_lock(). 148 * Caller holds tomoyo_read_lock(). 157 */ 149 */ 158 bool tomoyo_number_matches_group(const unsigne 150 bool tomoyo_number_matches_group(const unsigned long min, 159 const unsigne 151 const unsigned long max, 160 const struct 152 const struct tomoyo_group *group) 161 { 153 { 162 struct tomoyo_number_group *member; 154 struct tomoyo_number_group *member; 163 bool matched = false; 155 bool matched = false; 164 !! 156 list_for_each_entry_rcu(member, &group->member_list, head.list) { 165 list_for_each_entry_rcu(member, &group << 166 srcu_read_lock << 167 if (member->head.is_deleted) 157 if (member->head.is_deleted) 168 continue; 158 continue; 169 if (min > member->number.value 159 if (min > member->number.values[1] || 170 max < member->number.value 160 max < member->number.values[0]) 171 continue; 161 continue; 172 matched = true; 162 matched = true; 173 break; 163 break; 174 } 164 } 175 return matched; 165 return matched; 176 } 166 } 177 167 178 /** 168 /** 179 * tomoyo_address_matches_group - Check whethe 169 * tomoyo_address_matches_group - Check whether the given address matches members of the given address group. 180 * 170 * 181 * @is_ipv6: True if @address is an IPv6 addre 171 * @is_ipv6: True if @address is an IPv6 address. 182 * @address: An IPv4 or IPv6 address. 172 * @address: An IPv4 or IPv6 address. 183 * @group: Pointer to "struct tomoyo_address 173 * @group: Pointer to "struct tomoyo_address_group". 184 * 174 * 185 * Returns true if @address matches addresses 175 * Returns true if @address matches addresses in @group group, false otherwise. 186 * 176 * 187 * Caller holds tomoyo_read_lock(). 177 * Caller holds tomoyo_read_lock(). 188 */ 178 */ 189 bool tomoyo_address_matches_group(const bool i 179 bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address, 190 const struct 180 const struct tomoyo_group *group) 191 { 181 { 192 struct tomoyo_address_group *member; 182 struct tomoyo_address_group *member; 193 bool matched = false; 183 bool matched = false; 194 const u8 size = is_ipv6 ? 16 : 4; 184 const u8 size = is_ipv6 ? 16 : 4; 195 185 196 list_for_each_entry_rcu(member, &group !! 186 list_for_each_entry_rcu(member, &group->member_list, head.list) { 197 srcu_read_lock << 198 if (member->head.is_deleted) 187 if (member->head.is_deleted) 199 continue; 188 continue; 200 if (member->address.is_ipv6 != 189 if (member->address.is_ipv6 != is_ipv6) 201 continue; 190 continue; 202 if (memcmp(&member->address.ip 191 if (memcmp(&member->address.ip[0], address, size) > 0 || 203 memcmp(address, &member->a 192 memcmp(address, &member->address.ip[1], size) > 0) 204 continue; 193 continue; 205 matched = true; 194 matched = true; 206 break; 195 break; 207 } 196 } 208 return matched; 197 return matched; 209 } 198 } 210 199
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.