at v2.6.35 172 lines 4.8 kB view raw
1/* 2 * security/tomoyo/path_group.c 3 * 4 * Copyright (C) 2005-2009 NTT DATA CORPORATION 5 */ 6 7#include <linux/slab.h> 8#include "common.h" 9/* The list for "struct ccs_path_group". */ 10LIST_HEAD(tomoyo_path_group_list); 11 12/** 13 * tomoyo_get_path_group - Allocate memory for "struct tomoyo_path_group". 14 * 15 * @group_name: The name of pathname group. 16 * 17 * Returns pointer to "struct tomoyo_path_group" on success, NULL otherwise. 18 */ 19struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name) 20{ 21 struct tomoyo_path_group *entry = NULL; 22 struct tomoyo_path_group *group = NULL; 23 const struct tomoyo_path_info *saved_group_name; 24 int error = -ENOMEM; 25 if (!tomoyo_is_correct_path(group_name, 0, 0, 0) || 26 !group_name[0]) 27 return NULL; 28 saved_group_name = tomoyo_get_name(group_name); 29 if (!saved_group_name) 30 return NULL; 31 entry = kzalloc(sizeof(*entry), GFP_NOFS); 32 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 33 goto out; 34 list_for_each_entry_rcu(group, &tomoyo_path_group_list, list) { 35 if (saved_group_name != group->group_name) 36 continue; 37 atomic_inc(&group->users); 38 error = 0; 39 break; 40 } 41 if (error && tomoyo_memory_ok(entry)) { 42 INIT_LIST_HEAD(&entry->member_list); 43 entry->group_name = saved_group_name; 44 saved_group_name = NULL; 45 atomic_set(&entry->users, 1); 46 list_add_tail_rcu(&entry->list, &tomoyo_path_group_list); 47 group = entry; 48 entry = NULL; 49 error = 0; 50 } 51 mutex_unlock(&tomoyo_policy_lock); 52 out: 53 tomoyo_put_name(saved_group_name); 54 kfree(entry); 55 return !error ? group : NULL; 56} 57 58/** 59 * tomoyo_write_path_group_policy - Write "struct tomoyo_path_group" list. 60 * 61 * @data: String to parse. 62 * @is_delete: True if it is a delete request. 63 * 64 * Returns 0 on success, nagative value otherwise. 65 */ 66int tomoyo_write_path_group_policy(char *data, const bool is_delete) 67{ 68 struct tomoyo_path_group *group; 69 struct tomoyo_path_group_member *member; 70 struct tomoyo_path_group_member e = { }; 71 int error = is_delete ? -ENOENT : -ENOMEM; 72 char *w[2]; 73 if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0]) 74 return -EINVAL; 75 group = tomoyo_get_path_group(w[0]); 76 if (!group) 77 return -ENOMEM; 78 e.member_name = tomoyo_get_name(w[1]); 79 if (!e.member_name) 80 goto out; 81 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 82 goto out; 83 list_for_each_entry_rcu(member, &group->member_list, list) { 84 if (member->member_name != e.member_name) 85 continue; 86 member->is_deleted = is_delete; 87 error = 0; 88 break; 89 } 90 if (!is_delete && error) { 91 struct tomoyo_path_group_member *entry = 92 tomoyo_commit_ok(&e, sizeof(e)); 93 if (entry) { 94 list_add_tail_rcu(&entry->list, &group->member_list); 95 error = 0; 96 } 97 } 98 mutex_unlock(&tomoyo_policy_lock); 99 out: 100 tomoyo_put_name(e.member_name); 101 tomoyo_put_path_group(group); 102 return error; 103} 104 105/** 106 * tomoyo_read_path_group_policy - Read "struct tomoyo_path_group" list. 107 * 108 * @head: Pointer to "struct tomoyo_io_buffer". 109 * 110 * Returns true on success, false otherwise. 111 * 112 * Caller holds tomoyo_read_lock(). 113 */ 114bool tomoyo_read_path_group_policy(struct tomoyo_io_buffer *head) 115{ 116 struct list_head *gpos; 117 struct list_head *mpos; 118 list_for_each_cookie(gpos, head->read_var1, &tomoyo_path_group_list) { 119 struct tomoyo_path_group *group; 120 group = list_entry(gpos, struct tomoyo_path_group, list); 121 list_for_each_cookie(mpos, head->read_var2, 122 &group->member_list) { 123 struct tomoyo_path_group_member *member; 124 member = list_entry(mpos, 125 struct tomoyo_path_group_member, 126 list); 127 if (member->is_deleted) 128 continue; 129 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_PATH_GROUP 130 "%s %s\n", 131 group->group_name->name, 132 member->member_name->name)) 133 return false; 134 } 135 } 136 return true; 137} 138 139/** 140 * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group. 141 * 142 * @pathname: The name of pathname. 143 * @group: Pointer to "struct tomoyo_path_group". 144 * @may_use_pattern: True if wild card is permitted. 145 * 146 * Returns true if @pathname matches pathnames in @group, false otherwise. 147 * 148 * Caller holds tomoyo_read_lock(). 149 */ 150bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, 151 const struct tomoyo_path_group *group, 152 const bool may_use_pattern) 153{ 154 struct tomoyo_path_group_member *member; 155 bool matched = false; 156 list_for_each_entry_rcu(member, &group->member_list, list) { 157 if (member->is_deleted) 158 continue; 159 if (!member->member_name->is_patterned) { 160 if (tomoyo_pathcmp(pathname, member->member_name)) 161 continue; 162 } else if (may_use_pattern) { 163 if (!tomoyo_path_matches_pattern(pathname, 164 member->member_name)) 165 continue; 166 } else 167 continue; 168 matched = true; 169 break; 170 } 171 return matched; 172}