aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c60
-rw-r--r--security/selinux/include/xfrm.h12
-rw-r--r--security/selinux/nlmsgtab.c7
-rw-r--r--security/selinux/selinuxfs.c112
-rw-r--r--security/selinux/ss/services.c9
-rw-r--r--security/selinux/xfrm.c68
6 files changed, 190 insertions, 78 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 81b726b1a419..b61b9554bc27 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -117,6 +117,8 @@ static struct security_operations *secondary_ops = NULL;
117static LIST_HEAD(superblock_security_head); 117static LIST_HEAD(superblock_security_head);
118static DEFINE_SPINLOCK(sb_security_lock); 118static DEFINE_SPINLOCK(sb_security_lock);
119 119
120static kmem_cache_t *sel_inode_cache;
121
120/* Return security context for a given sid or just the context 122/* Return security context for a given sid or just the context
121 length if the buffer is null or length is 0 */ 123 length if the buffer is null or length is 0 */
122static int selinux_getsecurity(u32 sid, void *buffer, size_t size) 124static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
@@ -172,10 +174,11 @@ static int inode_alloc_security(struct inode *inode)
172 struct task_security_struct *tsec = current->security; 174 struct task_security_struct *tsec = current->security;
173 struct inode_security_struct *isec; 175 struct inode_security_struct *isec;
174 176
175 isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL); 177 isec = kmem_cache_alloc(sel_inode_cache, SLAB_KERNEL);
176 if (!isec) 178 if (!isec)
177 return -ENOMEM; 179 return -ENOMEM;
178 180
181 memset(isec, 0, sizeof(*isec));
179 init_MUTEX(&isec->sem); 182 init_MUTEX(&isec->sem);
180 INIT_LIST_HEAD(&isec->list); 183 INIT_LIST_HEAD(&isec->list);
181 isec->inode = inode; 184 isec->inode = inode;
@@ -198,7 +201,7 @@ static void inode_free_security(struct inode *inode)
198 spin_unlock(&sbsec->isec_lock); 201 spin_unlock(&sbsec->isec_lock);
199 202
200 inode->i_security = NULL; 203 inode->i_security = NULL;
201 kfree(isec); 204 kmem_cache_free(sel_inode_cache, isec);
202} 205}
203 206
204static int file_alloc_security(struct file *file) 207static int file_alloc_security(struct file *file)
@@ -1955,7 +1958,6 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1955 struct task_security_struct *tsec; 1958 struct task_security_struct *tsec;
1956 struct inode_security_struct *dsec; 1959 struct inode_security_struct *dsec;
1957 struct superblock_security_struct *sbsec; 1960 struct superblock_security_struct *sbsec;
1958 struct inode_security_struct *isec;
1959 u32 newsid, clen; 1961 u32 newsid, clen;
1960 int rc; 1962 int rc;
1961 char *namep = NULL, *context; 1963 char *namep = NULL, *context;
@@ -1963,7 +1965,6 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1963 tsec = current->security; 1965 tsec = current->security;
1964 dsec = dir->i_security; 1966 dsec = dir->i_security;
1965 sbsec = dir->i_sb->s_security; 1967 sbsec = dir->i_sb->s_security;
1966 isec = inode->i_security;
1967 1968
1968 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) { 1969 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
1969 newsid = tsec->create_sid; 1970 newsid = tsec->create_sid;
@@ -1983,7 +1984,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1983 1984
1984 inode_security_set_sid(inode, newsid); 1985 inode_security_set_sid(inode, newsid);
1985 1986
1986 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) 1987 if (!ss_initialized || sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
1987 return -EOPNOTSUPP; 1988 return -EOPNOTSUPP;
1988 1989
1989 if (name) { 1990 if (name) {
@@ -3316,24 +3317,38 @@ out:
3316 return err; 3317 return err;
3317} 3318}
3318 3319
3319static int selinux_socket_getpeersec(struct socket *sock, char __user *optval, 3320static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
3320 int __user *optlen, unsigned len) 3321 int __user *optlen, unsigned len)
3321{ 3322{
3322 int err = 0; 3323 int err = 0;
3323 char *scontext; 3324 char *scontext;
3324 u32 scontext_len; 3325 u32 scontext_len;
3325 struct sk_security_struct *ssec; 3326 struct sk_security_struct *ssec;
3326 struct inode_security_struct *isec; 3327 struct inode_security_struct *isec;
3328 u32 peer_sid = 0;
3327 3329
3328 isec = SOCK_INODE(sock)->i_security; 3330 isec = SOCK_INODE(sock)->i_security;
3329 if (isec->sclass != SECCLASS_UNIX_STREAM_SOCKET) { 3331
3332 /* if UNIX_STREAM check peer_sid, if TCP check dst for labelled sa */
3333 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET) {
3334 ssec = sock->sk->sk_security;
3335 peer_sid = ssec->peer_sid;
3336 }
3337 else if (isec->sclass == SECCLASS_TCP_SOCKET) {
3338 peer_sid = selinux_socket_getpeer_stream(sock->sk);
3339
3340 if (peer_sid == SECSID_NULL) {
3341 err = -ENOPROTOOPT;
3342 goto out;
3343 }
3344 }
3345 else {
3330 err = -ENOPROTOOPT; 3346 err = -ENOPROTOOPT;
3331 goto out; 3347 goto out;
3332 } 3348 }
3333 3349
3334 ssec = sock->sk->sk_security; 3350 err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
3335 3351
3336 err = security_sid_to_context(ssec->peer_sid, &scontext, &scontext_len);
3337 if (err) 3352 if (err)
3338 goto out; 3353 goto out;
3339 3354
@@ -3354,6 +3369,23 @@ out:
3354 return err; 3369 return err;
3355} 3370}
3356 3371
3372static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
3373{
3374 int err = 0;
3375 u32 peer_sid = selinux_socket_getpeer_dgram(skb);
3376
3377 if (peer_sid == SECSID_NULL)
3378 return -EINVAL;
3379
3380 err = security_sid_to_context(peer_sid, secdata, seclen);
3381 if (err)
3382 return err;
3383
3384 return 0;
3385}
3386
3387
3388
3357static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) 3389static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
3358{ 3390{
3359 return sk_alloc_security(sk, family, priority); 3391 return sk_alloc_security(sk, family, priority);
@@ -4338,7 +4370,8 @@ static struct security_operations selinux_ops = {
4338 .socket_setsockopt = selinux_socket_setsockopt, 4370 .socket_setsockopt = selinux_socket_setsockopt,
4339 .socket_shutdown = selinux_socket_shutdown, 4371 .socket_shutdown = selinux_socket_shutdown,
4340 .socket_sock_rcv_skb = selinux_socket_sock_rcv_skb, 4372 .socket_sock_rcv_skb = selinux_socket_sock_rcv_skb,
4341 .socket_getpeersec = selinux_socket_getpeersec, 4373 .socket_getpeersec_stream = selinux_socket_getpeersec_stream,
4374 .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram,
4342 .sk_alloc_security = selinux_sk_alloc_security, 4375 .sk_alloc_security = selinux_sk_alloc_security,
4343 .sk_free_security = selinux_sk_free_security, 4376 .sk_free_security = selinux_sk_free_security,
4344 .sk_getsid = selinux_sk_getsid_security, 4377 .sk_getsid = selinux_sk_getsid_security,
@@ -4370,6 +4403,9 @@ static __init int selinux_init(void)
4370 tsec = current->security; 4403 tsec = current->security;
4371 tsec->osid = tsec->sid = SECINITSID_KERNEL; 4404 tsec->osid = tsec->sid = SECINITSID_KERNEL;
4372 4405
4406 sel_inode_cache = kmem_cache_create("selinux_inode_security",
4407 sizeof(struct inode_security_struct),
4408 0, SLAB_PANIC, NULL, NULL);
4373 avc_init(); 4409 avc_init();
4374 4410
4375 original_ops = secondary_ops = security_ops; 4411 original_ops = secondary_ops = security_ops;
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 8e87996c6dd5..c10f1fc41502 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -39,6 +39,8 @@ static inline u32 selinux_no_sk_sid(struct flowi *fl)
39#ifdef CONFIG_SECURITY_NETWORK_XFRM 39#ifdef CONFIG_SECURITY_NETWORK_XFRM
40int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb); 40int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb);
41int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb); 41int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb);
42u32 selinux_socket_getpeer_stream(struct sock *sk);
43u32 selinux_socket_getpeer_dgram(struct sk_buff *skb);
42#else 44#else
43static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) 45static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
44{ 46{
@@ -49,6 +51,16 @@ static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
49{ 51{
50 return NF_ACCEPT; 52 return NF_ACCEPT;
51} 53}
54
55static inline int selinux_socket_getpeer_stream(struct sock *sk)
56{
57 return SECSID_NULL;
58}
59
60static inline int selinux_socket_getpeer_dgram(struct sk_buff *skb)
61{
62 return SECSID_NULL;
63}
52#endif 64#endif
53 65
54#endif /* _SELINUX_XFRM_H_ */ 66#endif /* _SELINUX_XFRM_H_ */
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 73158244cf8c..b8f4d25cf335 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -88,8 +88,15 @@ static struct nlmsg_perm nlmsg_xfrm_perms[] =
88 { XFRM_MSG_DELPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 88 { XFRM_MSG_DELPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
89 { XFRM_MSG_GETPOLICY, NETLINK_XFRM_SOCKET__NLMSG_READ }, 89 { XFRM_MSG_GETPOLICY, NETLINK_XFRM_SOCKET__NLMSG_READ },
90 { XFRM_MSG_ALLOCSPI, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 90 { XFRM_MSG_ALLOCSPI, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
91 { XFRM_MSG_ACQUIRE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
92 { XFRM_MSG_EXPIRE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
91 { XFRM_MSG_UPDPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 93 { XFRM_MSG_UPDPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
92 { XFRM_MSG_UPDSA, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 94 { XFRM_MSG_UPDSA, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
95 { XFRM_MSG_POLEXPIRE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
96 { XFRM_MSG_FLUSHSA, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
97 { XFRM_MSG_FLUSHPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
98 { XFRM_MSG_NEWAE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
99 { XFRM_MSG_GETAE, NETLINK_XFRM_SOCKET__NLMSG_READ },
93}; 100};
94 101
95static struct nlmsg_perm nlmsg_audit_perms[] = 102static struct nlmsg_perm nlmsg_audit_perms[] =
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 5eba6664eac0..a4efc966f065 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/vmalloc.h> 16#include <linux/vmalloc.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/mutex.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/string.h> 20#include <linux/string.h>
20#include <linux/security.h> 21#include <linux/security.h>
@@ -45,7 +46,7 @@ static int __init checkreqprot_setup(char *str)
45__setup("checkreqprot=", checkreqprot_setup); 46__setup("checkreqprot=", checkreqprot_setup);
46 47
47 48
48static DECLARE_MUTEX(sel_sem); 49static DEFINE_MUTEX(sel_mutex);
49 50
50/* global data for booleans */ 51/* global data for booleans */
51static struct dentry *bool_dir = NULL; 52static struct dentry *bool_dir = NULL;
@@ -238,7 +239,7 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
238 ssize_t length; 239 ssize_t length;
239 void *data = NULL; 240 void *data = NULL;
240 241
241 down(&sel_sem); 242 mutex_lock(&sel_mutex);
242 243
243 length = task_has_security(current, SECURITY__LOAD_POLICY); 244 length = task_has_security(current, SECURITY__LOAD_POLICY);
244 if (length) 245 if (length)
@@ -273,7 +274,7 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
273 "policy loaded auid=%u", 274 "policy loaded auid=%u",
274 audit_get_loginuid(current->audit_context)); 275 audit_get_loginuid(current->audit_context));
275out: 276out:
276 up(&sel_sem); 277 mutex_unlock(&sel_mutex);
277 vfree(data); 278 vfree(data);
278 return length; 279 return length;
279} 280}
@@ -720,12 +721,11 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
720{ 721{
721 char *page = NULL; 722 char *page = NULL;
722 ssize_t length; 723 ssize_t length;
723 ssize_t end;
724 ssize_t ret; 724 ssize_t ret;
725 int cur_enforcing; 725 int cur_enforcing;
726 struct inode *inode; 726 struct inode *inode;
727 727
728 down(&sel_sem); 728 mutex_lock(&sel_mutex);
729 729
730 ret = -EFAULT; 730 ret = -EFAULT;
731 731
@@ -751,26 +751,9 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
751 751
752 length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, 752 length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
753 bool_pending_values[inode->i_ino - BOOL_INO_OFFSET]); 753 bool_pending_values[inode->i_ino - BOOL_INO_OFFSET]);
754 if (length < 0) { 754 ret = simple_read_from_buffer(buf, count, ppos, page, length);
755 ret = length;
756 goto out;
757 }
758
759 if (*ppos >= length) {
760 ret = 0;
761 goto out;
762 }
763 if (count + *ppos > length)
764 count = length - *ppos;
765 end = count + *ppos;
766 if (copy_to_user(buf, (char *) page + *ppos, count)) {
767 ret = -EFAULT;
768 goto out;
769 }
770 *ppos = end;
771 ret = count;
772out: 755out:
773 up(&sel_sem); 756 mutex_unlock(&sel_mutex);
774 if (page) 757 if (page)
775 free_page((unsigned long)page); 758 free_page((unsigned long)page);
776 return ret; 759 return ret;
@@ -784,7 +767,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
784 int new_value; 767 int new_value;
785 struct inode *inode; 768 struct inode *inode;
786 769
787 down(&sel_sem); 770 mutex_lock(&sel_mutex);
788 771
789 length = task_has_security(current, SECURITY__SETBOOL); 772 length = task_has_security(current, SECURITY__SETBOOL);
790 if (length) 773 if (length)
@@ -823,7 +806,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
823 length = count; 806 length = count;
824 807
825out: 808out:
826 up(&sel_sem); 809 mutex_unlock(&sel_mutex);
827 if (page) 810 if (page)
828 free_page((unsigned long) page); 811 free_page((unsigned long) page);
829 return length; 812 return length;
@@ -842,7 +825,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
842 ssize_t length = -EFAULT; 825 ssize_t length = -EFAULT;
843 int new_value; 826 int new_value;
844 827
845 down(&sel_sem); 828 mutex_lock(&sel_mutex);
846 829
847 length = task_has_security(current, SECURITY__SETBOOL); 830 length = task_has_security(current, SECURITY__SETBOOL);
848 if (length) 831 if (length)
@@ -880,7 +863,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
880 length = count; 863 length = count;
881 864
882out: 865out:
883 up(&sel_sem); 866 mutex_unlock(&sel_mutex);
884 if (page) 867 if (page)
885 free_page((unsigned long) page); 868 free_page((unsigned long) page);
886 return length; 869 return length;
@@ -998,7 +981,7 @@ out:
998 return ret; 981 return ret;
999err: 982err:
1000 kfree(values); 983 kfree(values);
1001 d_genocide(dir); 984 sel_remove_bools(dir);
1002 ret = -ENOMEM; 985 ret = -ENOMEM;
1003 goto out; 986 goto out;
1004} 987}
@@ -1179,37 +1162,38 @@ static int sel_make_avc_files(struct dentry *dir)
1179 dentry = d_alloc_name(dir, files[i].name); 1162 dentry = d_alloc_name(dir, files[i].name);
1180 if (!dentry) { 1163 if (!dentry) {
1181 ret = -ENOMEM; 1164 ret = -ENOMEM;
1182 goto err; 1165 goto out;
1183 } 1166 }
1184 1167
1185 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); 1168 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1186 if (!inode) { 1169 if (!inode) {
1187 ret = -ENOMEM; 1170 ret = -ENOMEM;
1188 goto err; 1171 goto out;
1189 } 1172 }
1190 inode->i_fop = files[i].ops; 1173 inode->i_fop = files[i].ops;
1191 d_add(dentry, inode); 1174 d_add(dentry, inode);
1192 } 1175 }
1193out: 1176out:
1194 return ret; 1177 return ret;
1195err:
1196 d_genocide(dir);
1197 goto out;
1198} 1178}
1199 1179
1200static int sel_make_dir(struct super_block *sb, struct dentry *dentry) 1180static int sel_make_dir(struct inode *dir, struct dentry *dentry)
1201{ 1181{
1202 int ret = 0; 1182 int ret = 0;
1203 struct inode *inode; 1183 struct inode *inode;
1204 1184
1205 inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); 1185 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1206 if (!inode) { 1186 if (!inode) {
1207 ret = -ENOMEM; 1187 ret = -ENOMEM;
1208 goto out; 1188 goto out;
1209 } 1189 }
1210 inode->i_op = &simple_dir_inode_operations; 1190 inode->i_op = &simple_dir_inode_operations;
1211 inode->i_fop = &simple_dir_operations; 1191 inode->i_fop = &simple_dir_operations;
1192 /* directory inodes start off with i_nlink == 2 (for "." entry) */
1193 inode->i_nlink++;
1212 d_add(dentry, inode); 1194 d_add(dentry, inode);
1195 /* bump link count on parent directory, too */
1196 dir->i_nlink++;
1213out: 1197out:
1214 return ret; 1198 return ret;
1215} 1199}
@@ -1218,7 +1202,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1218{ 1202{
1219 int ret; 1203 int ret;
1220 struct dentry *dentry; 1204 struct dentry *dentry;
1221 struct inode *inode; 1205 struct inode *inode, *root_inode;
1222 struct inode_security_struct *isec; 1206 struct inode_security_struct *isec;
1223 1207
1224 static struct tree_descr selinux_files[] = { 1208 static struct tree_descr selinux_files[] = {
@@ -1239,30 +1223,33 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1239 }; 1223 };
1240 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); 1224 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
1241 if (ret) 1225 if (ret)
1242 return ret; 1226 goto err;
1227
1228 root_inode = sb->s_root->d_inode;
1243 1229
1244 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); 1230 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1245 if (!dentry) 1231 if (!dentry) {
1246 return -ENOMEM; 1232 ret = -ENOMEM;
1233 goto err;
1234 }
1247 1235
1248 inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); 1236 ret = sel_make_dir(root_inode, dentry);
1249 if (!inode)
1250 goto out;
1251 inode->i_op = &simple_dir_inode_operations;
1252 inode->i_fop = &simple_dir_operations;
1253 d_add(dentry, inode);
1254 bool_dir = dentry;
1255 ret = sel_make_bools();
1256 if (ret) 1237 if (ret)
1257 goto out; 1238 goto err;
1239
1240 bool_dir = dentry;
1258 1241
1259 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); 1242 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1260 if (!dentry) 1243 if (!dentry) {
1261 return -ENOMEM; 1244 ret = -ENOMEM;
1245 goto err;
1246 }
1262 1247
1263 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); 1248 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1264 if (!inode) 1249 if (!inode) {
1265 goto out; 1250 ret = -ENOMEM;
1251 goto err;
1252 }
1266 isec = (struct inode_security_struct*)inode->i_security; 1253 isec = (struct inode_security_struct*)inode->i_security;
1267 isec->sid = SECINITSID_DEVNULL; 1254 isec->sid = SECINITSID_DEVNULL;
1268 isec->sclass = SECCLASS_CHR_FILE; 1255 isec->sclass = SECCLASS_CHR_FILE;
@@ -1273,22 +1260,23 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1273 selinux_null = dentry; 1260 selinux_null = dentry;
1274 1261
1275 dentry = d_alloc_name(sb->s_root, "avc"); 1262 dentry = d_alloc_name(sb->s_root, "avc");
1276 if (!dentry) 1263 if (!dentry) {
1277 return -ENOMEM; 1264 ret = -ENOMEM;
1265 goto err;
1266 }
1278 1267
1279 ret = sel_make_dir(sb, dentry); 1268 ret = sel_make_dir(root_inode, dentry);
1280 if (ret) 1269 if (ret)
1281 goto out; 1270 goto err;
1282 1271
1283 ret = sel_make_avc_files(dentry); 1272 ret = sel_make_avc_files(dentry);
1284 if (ret) 1273 if (ret)
1285 goto out; 1274 goto err;
1286
1287 return 0;
1288out: 1275out:
1289 dput(dentry); 1276 return ret;
1277err:
1290 printk(KERN_ERR "%s: failed while creating inodes\n", __FUNCTION__); 1278 printk(KERN_ERR "%s: failed while creating inodes\n", __FUNCTION__);
1291 return -ENOMEM; 1279 goto out;
1292} 1280}
1293 1281
1294static struct super_block *sel_get_sb(struct file_system_type *fs_type, 1282static struct super_block *sel_get_sb(struct file_system_type *fs_type,
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index d877cd16a813..61492485de84 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -27,7 +27,8 @@
27#include <linux/in.h> 27#include <linux/in.h>
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <asm/semaphore.h> 30#include <linux/mutex.h>
31
31#include "flask.h" 32#include "flask.h"
32#include "avc.h" 33#include "avc.h"
33#include "avc_ss.h" 34#include "avc_ss.h"
@@ -48,9 +49,9 @@ static DEFINE_RWLOCK(policy_rwlock);
48#define POLICY_RDUNLOCK read_unlock(&policy_rwlock) 49#define POLICY_RDUNLOCK read_unlock(&policy_rwlock)
49#define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock) 50#define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock)
50 51
51static DECLARE_MUTEX(load_sem); 52static DEFINE_MUTEX(load_mutex);
52#define LOAD_LOCK down(&load_sem) 53#define LOAD_LOCK mutex_lock(&load_mutex)
53#define LOAD_UNLOCK up(&load_sem) 54#define LOAD_UNLOCK mutex_unlock(&load_mutex)
54 55
55static struct sidtab sidtab; 56static struct sidtab sidtab;
56struct policydb policydb; 57struct policydb policydb;
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index b2af7ca496c1..dfab6c886698 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -225,6 +225,74 @@ void selinux_xfrm_state_free(struct xfrm_state *x)
225} 225}
226 226
227/* 227/*
228 * SELinux internal function to retrieve the context of a connected
229 * (sk->sk_state == TCP_ESTABLISHED) TCP socket based on its security
230 * association used to connect to the remote socket.
231 *
232 * Retrieve via getsockopt SO_PEERSEC.
233 */
234u32 selinux_socket_getpeer_stream(struct sock *sk)
235{
236 struct dst_entry *dst, *dst_test;
237 u32 peer_sid = SECSID_NULL;
238
239 if (sk->sk_state != TCP_ESTABLISHED)
240 goto out;
241
242 dst = sk_dst_get(sk);
243 if (!dst)
244 goto out;
245
246 for (dst_test = dst; dst_test != 0;
247 dst_test = dst_test->child) {
248 struct xfrm_state *x = dst_test->xfrm;
249
250 if (x && selinux_authorizable_xfrm(x)) {
251 struct xfrm_sec_ctx *ctx = x->security;
252 peer_sid = ctx->ctx_sid;
253 break;
254 }
255 }
256 dst_release(dst);
257
258out:
259 return peer_sid;
260}
261
262/*
263 * SELinux internal function to retrieve the context of a UDP packet
264 * based on its security association used to connect to the remote socket.
265 *
266 * Retrieve via setsockopt IP_PASSSEC and recvmsg with control message
267 * type SCM_SECURITY.
268 */
269u32 selinux_socket_getpeer_dgram(struct sk_buff *skb)
270{
271 struct sec_path *sp;
272
273 if (skb == NULL)
274 return SECSID_NULL;
275
276 if (skb->sk->sk_protocol != IPPROTO_UDP)
277 return SECSID_NULL;
278
279 sp = skb->sp;
280 if (sp) {
281 int i;
282
283 for (i = sp->len-1; i >= 0; i--) {
284 struct xfrm_state *x = sp->x[i].xvec;
285 if (selinux_authorizable_xfrm(x)) {
286 struct xfrm_sec_ctx *ctx = x->security;
287 return ctx->ctx_sid;
288 }
289 }
290 }
291
292 return SECSID_NULL;
293}
294
295/*
228 * LSM hook that controls access to unlabelled packets. If 296 * LSM hook that controls access to unlabelled packets. If
229 * a xfrm_state is authorizable (defined by macro) then it was 297 * a xfrm_state is authorizable (defined by macro) then it was
230 * already authorized by the IPSec process. If not, then 298 * already authorized by the IPSec process. If not, then