Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
group.c
Go to the documentation of this file.
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 
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 
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,
39  ->number,
40  sizeof(container_of(a, struct tomoyo_number_group, head)
41  ->number));
42 }
43 
52 static bool tomoyo_same_address_group(const struct tomoyo_acl_head *a,
53  const struct tomoyo_acl_head *b)
54 {
55  const struct tomoyo_address_group *p1 = container_of(a, typeof(*p1),
56  head);
57  const struct tomoyo_address_group *p2 = container_of(b, typeof(*p2),
58  head);
59 
60  return tomoyo_same_ipaddr_union(&p1->address, &p2->address);
61 }
62 
72 {
73  struct tomoyo_group *group = tomoyo_get_group(param, type);
74  int error = -EINVAL;
75  if (!group)
76  return -ENOMEM;
77  param->list = &group->member_list;
78  if (type == TOMOYO_PATH_GROUP) {
79  struct tomoyo_path_group e = { };
81  if (!e.member_name) {
82  error = -ENOMEM;
83  goto out;
84  }
85  error = tomoyo_update_policy(&e.head, sizeof(e), param,
86  tomoyo_same_path_group);
87  tomoyo_put_name(e.member_name);
88  } else if (type == TOMOYO_NUMBER_GROUP) {
89  struct tomoyo_number_group e = { };
90  if (param->data[0] == '@' ||
92  goto out;
93  error = tomoyo_update_policy(&e.head, sizeof(e), param,
94  tomoyo_same_number_group);
95  /*
96  * tomoyo_put_number_union() is not needed because
97  * param->data[0] != '@'.
98  */
99  } else {
100  struct tomoyo_address_group e = { };
101 
102  if (param->data[0] == '@' ||
104  goto out;
105  error = tomoyo_update_policy(&e.head, sizeof(e), param,
106  tomoyo_same_address_group);
107  }
108 out:
109  tomoyo_put_group(group);
110  return error;
111 }
112 
124 const struct tomoyo_path_info *
126  const struct tomoyo_group *group)
127 {
128  struct tomoyo_path_group *member;
129  list_for_each_entry_rcu(member, &group->member_list, head.list) {
130  if (member->head.is_deleted)
131  continue;
132  if (!tomoyo_path_matches_pattern(pathname, member->member_name))
133  continue;
134  return member->member_name;
135  }
136  return NULL;
137 }
138 
150 bool tomoyo_number_matches_group(const unsigned long min,
151  const unsigned long max,
152  const struct tomoyo_group *group)
153 {
154  struct tomoyo_number_group *member;
155  bool matched = false;
156  list_for_each_entry_rcu(member, &group->member_list, head.list) {
157  if (member->head.is_deleted)
158  continue;
159  if (min > member->number.values[1] ||
160  max < member->number.values[0])
161  continue;
162  matched = true;
163  break;
164  }
165  return matched;
166 }
167 
179 bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address,
180  const struct tomoyo_group *group)
181 {
182  struct tomoyo_address_group *member;
183  bool matched = false;
184  const u8 size = is_ipv6 ? 16 : 4;
185 
186  list_for_each_entry_rcu(member, &group->member_list, head.list) {
187  if (member->head.is_deleted)
188  continue;
189  if (member->address.is_ipv6 != is_ipv6)
190  continue;
191  if (memcmp(&member->address.ip[0], address, size) > 0 ||
192  memcmp(address, &member->address.ip[1], size) > 0)
193  continue;
194  matched = true;
195  break;
196  }
197  return matched;
198 }