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; |
