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