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