aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c42
-rw-r--r--security/selinux/include/avc_ss.h9
-rw-r--r--security/selinux/include/netlabel.h2
-rw-r--r--security/selinux/include/objsec.h60
-rw-r--r--security/selinux/include/security.h6
-rw-r--r--security/selinux/netnode.c104
-rw-r--r--security/selinux/netport.c40
-rw-r--r--security/selinux/ss/conditional.h6
-rw-r--r--security/selinux/ss/context.h4
-rw-r--r--security/selinux/ss/hashtab.h6
-rw-r--r--security/selinux/ss/mls.h6
-rw-r--r--security/selinux/ss/mls_types.h4
-rw-r--r--security/selinux/ss/policydb.h10
-rw-r--r--security/selinux/ss/services.c4
14 files changed, 150 insertions, 153 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 308e2cf17d75..4e4de98941ae 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2619,7 +2619,7 @@ static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2619 return dentry_has_perm(current, mnt, dentry, FILE__GETATTR); 2619 return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
2620} 2620}
2621 2621
2622static int selinux_inode_setotherxattr(struct dentry *dentry, char *name) 2622static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2623{ 2623{
2624 if (!strncmp(name, XATTR_SECURITY_PREFIX, 2624 if (!strncmp(name, XATTR_SECURITY_PREFIX,
2625 sizeof XATTR_SECURITY_PREFIX - 1)) { 2625 sizeof XATTR_SECURITY_PREFIX - 1)) {
@@ -2638,7 +2638,8 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, char *name)
2638 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); 2638 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
2639} 2639}
2640 2640
2641static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) 2641static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2642 const void *value, size_t size, int flags)
2642{ 2643{
2643 struct task_security_struct *tsec = current->security; 2644 struct task_security_struct *tsec = current->security;
2644 struct inode *inode = dentry->d_inode; 2645 struct inode *inode = dentry->d_inode;
@@ -2687,8 +2688,9 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value
2687 &ad); 2688 &ad);
2688} 2689}
2689 2690
2690static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, 2691static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
2691 void *value, size_t size, int flags) 2692 const void *value, size_t size,
2693 int flags)
2692{ 2694{
2693 struct inode *inode = dentry->d_inode; 2695 struct inode *inode = dentry->d_inode;
2694 struct inode_security_struct *isec = inode->i_security; 2696 struct inode_security_struct *isec = inode->i_security;
@@ -2711,7 +2713,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
2711 return; 2713 return;
2712} 2714}
2713 2715
2714static int selinux_inode_getxattr(struct dentry *dentry, char *name) 2716static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2715{ 2717{
2716 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); 2718 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
2717} 2719}
@@ -2721,7 +2723,7 @@ static int selinux_inode_listxattr(struct dentry *dentry)
2721 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); 2723 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
2722} 2724}
2723 2725
2724static int selinux_inode_removexattr(struct dentry *dentry, char *name) 2726static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
2725{ 2727{
2726 if (strcmp(name, XATTR_NAME_SELINUX)) 2728 if (strcmp(name, XATTR_NAME_SELINUX))
2727 return selinux_inode_setotherxattr(dentry, name); 2729 return selinux_inode_setotherxattr(dentry, name);
@@ -3303,12 +3305,13 @@ static int selinux_task_prctl(int option,
3303 unsigned long arg2, 3305 unsigned long arg2,
3304 unsigned long arg3, 3306 unsigned long arg3,
3305 unsigned long arg4, 3307 unsigned long arg4,
3306 unsigned long arg5) 3308 unsigned long arg5,
3309 long *rc_p)
3307{ 3310{
3308 /* The current prctl operations do not appear to require 3311 /* The current prctl operations do not appear to require
3309 any SELinux controls since they merely observe or modify 3312 any SELinux controls since they merely observe or modify
3310 the state of the current process. */ 3313 the state of the current process. */
3311 return 0; 3314 return secondary_ops->task_prctl(option, arg2, arg3, arg4, arg5, rc_p);
3312} 3315}
3313 3316
3314static int selinux_task_wait(struct task_struct *p) 3317static int selinux_task_wait(struct task_struct *p)
@@ -5297,6 +5300,20 @@ static int selinux_key_permission(key_ref_t key_ref,
5297 SECCLASS_KEY, perm, NULL); 5300 SECCLASS_KEY, perm, NULL);
5298} 5301}
5299 5302
5303static int selinux_key_getsecurity(struct key *key, char **_buffer)
5304{
5305 struct key_security_struct *ksec = key->security;
5306 char *context = NULL;
5307 unsigned len;
5308 int rc;
5309
5310 rc = security_sid_to_context(ksec->sid, &context, &len);
5311 if (!rc)
5312 rc = len;
5313 *_buffer = context;
5314 return rc;
5315}
5316
5300#endif 5317#endif
5301 5318
5302static struct security_operations selinux_ops = { 5319static struct security_operations selinux_ops = {
@@ -5485,6 +5502,7 @@ static struct security_operations selinux_ops = {
5485 .key_alloc = selinux_key_alloc, 5502 .key_alloc = selinux_key_alloc,
5486 .key_free = selinux_key_free, 5503 .key_free = selinux_key_free,
5487 .key_permission = selinux_key_permission, 5504 .key_permission = selinux_key_permission,
5505 .key_getsecurity = selinux_key_getsecurity,
5488#endif 5506#endif
5489 5507
5490#ifdef CONFIG_AUDIT 5508#ifdef CONFIG_AUDIT
@@ -5533,14 +5551,6 @@ static __init int selinux_init(void)
5533 else 5551 else
5534 printk(KERN_DEBUG "SELinux: Starting in permissive mode\n"); 5552 printk(KERN_DEBUG "SELinux: Starting in permissive mode\n");
5535 5553
5536#ifdef CONFIG_KEYS
5537 /* Add security information to initial keyrings */
5538 selinux_key_alloc(&root_user_keyring, current,
5539 KEY_ALLOC_NOT_IN_QUOTA);
5540 selinux_key_alloc(&root_session_keyring, current,
5541 KEY_ALLOC_NOT_IN_QUOTA);
5542#endif
5543
5544 return 0; 5554 return 0;
5545} 5555}
5546 5556
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
11int avc_ss_reset(u32 seqno); 11int avc_ss_reset(u32 seqno);
12 12
13struct av_perm_to_string 13struct 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
20struct av_inherit 19struct 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
27struct selinux_class_perm 25struct 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
66static inline void selinux_netlbl_sk_security_reset( 66static 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
30struct task_security_struct { 30struct 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
39struct inode_security_struct { 39struct 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
50struct file_security_struct { 50struct 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
57struct superblock_security_struct { 57struct 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
72struct msg_security_struct { 72struct msg_security_struct {
73 u32 sid; /* SID of message */ 73 u32 sid; /* SID of message */
74}; 74};
75 75
76struct ipc_security_struct { 76struct 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
81struct bprm_security_struct { 81struct 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
125struct key_security_struct { 125struct key_security_struct {
126 u32 sid; /* SID of key */ 126 u32 sid; /* SID of key */
127}; 127};
128 128
129extern unsigned int selinux_checkreqprot; 129extern unsigned int selinux_checkreqprot;
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 1904c462a605..cdb14add27d2 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -62,7 +62,7 @@ enum {
62extern int selinux_policycap_netpeer; 62extern int selinux_policycap_netpeer;
63extern int selinux_policycap_openperm; 63extern int selinux_policycap_openperm;
64 64
65int security_load_policy(void * data, size_t len); 65int security_load_policy(void *data, size_t len);
66 66
67int security_policycap_supported(unsigned int req_cap); 67int security_policycap_supported(unsigned int req_cap);
68 68
@@ -93,7 +93,7 @@ int security_change_sid(u32 ssid, u32 tsid,
93int security_sid_to_context(u32 sid, char **scontext, 93int security_sid_to_context(u32 sid, char **scontext,
94 u32 *scontext_len); 94 u32 *scontext_len);
95 95
96int security_context_to_sid(char *scontext, u32 scontext_len, 96int security_context_to_sid(const char *scontext, u32 scontext_len,
97 u32 *out_sid); 97 u32 *out_sid);
98 98
99int security_context_to_sid_default(char *scontext, u32 scontext_len, 99int security_context_to_sid_default(char *scontext, u32 scontext_len,
@@ -110,7 +110,7 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen,
110 u32 *out_sid); 110 u32 *out_sid);
111 111
112int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, 112int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
113 u16 tclass); 113 u16 tclass);
114 114
115int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); 115int 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
49struct sel_netnode_bkt {
50 unsigned int size;
51 struct list_head list;
52};
53
48struct sel_netnode { 54struct 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
61static LIST_HEAD(sel_netnode_list); 67static LIST_HEAD(sel_netnode_list);
62static DEFINE_SPINLOCK(sel_netnode_lock); 68static DEFINE_SPINLOCK(sel_netnode_lock);
63static struct list_head sel_netnode_hash[SEL_NETNODE_HASH_SIZE]; 69static 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 */
90static u32 sel_netnode_hashfn_ipv4(__be32 addr) 96static 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 */
106static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr) 112static 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 */
124static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) 130static 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 */
166static int sel_netnode_insert(struct sel_netnode *node) 171static 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 */
204static 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 */
223static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) 215static 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
265out: 252out:
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 */
313static void sel_netnode_flush(void) 300static 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 */
133static int sel_netport_insert(struct sel_netport *port) 131static 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 */
164static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) 162static 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
192out: 187out:
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)
239static void sel_netport_flush(void) 234static 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
62int cond_policydb_init(struct policydb* p); 62int cond_policydb_init(struct policydb *p);
63void cond_policydb_destroy(struct policydb* p); 63void cond_policydb_destroy(struct policydb *p);
64 64
65int cond_init_bool_indexes(struct policydb* p); 65int cond_init_bool_indexes(struct policydb *p);
66int cond_destroy_bool(void *key, void *datum, void *p); 66int cond_destroy_bool(void *key, void *datum, void *p);
67 67
68int cond_index_bool(void *key, void *datum, void *datap); 68int 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
92static inline void mls_context_destroy(struct context *c) 92static 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 */
42struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), 42struct 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 */
54int hashtab_insert(struct hashtab *h, void *k, void *d); 54int 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);
31int mls_level_isvalid(struct policydb *p, struct mls_level *l); 31int mls_level_isvalid(struct policydb *p, struct mls_level *l);
32 32
33int mls_context_to_sid(char oldc, 33int 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
51int mls_setup_user_range(struct context *fromcon, struct user_datum *user, 51int 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
55void mls_export_netlbl_lvl(struct context *context, 55void 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
37static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) 37static 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;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 2daaddbb301d..25cac5a2aa8e 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -708,7 +708,7 @@ out:
708 708
709} 709}
710 710
711static int security_context_to_sid_core(char *scontext, u32 scontext_len, 711static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
712 u32 *sid, u32 def_sid, gfp_t gfp_flags) 712 u32 *sid, u32 def_sid, gfp_t gfp_flags)
713{ 713{
714 char *scontext2; 714 char *scontext2;
@@ -835,7 +835,7 @@ out:
835 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 835 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
836 * memory is available, or 0 on success. 836 * memory is available, or 0 on success.
837 */ 837 */
838int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) 838int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid)
839{ 839{
840 return security_context_to_sid_core(scontext, scontext_len, 840 return security_context_to_sid_core(scontext, scontext_len,
841 sid, SECSID_NULL, GFP_KERNEL); 841 sid, SECSID_NULL, GFP_KERNEL);