diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/include/avc_ss.h | 9 | ||||
-rw-r--r-- | security/selinux/include/netlabel.h | 2 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 60 | ||||
-rw-r--r-- | security/selinux/include/security.h | 4 | ||||
-rw-r--r-- | security/selinux/netnode.c | 104 | ||||
-rw-r--r-- | security/selinux/netport.c | 40 | ||||
-rw-r--r-- | security/selinux/ss/conditional.h | 6 | ||||
-rw-r--r-- | security/selinux/ss/context.h | 4 | ||||
-rw-r--r-- | security/selinux/ss/hashtab.h | 6 | ||||
-rw-r--r-- | security/selinux/ss/mls.h | 6 | ||||
-rw-r--r-- | security/selinux/ss/mls_types.h | 4 | ||||
-rw-r--r-- | security/selinux/ss/policydb.h | 10 |
12 files changed, 121 insertions, 134 deletions
diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h index ff869e8b6f4a..c0d314d9f8e1 100644 --- a/security/selinux/include/avc_ss.h +++ b/security/selinux/include/avc_ss.h | |||
@@ -10,22 +10,19 @@ | |||
10 | 10 | ||
11 | int avc_ss_reset(u32 seqno); | 11 | int avc_ss_reset(u32 seqno); |
12 | 12 | ||
13 | struct av_perm_to_string | 13 | struct av_perm_to_string { |
14 | { | ||
15 | u16 tclass; | 14 | u16 tclass; |
16 | u32 value; | 15 | u32 value; |
17 | const char *name; | 16 | const char *name; |
18 | }; | 17 | }; |
19 | 18 | ||
20 | struct av_inherit | 19 | struct av_inherit { |
21 | { | ||
22 | u16 tclass; | 20 | u16 tclass; |
23 | const char **common_pts; | 21 | const char **common_pts; |
24 | u32 common_base; | 22 | u32 common_base; |
25 | }; | 23 | }; |
26 | 24 | ||
27 | struct selinux_class_perm | 25 | struct selinux_class_perm { |
28 | { | ||
29 | const struct av_perm_to_string *av_perm_to_string; | 26 | const struct av_perm_to_string *av_perm_to_string; |
30 | u32 av_pts_len; | 27 | u32 av_pts_len; |
31 | const char **class_to_string; | 28 | const char **class_to_string; |
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index 9a9e7cd9a379..487a7d81fe20 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h | |||
@@ -64,7 +64,7 @@ static inline void selinux_netlbl_cache_invalidate(void) | |||
64 | } | 64 | } |
65 | 65 | ||
66 | static inline void selinux_netlbl_sk_security_reset( | 66 | static inline void selinux_netlbl_sk_security_reset( |
67 | struct sk_security_struct *ssec, | 67 | struct sk_security_struct *ssec, |
68 | int family) | 68 | int family) |
69 | { | 69 | { |
70 | return; | 70 | return; |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 300b61bad7b3..032c2357dad1 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
@@ -4,16 +4,16 @@ | |||
4 | * This file contains the SELinux security data structures for kernel objects. | 4 | * This file contains the SELinux security data structures for kernel objects. |
5 | * | 5 | * |
6 | * Author(s): Stephen Smalley, <sds@epoch.ncsc.mil> | 6 | * Author(s): Stephen Smalley, <sds@epoch.ncsc.mil> |
7 | * Chris Vance, <cvance@nai.com> | 7 | * Chris Vance, <cvance@nai.com> |
8 | * Wayne Salamon, <wsalamon@nai.com> | 8 | * Wayne Salamon, <wsalamon@nai.com> |
9 | * James Morris <jmorris@redhat.com> | 9 | * James Morris <jmorris@redhat.com> |
10 | * | 10 | * |
11 | * Copyright (C) 2001,2002 Networks Associates Technology, Inc. | 11 | * Copyright (C) 2001,2002 Networks Associates Technology, Inc. |
12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> | 12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License version 2, | 15 | * it under the terms of the GNU General Public License version 2, |
16 | * as published by the Free Software Foundation. | 16 | * as published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | #ifndef _SELINUX_OBJSEC_H_ | 18 | #ifndef _SELINUX_OBJSEC_H_ |
19 | #define _SELINUX_OBJSEC_H_ | 19 | #define _SELINUX_OBJSEC_H_ |
@@ -28,58 +28,58 @@ | |||
28 | #include "avc.h" | 28 | #include "avc.h" |
29 | 29 | ||
30 | struct task_security_struct { | 30 | struct task_security_struct { |
31 | u32 osid; /* SID prior to last execve */ | 31 | u32 osid; /* SID prior to last execve */ |
32 | u32 sid; /* current SID */ | 32 | u32 sid; /* current SID */ |
33 | u32 exec_sid; /* exec SID */ | 33 | u32 exec_sid; /* exec SID */ |
34 | u32 create_sid; /* fscreate SID */ | 34 | u32 create_sid; /* fscreate SID */ |
35 | u32 keycreate_sid; /* keycreate SID */ | 35 | u32 keycreate_sid; /* keycreate SID */ |
36 | u32 sockcreate_sid; /* fscreate SID */ | 36 | u32 sockcreate_sid; /* fscreate SID */ |
37 | }; | 37 | }; |
38 | 38 | ||
39 | struct inode_security_struct { | 39 | struct inode_security_struct { |
40 | struct inode *inode; /* back pointer to inode object */ | 40 | struct inode *inode; /* back pointer to inode object */ |
41 | struct list_head list; /* list of inode_security_struct */ | 41 | struct list_head list; /* list of inode_security_struct */ |
42 | u32 task_sid; /* SID of creating task */ | 42 | u32 task_sid; /* SID of creating task */ |
43 | u32 sid; /* SID of this object */ | 43 | u32 sid; /* SID of this object */ |
44 | u16 sclass; /* security class of this object */ | 44 | u16 sclass; /* security class of this object */ |
45 | unsigned char initialized; /* initialization flag */ | 45 | unsigned char initialized; /* initialization flag */ |
46 | struct mutex lock; | 46 | struct mutex lock; |
47 | unsigned char inherit; /* inherit SID from parent entry */ | 47 | unsigned char inherit; /* inherit SID from parent entry */ |
48 | }; | 48 | }; |
49 | 49 | ||
50 | struct file_security_struct { | 50 | struct file_security_struct { |
51 | u32 sid; /* SID of open file description */ | 51 | u32 sid; /* SID of open file description */ |
52 | u32 fown_sid; /* SID of file owner (for SIGIO) */ | 52 | u32 fown_sid; /* SID of file owner (for SIGIO) */ |
53 | u32 isid; /* SID of inode at the time of file open */ | 53 | u32 isid; /* SID of inode at the time of file open */ |
54 | u32 pseqno; /* Policy seqno at the time of file open */ | 54 | u32 pseqno; /* Policy seqno at the time of file open */ |
55 | }; | 55 | }; |
56 | 56 | ||
57 | struct superblock_security_struct { | 57 | struct superblock_security_struct { |
58 | struct super_block *sb; /* back pointer to sb object */ | 58 | struct super_block *sb; /* back pointer to sb object */ |
59 | struct list_head list; /* list of superblock_security_struct */ | 59 | struct list_head list; /* list of superblock_security_struct */ |
60 | u32 sid; /* SID of file system superblock */ | 60 | u32 sid; /* SID of file system superblock */ |
61 | u32 def_sid; /* default SID for labeling */ | 61 | u32 def_sid; /* default SID for labeling */ |
62 | u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ | 62 | u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ |
63 | unsigned int behavior; /* labeling behavior */ | 63 | unsigned int behavior; /* labeling behavior */ |
64 | unsigned char initialized; /* initialization flag */ | 64 | unsigned char initialized; /* initialization flag */ |
65 | unsigned char flags; /* which mount options were specified */ | 65 | unsigned char flags; /* which mount options were specified */ |
66 | unsigned char proc; /* proc fs */ | 66 | unsigned char proc; /* proc fs */ |
67 | struct mutex lock; | 67 | struct mutex lock; |
68 | struct list_head isec_head; | 68 | struct list_head isec_head; |
69 | spinlock_t isec_lock; | 69 | spinlock_t isec_lock; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct msg_security_struct { | 72 | struct msg_security_struct { |
73 | u32 sid; /* SID of message */ | 73 | u32 sid; /* SID of message */ |
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct ipc_security_struct { | 76 | struct ipc_security_struct { |
77 | u16 sclass; /* security class of this object */ | 77 | u16 sclass; /* security class of this object */ |
78 | u32 sid; /* SID of IPC resource */ | 78 | u32 sid; /* SID of IPC resource */ |
79 | }; | 79 | }; |
80 | 80 | ||
81 | struct bprm_security_struct { | 81 | struct bprm_security_struct { |
82 | u32 sid; /* SID for transformed process */ | 82 | u32 sid; /* SID for transformed process */ |
83 | unsigned char set; | 83 | unsigned char set; |
84 | 84 | ||
85 | /* | 85 | /* |
@@ -123,7 +123,7 @@ struct sk_security_struct { | |||
123 | }; | 123 | }; |
124 | 124 | ||
125 | struct key_security_struct { | 125 | struct key_security_struct { |
126 | u32 sid; /* SID of key */ | 126 | u32 sid; /* SID of key */ |
127 | }; | 127 | }; |
128 | 128 | ||
129 | extern unsigned int selinux_checkreqprot; | 129 | extern unsigned int selinux_checkreqprot; |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 1904c462a605..6445b6440648 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -62,7 +62,7 @@ enum { | |||
62 | extern int selinux_policycap_netpeer; | 62 | extern int selinux_policycap_netpeer; |
63 | extern int selinux_policycap_openperm; | 63 | extern int selinux_policycap_openperm; |
64 | 64 | ||
65 | int security_load_policy(void * data, size_t len); | 65 | int security_load_policy(void *data, size_t len); |
66 | 66 | ||
67 | int security_policycap_supported(unsigned int req_cap); | 67 | int security_policycap_supported(unsigned int req_cap); |
68 | 68 | ||
@@ -110,7 +110,7 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen, | |||
110 | u32 *out_sid); | 110 | u32 *out_sid); |
111 | 111 | ||
112 | int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | 112 | int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, |
113 | u16 tclass); | 113 | u16 tclass); |
114 | 114 | ||
115 | int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); | 115 | int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); |
116 | 116 | ||
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index 2edc4c5e0c61..b6ccd09379f1 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c | |||
@@ -40,11 +40,17 @@ | |||
40 | #include <net/ipv6.h> | 40 | #include <net/ipv6.h> |
41 | #include <asm/bug.h> | 41 | #include <asm/bug.h> |
42 | 42 | ||
43 | #include "netnode.h" | ||
43 | #include "objsec.h" | 44 | #include "objsec.h" |
44 | 45 | ||
45 | #define SEL_NETNODE_HASH_SIZE 256 | 46 | #define SEL_NETNODE_HASH_SIZE 256 |
46 | #define SEL_NETNODE_HASH_BKT_LIMIT 16 | 47 | #define SEL_NETNODE_HASH_BKT_LIMIT 16 |
47 | 48 | ||
49 | struct sel_netnode_bkt { | ||
50 | unsigned int size; | ||
51 | struct list_head list; | ||
52 | }; | ||
53 | |||
48 | struct sel_netnode { | 54 | struct sel_netnode { |
49 | struct netnode_security_struct nsec; | 55 | struct netnode_security_struct nsec; |
50 | 56 | ||
@@ -60,7 +66,7 @@ struct sel_netnode { | |||
60 | 66 | ||
61 | static LIST_HEAD(sel_netnode_list); | 67 | static LIST_HEAD(sel_netnode_list); |
62 | static DEFINE_SPINLOCK(sel_netnode_lock); | 68 | static DEFINE_SPINLOCK(sel_netnode_lock); |
63 | static struct list_head sel_netnode_hash[SEL_NETNODE_HASH_SIZE]; | 69 | static struct sel_netnode_bkt sel_netnode_hash[SEL_NETNODE_HASH_SIZE]; |
64 | 70 | ||
65 | /** | 71 | /** |
66 | * sel_netnode_free - Frees a node entry | 72 | * sel_netnode_free - Frees a node entry |
@@ -87,7 +93,7 @@ static void sel_netnode_free(struct rcu_head *p) | |||
87 | * the bucket number for the given IP address. | 93 | * the bucket number for the given IP address. |
88 | * | 94 | * |
89 | */ | 95 | */ |
90 | static u32 sel_netnode_hashfn_ipv4(__be32 addr) | 96 | static unsigned int sel_netnode_hashfn_ipv4(__be32 addr) |
91 | { | 97 | { |
92 | /* at some point we should determine if the mismatch in byte order | 98 | /* at some point we should determine if the mismatch in byte order |
93 | * affects the hash function dramatically */ | 99 | * affects the hash function dramatically */ |
@@ -103,7 +109,7 @@ static u32 sel_netnode_hashfn_ipv4(__be32 addr) | |||
103 | * the bucket number for the given IP address. | 109 | * the bucket number for the given IP address. |
104 | * | 110 | * |
105 | */ | 111 | */ |
106 | static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr) | 112 | static unsigned int sel_netnode_hashfn_ipv6(const struct in6_addr *addr) |
107 | { | 113 | { |
108 | /* just hash the least significant 32 bits to keep things fast (they | 114 | /* just hash the least significant 32 bits to keep things fast (they |
109 | * are the most likely to be different anyway), we can revisit this | 115 | * are the most likely to be different anyway), we can revisit this |
@@ -123,7 +129,7 @@ static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr) | |||
123 | */ | 129 | */ |
124 | static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) | 130 | static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) |
125 | { | 131 | { |
126 | u32 idx; | 132 | unsigned int idx; |
127 | struct sel_netnode *node; | 133 | struct sel_netnode *node; |
128 | 134 | ||
129 | switch (family) { | 135 | switch (family) { |
@@ -137,7 +143,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) | |||
137 | BUG(); | 143 | BUG(); |
138 | } | 144 | } |
139 | 145 | ||
140 | list_for_each_entry_rcu(node, &sel_netnode_hash[idx], list) | 146 | list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list) |
141 | if (node->nsec.family == family) | 147 | if (node->nsec.family == family) |
142 | switch (family) { | 148 | switch (family) { |
143 | case PF_INET: | 149 | case PF_INET: |
@@ -159,15 +165,12 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) | |||
159 | * @node: the new node record | 165 | * @node: the new node record |
160 | * | 166 | * |
161 | * Description: | 167 | * Description: |
162 | * Add a new node record to the network address hash table. Returns zero on | 168 | * Add a new node record to the network address hash table. |
163 | * success, negative values on failure. | ||
164 | * | 169 | * |
165 | */ | 170 | */ |
166 | static int sel_netnode_insert(struct sel_netnode *node) | 171 | static void sel_netnode_insert(struct sel_netnode *node) |
167 | { | 172 | { |
168 | u32 idx; | 173 | unsigned int idx; |
169 | u32 count = 0; | ||
170 | struct sel_netnode *iter; | ||
171 | 174 | ||
172 | switch (node->nsec.family) { | 175 | switch (node->nsec.family) { |
173 | case PF_INET: | 176 | case PF_INET: |
@@ -179,32 +182,21 @@ static int sel_netnode_insert(struct sel_netnode *node) | |||
179 | default: | 182 | default: |
180 | BUG(); | 183 | BUG(); |
181 | } | 184 | } |
182 | list_add_rcu(&node->list, &sel_netnode_hash[idx]); | 185 | |
186 | INIT_RCU_HEAD(&node->rcu); | ||
183 | 187 | ||
184 | /* we need to impose a limit on the growth of the hash table so check | 188 | /* we need to impose a limit on the growth of the hash table so check |
185 | * this bucket to make sure it is within the specified bounds */ | 189 | * this bucket to make sure it is within the specified bounds */ |
186 | list_for_each_entry(iter, &sel_netnode_hash[idx], list) | 190 | list_add_rcu(&node->list, &sel_netnode_hash[idx].list); |
187 | if (++count > SEL_NETNODE_HASH_BKT_LIMIT) { | 191 | if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { |
188 | list_del_rcu(&iter->list); | 192 | struct sel_netnode *tail; |
189 | call_rcu(&iter->rcu, sel_netnode_free); | 193 | tail = list_entry( |
190 | break; | 194 | rcu_dereference(sel_netnode_hash[idx].list.prev), |
191 | } | 195 | struct sel_netnode, list); |
192 | 196 | list_del_rcu(&tail->list); | |
193 | return 0; | 197 | call_rcu(&tail->rcu, sel_netnode_free); |
194 | } | 198 | } else |
195 | 199 | sel_netnode_hash[idx].size++; | |
196 | /** | ||
197 | * sel_netnode_destroy - Remove a node record from the table | ||
198 | * @node: the existing node record | ||
199 | * | ||
200 | * Description: | ||
201 | * Remove an existing node record from the network address table. | ||
202 | * | ||
203 | */ | ||
204 | static void sel_netnode_destroy(struct sel_netnode *node) | ||
205 | { | ||
206 | list_del_rcu(&node->list); | ||
207 | call_rcu(&node->rcu, sel_netnode_free); | ||
208 | } | 200 | } |
209 | 201 | ||
210 | /** | 202 | /** |
@@ -222,7 +214,7 @@ static void sel_netnode_destroy(struct sel_netnode *node) | |||
222 | */ | 214 | */ |
223 | static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) | 215 | static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) |
224 | { | 216 | { |
225 | int ret; | 217 | int ret = -ENOMEM; |
226 | struct sel_netnode *node; | 218 | struct sel_netnode *node; |
227 | struct sel_netnode *new = NULL; | 219 | struct sel_netnode *new = NULL; |
228 | 220 | ||
@@ -230,25 +222,21 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) | |||
230 | node = sel_netnode_find(addr, family); | 222 | node = sel_netnode_find(addr, family); |
231 | if (node != NULL) { | 223 | if (node != NULL) { |
232 | *sid = node->nsec.sid; | 224 | *sid = node->nsec.sid; |
233 | ret = 0; | 225 | spin_unlock_bh(&sel_netnode_lock); |
234 | goto out; | 226 | return 0; |
235 | } | 227 | } |
236 | new = kzalloc(sizeof(*new), GFP_ATOMIC); | 228 | new = kzalloc(sizeof(*new), GFP_ATOMIC); |
237 | if (new == NULL) { | 229 | if (new == NULL) |
238 | ret = -ENOMEM; | ||
239 | goto out; | 230 | goto out; |
240 | } | ||
241 | switch (family) { | 231 | switch (family) { |
242 | case PF_INET: | 232 | case PF_INET: |
243 | ret = security_node_sid(PF_INET, | 233 | ret = security_node_sid(PF_INET, |
244 | addr, sizeof(struct in_addr), | 234 | addr, sizeof(struct in_addr), sid); |
245 | &new->nsec.sid); | ||
246 | new->nsec.addr.ipv4 = *(__be32 *)addr; | 235 | new->nsec.addr.ipv4 = *(__be32 *)addr; |
247 | break; | 236 | break; |
248 | case PF_INET6: | 237 | case PF_INET6: |
249 | ret = security_node_sid(PF_INET6, | 238 | ret = security_node_sid(PF_INET6, |
250 | addr, sizeof(struct in6_addr), | 239 | addr, sizeof(struct in6_addr), sid); |
251 | &new->nsec.sid); | ||
252 | ipv6_addr_copy(&new->nsec.addr.ipv6, addr); | 240 | ipv6_addr_copy(&new->nsec.addr.ipv6, addr); |
253 | break; | 241 | break; |
254 | default: | 242 | default: |
@@ -256,11 +244,10 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) | |||
256 | } | 244 | } |
257 | if (ret != 0) | 245 | if (ret != 0) |
258 | goto out; | 246 | goto out; |
247 | |||
259 | new->nsec.family = family; | 248 | new->nsec.family = family; |
260 | ret = sel_netnode_insert(new); | 249 | new->nsec.sid = *sid; |
261 | if (ret != 0) | 250 | sel_netnode_insert(new); |
262 | goto out; | ||
263 | *sid = new->nsec.sid; | ||
264 | 251 | ||
265 | out: | 252 | out: |
266 | spin_unlock_bh(&sel_netnode_lock); | 253 | spin_unlock_bh(&sel_netnode_lock); |
@@ -312,13 +299,18 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid) | |||
312 | */ | 299 | */ |
313 | static void sel_netnode_flush(void) | 300 | static void sel_netnode_flush(void) |
314 | { | 301 | { |
315 | u32 idx; | 302 | unsigned int idx; |
316 | struct sel_netnode *node; | 303 | struct sel_netnode *node, *node_tmp; |
317 | 304 | ||
318 | spin_lock_bh(&sel_netnode_lock); | 305 | spin_lock_bh(&sel_netnode_lock); |
319 | for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++) | 306 | for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++) { |
320 | list_for_each_entry(node, &sel_netnode_hash[idx], list) | 307 | list_for_each_entry_safe(node, node_tmp, |
321 | sel_netnode_destroy(node); | 308 | &sel_netnode_hash[idx].list, list) { |
309 | list_del_rcu(&node->list); | ||
310 | call_rcu(&node->rcu, sel_netnode_free); | ||
311 | } | ||
312 | sel_netnode_hash[idx].size = 0; | ||
313 | } | ||
322 | spin_unlock_bh(&sel_netnode_lock); | 314 | spin_unlock_bh(&sel_netnode_lock); |
323 | } | 315 | } |
324 | 316 | ||
@@ -340,8 +332,10 @@ static __init int sel_netnode_init(void) | |||
340 | if (!selinux_enabled) | 332 | if (!selinux_enabled) |
341 | return 0; | 333 | return 0; |
342 | 334 | ||
343 | for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++) | 335 | for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++) { |
344 | INIT_LIST_HEAD(&sel_netnode_hash[iter]); | 336 | INIT_LIST_HEAD(&sel_netnode_hash[iter].list); |
337 | sel_netnode_hash[iter].size = 0; | ||
338 | } | ||
345 | 339 | ||
346 | ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET, | 340 | ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET, |
347 | SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); | 341 | SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); |
diff --git a/security/selinux/netport.c b/security/selinux/netport.c index 68ede3c498ab..90b4cff7c350 100644 --- a/security/selinux/netport.c +++ b/security/selinux/netport.c | |||
@@ -114,8 +114,7 @@ static struct sel_netport *sel_netport_find(u8 protocol, u16 pnum) | |||
114 | 114 | ||
115 | idx = sel_netport_hashfn(pnum); | 115 | idx = sel_netport_hashfn(pnum); |
116 | list_for_each_entry_rcu(port, &sel_netport_hash[idx].list, list) | 116 | list_for_each_entry_rcu(port, &sel_netport_hash[idx].list, list) |
117 | if (port->psec.port == pnum && | 117 | if (port->psec.port == pnum && port->psec.protocol == protocol) |
118 | port->psec.protocol == protocol) | ||
119 | return port; | 118 | return port; |
120 | 119 | ||
121 | return NULL; | 120 | return NULL; |
@@ -126,11 +125,10 @@ static struct sel_netport *sel_netport_find(u8 protocol, u16 pnum) | |||
126 | * @port: the new port record | 125 | * @port: the new port record |
127 | * | 126 | * |
128 | * Description: | 127 | * Description: |
129 | * Add a new port record to the network address hash table. Returns zero on | 128 | * Add a new port record to the network address hash table. |
130 | * success, negative values on failure. | ||
131 | * | 129 | * |
132 | */ | 130 | */ |
133 | static int sel_netport_insert(struct sel_netport *port) | 131 | static void sel_netport_insert(struct sel_netport *port) |
134 | { | 132 | { |
135 | unsigned int idx; | 133 | unsigned int idx; |
136 | 134 | ||
@@ -140,13 +138,13 @@ static int sel_netport_insert(struct sel_netport *port) | |||
140 | list_add_rcu(&port->list, &sel_netport_hash[idx].list); | 138 | list_add_rcu(&port->list, &sel_netport_hash[idx].list); |
141 | if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) { | 139 | if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) { |
142 | struct sel_netport *tail; | 140 | struct sel_netport *tail; |
143 | tail = list_entry(port->list.prev, struct sel_netport, list); | 141 | tail = list_entry( |
144 | list_del_rcu(port->list.prev); | 142 | rcu_dereference(sel_netport_hash[idx].list.prev), |
143 | struct sel_netport, list); | ||
144 | list_del_rcu(&tail->list); | ||
145 | call_rcu(&tail->rcu, sel_netport_free); | 145 | call_rcu(&tail->rcu, sel_netport_free); |
146 | } else | 146 | } else |
147 | sel_netport_hash[idx].size++; | 147 | sel_netport_hash[idx].size++; |
148 | |||
149 | return 0; | ||
150 | } | 148 | } |
151 | 149 | ||
152 | /** | 150 | /** |
@@ -163,7 +161,7 @@ static int sel_netport_insert(struct sel_netport *port) | |||
163 | */ | 161 | */ |
164 | static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) | 162 | static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) |
165 | { | 163 | { |
166 | int ret; | 164 | int ret = -ENOMEM; |
167 | struct sel_netport *port; | 165 | struct sel_netport *port; |
168 | struct sel_netport *new = NULL; | 166 | struct sel_netport *new = NULL; |
169 | 167 | ||
@@ -171,23 +169,20 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) | |||
171 | port = sel_netport_find(protocol, pnum); | 169 | port = sel_netport_find(protocol, pnum); |
172 | if (port != NULL) { | 170 | if (port != NULL) { |
173 | *sid = port->psec.sid; | 171 | *sid = port->psec.sid; |
174 | ret = 0; | 172 | spin_unlock_bh(&sel_netport_lock); |
175 | goto out; | 173 | return 0; |
176 | } | 174 | } |
177 | new = kzalloc(sizeof(*new), GFP_ATOMIC); | 175 | new = kzalloc(sizeof(*new), GFP_ATOMIC); |
178 | if (new == NULL) { | 176 | if (new == NULL) |
179 | ret = -ENOMEM; | ||
180 | goto out; | 177 | goto out; |
181 | } | 178 | ret = security_port_sid(protocol, pnum, sid); |
182 | ret = security_port_sid(protocol, pnum, &new->psec.sid); | ||
183 | if (ret != 0) | 179 | if (ret != 0) |
184 | goto out; | 180 | goto out; |
181 | |||
185 | new->psec.port = pnum; | 182 | new->psec.port = pnum; |
186 | new->psec.protocol = protocol; | 183 | new->psec.protocol = protocol; |
187 | ret = sel_netport_insert(new); | 184 | new->psec.sid = *sid; |
188 | if (ret != 0) | 185 | sel_netport_insert(new); |
189 | goto out; | ||
190 | *sid = new->psec.sid; | ||
191 | 186 | ||
192 | out: | 187 | out: |
193 | spin_unlock_bh(&sel_netport_lock); | 188 | spin_unlock_bh(&sel_netport_lock); |
@@ -239,11 +234,12 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid) | |||
239 | static void sel_netport_flush(void) | 234 | static void sel_netport_flush(void) |
240 | { | 235 | { |
241 | unsigned int idx; | 236 | unsigned int idx; |
242 | struct sel_netport *port; | 237 | struct sel_netport *port, *port_tmp; |
243 | 238 | ||
244 | spin_lock_bh(&sel_netport_lock); | 239 | spin_lock_bh(&sel_netport_lock); |
245 | for (idx = 0; idx < SEL_NETPORT_HASH_SIZE; idx++) { | 240 | for (idx = 0; idx < SEL_NETPORT_HASH_SIZE; idx++) { |
246 | list_for_each_entry(port, &sel_netport_hash[idx].list, list) { | 241 | list_for_each_entry_safe(port, port_tmp, |
242 | &sel_netport_hash[idx].list, list) { | ||
247 | list_del_rcu(&port->list); | 243 | list_del_rcu(&port->list); |
248 | call_rcu(&port->rcu, sel_netport_free); | 244 | call_rcu(&port->rcu, sel_netport_free); |
249 | } | 245 | } |
diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h index f3a1fc6e5d66..65b9f8366e9c 100644 --- a/security/selinux/ss/conditional.h +++ b/security/selinux/ss/conditional.h | |||
@@ -59,10 +59,10 @@ struct cond_node { | |||
59 | struct cond_node *next; | 59 | struct cond_node *next; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | int cond_policydb_init(struct policydb* p); | 62 | int cond_policydb_init(struct policydb *p); |
63 | void cond_policydb_destroy(struct policydb* p); | 63 | void cond_policydb_destroy(struct policydb *p); |
64 | 64 | ||
65 | int cond_init_bool_indexes(struct policydb* p); | 65 | int cond_init_bool_indexes(struct policydb *p); |
66 | int cond_destroy_bool(void *key, void *datum, void *p); | 66 | int cond_destroy_bool(void *key, void *datum, void *p); |
67 | 67 | ||
68 | int cond_index_bool(void *key, void *datum, void *datap); | 68 | int cond_index_bool(void *key, void *datum, void *datap); |
diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h index 2eee0dab524d..b9a6f7fc62fc 100644 --- a/security/selinux/ss/context.h +++ b/security/selinux/ss/context.h | |||
@@ -84,9 +84,9 @@ static inline int mls_context_cmp(struct context *c1, struct context *c2) | |||
84 | return 1; | 84 | return 1; |
85 | 85 | ||
86 | return ((c1->range.level[0].sens == c2->range.level[0].sens) && | 86 | return ((c1->range.level[0].sens == c2->range.level[0].sens) && |
87 | ebitmap_cmp(&c1->range.level[0].cat,&c2->range.level[0].cat) && | 87 | ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) && |
88 | (c1->range.level[1].sens == c2->range.level[1].sens) && | 88 | (c1->range.level[1].sens == c2->range.level[1].sens) && |
89 | ebitmap_cmp(&c1->range.level[1].cat,&c2->range.level[1].cat)); | 89 | ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat)); |
90 | } | 90 | } |
91 | 91 | ||
92 | static inline void mls_context_destroy(struct context *c) | 92 | static inline void mls_context_destroy(struct context *c) |
diff --git a/security/selinux/ss/hashtab.h b/security/selinux/ss/hashtab.h index 7e2ff3e3c6d2..953872cd84ab 100644 --- a/security/selinux/ss/hashtab.h +++ b/security/selinux/ss/hashtab.h | |||
@@ -40,8 +40,8 @@ struct hashtab_info { | |||
40 | * the new hash table otherwise. | 40 | * the new hash table otherwise. |
41 | */ | 41 | */ |
42 | struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), | 42 | struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), |
43 | int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), | 43 | int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), |
44 | u32 size); | 44 | u32 size); |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * Inserts the specified (key, datum) pair into the specified hash table. | 47 | * Inserts the specified (key, datum) pair into the specified hash table. |
@@ -49,7 +49,7 @@ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void * | |||
49 | * Returns -ENOMEM on memory allocation error, | 49 | * Returns -ENOMEM on memory allocation error, |
50 | * -EEXIST if there is already an entry with the same key, | 50 | * -EEXIST if there is already an entry with the same key, |
51 | * -EINVAL for general errors or | 51 | * -EINVAL for general errors or |
52 | * 0 otherwise. | 52 | 0 otherwise. |
53 | */ | 53 | */ |
54 | int hashtab_insert(struct hashtab *h, void *k, void *d); | 54 | int hashtab_insert(struct hashtab *h, void *k, void *d); |
55 | 55 | ||
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index ab53663d9f5f..0fdf6257ef64 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h | |||
@@ -13,7 +13,7 @@ | |||
13 | /* | 13 | /* |
14 | * Updated: Hewlett-Packard <paul.moore@hp.com> | 14 | * Updated: Hewlett-Packard <paul.moore@hp.com> |
15 | * | 15 | * |
16 | * Added support to import/export the MLS label from NetLabel | 16 | * Added support to import/export the MLS label from NetLabel |
17 | * | 17 | * |
18 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 | 18 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 |
19 | */ | 19 | */ |
@@ -31,7 +31,7 @@ int mls_range_isvalid(struct policydb *p, struct mls_range *r); | |||
31 | int mls_level_isvalid(struct policydb *p, struct mls_level *l); | 31 | int mls_level_isvalid(struct policydb *p, struct mls_level *l); |
32 | 32 | ||
33 | int mls_context_to_sid(char oldc, | 33 | int mls_context_to_sid(char oldc, |
34 | char **scontext, | 34 | char **scontext, |
35 | struct context *context, | 35 | struct context *context, |
36 | struct sidtab *s, | 36 | struct sidtab *s, |
37 | u32 def_sid); | 37 | u32 def_sid); |
@@ -49,7 +49,7 @@ int mls_compute_sid(struct context *scontext, | |||
49 | struct context *newcontext); | 49 | struct context *newcontext); |
50 | 50 | ||
51 | int mls_setup_user_range(struct context *fromcon, struct user_datum *user, | 51 | int mls_setup_user_range(struct context *fromcon, struct user_datum *user, |
52 | struct context *usercon); | 52 | struct context *usercon); |
53 | 53 | ||
54 | #ifdef CONFIG_NETLABEL | 54 | #ifdef CONFIG_NETLABEL |
55 | void mls_export_netlbl_lvl(struct context *context, | 55 | void mls_export_netlbl_lvl(struct context *context, |
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h index 0c692d58d489..b6e943a21061 100644 --- a/security/selinux/ss/mls_types.h +++ b/security/selinux/ss/mls_types.h | |||
@@ -31,7 +31,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2) | |||
31 | return 1; | 31 | return 1; |
32 | 32 | ||
33 | return ((l1->sens == l2->sens) && | 33 | return ((l1->sens == l2->sens) && |
34 | ebitmap_cmp(&l1->cat, &l2->cat)); | 34 | ebitmap_cmp(&l1->cat, &l2->cat)); |
35 | } | 35 | } |
36 | 36 | ||
37 | static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) | 37 | static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) |
@@ -40,7 +40,7 @@ static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) | |||
40 | return 1; | 40 | return 1; |
41 | 41 | ||
42 | return ((l1->sens >= l2->sens) && | 42 | return ((l1->sens >= l2->sens) && |
43 | ebitmap_contains(&l1->cat, &l2->cat)); | 43 | ebitmap_contains(&l1->cat, &l2->cat)); |
44 | } | 44 | } |
45 | 45 | ||
46 | #define mls_level_incomp(l1, l2) \ | 46 | #define mls_level_incomp(l1, l2) \ |
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index ba593a3da877..4253370fda6a 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h | |||
@@ -12,12 +12,12 @@ | |||
12 | * | 12 | * |
13 | * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> | 13 | * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> |
14 | * | 14 | * |
15 | * Added conditional policy language extensions | 15 | * Added conditional policy language extensions |
16 | * | 16 | * |
17 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 17 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. |
18 | * Copyright (C) 2003 - 2004 Tresys Technology, LLC | 18 | * Copyright (C) 2003 - 2004 Tresys Technology, LLC |
19 | * This program is free software; you can redistribute it and/or modify | 19 | * This program is free software; you can redistribute it and/or modify |
20 | * it under the terms of the GNU General Public License as published by | 20 | * it under the terms of the GNU General Public License as published by |
21 | * the Free Software Foundation, version 2. | 21 | * the Free Software Foundation, version 2. |
22 | */ | 22 | */ |
23 | 23 | ||
@@ -221,7 +221,7 @@ struct policydb { | |||
221 | /* type enforcement conditional access vectors and transitions */ | 221 | /* type enforcement conditional access vectors and transitions */ |
222 | struct avtab te_cond_avtab; | 222 | struct avtab te_cond_avtab; |
223 | /* linked list indexing te_cond_avtab by conditional */ | 223 | /* linked list indexing te_cond_avtab by conditional */ |
224 | struct cond_node* cond_list; | 224 | struct cond_node *cond_list; |
225 | 225 | ||
226 | /* role allows */ | 226 | /* role allows */ |
227 | struct role_allow *role_allow; | 227 | struct role_allow *role_allow; |
@@ -230,10 +230,10 @@ struct policydb { | |||
230 | TCP or UDP port numbers, network interfaces and nodes */ | 230 | TCP or UDP port numbers, network interfaces and nodes */ |
231 | struct ocontext *ocontexts[OCON_NUM]; | 231 | struct ocontext *ocontexts[OCON_NUM]; |
232 | 232 | ||
233 | /* security contexts for files in filesystems that cannot support | 233 | /* security contexts for files in filesystems that cannot support |
234 | a persistent label mapping or use another | 234 | a persistent label mapping or use another |
235 | fixed labeling behavior. */ | 235 | fixed labeling behavior. */ |
236 | struct genfs *genfs; | 236 | struct genfs *genfs; |
237 | 237 | ||
238 | /* range transitions */ | 238 | /* range transitions */ |
239 | struct range_trans *range_tr; | 239 | struct range_trans *range_tr; |