aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c581
1 files changed, 420 insertions, 161 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 21dad415b896..a91c961ba38b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -18,7 +18,6 @@
18 * as published by the Free Software Foundation. 18 * as published by the Free Software Foundation.
19 */ 19 */
20 20
21#include <linux/config.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/kernel.h> 23#include <linux/kernel.h>
@@ -69,6 +68,7 @@
69#include <linux/sysctl.h> 68#include <linux/sysctl.h>
70#include <linux/audit.h> 69#include <linux/audit.h>
71#include <linux/string.h> 70#include <linux/string.h>
71#include <linux/selinux.h>
72 72
73#include "avc.h" 73#include "avc.h"
74#include "objsec.h" 74#include "objsec.h"
@@ -80,6 +80,7 @@
80 80
81extern unsigned int policydb_loaded_version; 81extern unsigned int policydb_loaded_version;
82extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); 82extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
83extern int selinux_compat_net;
83 84
84#ifdef CONFIG_SECURITY_SELINUX_DEVELOP 85#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
85int selinux_enforcing = 0; 86int selinux_enforcing = 0;
@@ -245,6 +246,7 @@ static int superblock_alloc_security(struct super_block *sb)
245 sbsec->sb = sb; 246 sbsec->sb = sb;
246 sbsec->sid = SECINITSID_UNLABELED; 247 sbsec->sid = SECINITSID_UNLABELED;
247 sbsec->def_sid = SECINITSID_FILE; 248 sbsec->def_sid = SECINITSID_FILE;
249 sbsec->mntpoint_sid = SECINITSID_UNLABELED;
248 sb->s_security = sbsec; 250 sb->s_security = sbsec;
249 251
250 return 0; 252 return 0;
@@ -318,19 +320,53 @@ enum {
318 Opt_context = 1, 320 Opt_context = 1,
319 Opt_fscontext = 2, 321 Opt_fscontext = 2,
320 Opt_defcontext = 4, 322 Opt_defcontext = 4,
323 Opt_rootcontext = 8,
321}; 324};
322 325
323static match_table_t tokens = { 326static match_table_t tokens = {
324 {Opt_context, "context=%s"}, 327 {Opt_context, "context=%s"},
325 {Opt_fscontext, "fscontext=%s"}, 328 {Opt_fscontext, "fscontext=%s"},
326 {Opt_defcontext, "defcontext=%s"}, 329 {Opt_defcontext, "defcontext=%s"},
330 {Opt_rootcontext, "rootcontext=%s"},
327}; 331};
328 332
329#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n" 333#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
330 334
335static int may_context_mount_sb_relabel(u32 sid,
336 struct superblock_security_struct *sbsec,
337 struct task_security_struct *tsec)
338{
339 int rc;
340
341 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
342 FILESYSTEM__RELABELFROM, NULL);
343 if (rc)
344 return rc;
345
346 rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
347 FILESYSTEM__RELABELTO, NULL);
348 return rc;
349}
350
351static int may_context_mount_inode_relabel(u32 sid,
352 struct superblock_security_struct *sbsec,
353 struct task_security_struct *tsec)
354{
355 int rc;
356 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
357 FILESYSTEM__RELABELFROM, NULL);
358 if (rc)
359 return rc;
360
361 rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
362 FILESYSTEM__ASSOCIATE, NULL);
363 return rc;
364}
365
331static int try_context_mount(struct super_block *sb, void *data) 366static int try_context_mount(struct super_block *sb, void *data)
332{ 367{
333 char *context = NULL, *defcontext = NULL; 368 char *context = NULL, *defcontext = NULL;
369 char *fscontext = NULL, *rootcontext = NULL;
334 const char *name; 370 const char *name;
335 u32 sid; 371 u32 sid;
336 int alloc = 0, rc = 0, seen = 0; 372 int alloc = 0, rc = 0, seen = 0;
@@ -373,7 +409,7 @@ static int try_context_mount(struct super_block *sb, void *data)
373 409
374 switch (token) { 410 switch (token) {
375 case Opt_context: 411 case Opt_context:
376 if (seen) { 412 if (seen & (Opt_context|Opt_defcontext)) {
377 rc = -EINVAL; 413 rc = -EINVAL;
378 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG); 414 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
379 goto out_free; 415 goto out_free;
@@ -389,13 +425,13 @@ static int try_context_mount(struct super_block *sb, void *data)
389 break; 425 break;
390 426
391 case Opt_fscontext: 427 case Opt_fscontext:
392 if (seen & (Opt_context|Opt_fscontext)) { 428 if (seen & Opt_fscontext) {
393 rc = -EINVAL; 429 rc = -EINVAL;
394 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG); 430 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
395 goto out_free; 431 goto out_free;
396 } 432 }
397 context = match_strdup(&args[0]); 433 fscontext = match_strdup(&args[0]);
398 if (!context) { 434 if (!fscontext) {
399 rc = -ENOMEM; 435 rc = -ENOMEM;
400 goto out_free; 436 goto out_free;
401 } 437 }
@@ -404,6 +440,22 @@ static int try_context_mount(struct super_block *sb, void *data)
404 seen |= Opt_fscontext; 440 seen |= Opt_fscontext;
405 break; 441 break;
406 442
443 case Opt_rootcontext:
444 if (seen & Opt_rootcontext) {
445 rc = -EINVAL;
446 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
447 goto out_free;
448 }
449 rootcontext = match_strdup(&args[0]);
450 if (!rootcontext) {
451 rc = -ENOMEM;
452 goto out_free;
453 }
454 if (!alloc)
455 alloc = 1;
456 seen |= Opt_rootcontext;
457 break;
458
407 case Opt_defcontext: 459 case Opt_defcontext:
408 if (sbsec->behavior != SECURITY_FS_USE_XATTR) { 460 if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
409 rc = -EINVAL; 461 rc = -EINVAL;
@@ -440,6 +492,28 @@ static int try_context_mount(struct super_block *sb, void *data)
440 if (!seen) 492 if (!seen)
441 goto out; 493 goto out;
442 494
495 /* sets the context of the superblock for the fs being mounted. */
496 if (fscontext) {
497 rc = security_context_to_sid(fscontext, strlen(fscontext), &sid);
498 if (rc) {
499 printk(KERN_WARNING "SELinux: security_context_to_sid"
500 "(%s) failed for (dev %s, type %s) errno=%d\n",
501 fscontext, sb->s_id, name, rc);
502 goto out_free;
503 }
504
505 rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
506 if (rc)
507 goto out_free;
508
509 sbsec->sid = sid;
510 }
511
512 /*
513 * Switch to using mount point labeling behavior.
514 * sets the label used on all file below the mountpoint, and will set
515 * the superblock context if not already set.
516 */
443 if (context) { 517 if (context) {
444 rc = security_context_to_sid(context, strlen(context), &sid); 518 rc = security_context_to_sid(context, strlen(context), &sid);
445 if (rc) { 519 if (rc) {
@@ -449,20 +523,38 @@ static int try_context_mount(struct super_block *sb, void *data)
449 goto out_free; 523 goto out_free;
450 } 524 }
451 525
452 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, 526 if (!fscontext) {
453 FILESYSTEM__RELABELFROM, NULL); 527 rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
454 if (rc) 528 if (rc)
529 goto out_free;
530 sbsec->sid = sid;
531 } else {
532 rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
533 if (rc)
534 goto out_free;
535 }
536 sbsec->mntpoint_sid = sid;
537
538 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
539 }
540
541 if (rootcontext) {
542 struct inode *inode = sb->s_root->d_inode;
543 struct inode_security_struct *isec = inode->i_security;
544 rc = security_context_to_sid(rootcontext, strlen(rootcontext), &sid);
545 if (rc) {
546 printk(KERN_WARNING "SELinux: security_context_to_sid"
547 "(%s) failed for (dev %s, type %s) errno=%d\n",
548 rootcontext, sb->s_id, name, rc);
455 goto out_free; 549 goto out_free;
550 }
456 551
457 rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM, 552 rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
458 FILESYSTEM__RELABELTO, NULL);
459 if (rc) 553 if (rc)
460 goto out_free; 554 goto out_free;
461 555
462 sbsec->sid = sid; 556 isec->sid = sid;
463 557 isec->initialized = 1;
464 if (seen & Opt_context)
465 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
466 } 558 }
467 559
468 if (defcontext) { 560 if (defcontext) {
@@ -477,13 +569,7 @@ static int try_context_mount(struct super_block *sb, void *data)
477 if (sid == sbsec->def_sid) 569 if (sid == sbsec->def_sid)
478 goto out_free; 570 goto out_free;
479 571
480 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, 572 rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
481 FILESYSTEM__RELABELFROM, NULL);
482 if (rc)
483 goto out_free;
484
485 rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
486 FILESYSTEM__ASSOCIATE, NULL);
487 if (rc) 573 if (rc)
488 goto out_free; 574 goto out_free;
489 575
@@ -494,6 +580,8 @@ out_free:
494 if (alloc) { 580 if (alloc) {
495 kfree(context); 581 kfree(context);
496 kfree(defcontext); 582 kfree(defcontext);
583 kfree(fscontext);
584 kfree(rootcontext);
497 } 585 }
498out: 586out:
499 return rc; 587 return rc;
@@ -696,6 +784,8 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
696 return SECCLASS_PACKET_SOCKET; 784 return SECCLASS_PACKET_SOCKET;
697 case PF_KEY: 785 case PF_KEY:
698 return SECCLASS_KEY_SOCKET; 786 return SECCLASS_KEY_SOCKET;
787 case PF_APPLETALK:
788 return SECCLASS_APPLETALK_SOCKET;
699 } 789 }
700 790
701 return SECCLASS_SOCKET; 791 return SECCLASS_SOCKET;
@@ -873,8 +963,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
873 goto out; 963 goto out;
874 isec->sid = sid; 964 isec->sid = sid;
875 break; 965 break;
966 case SECURITY_FS_USE_MNTPOINT:
967 isec->sid = sbsec->mntpoint_sid;
968 break;
876 default: 969 default:
877 /* Default to the fs SID. */ 970 /* Default to the fs superblock SID. */
878 isec->sid = sbsec->sid; 971 isec->sid = sbsec->sid;
879 972
880 if (sbsec->proc) { 973 if (sbsec->proc) {
@@ -1096,6 +1189,17 @@ static int may_create(struct inode *dir,
1096 FILESYSTEM__ASSOCIATE, &ad); 1189 FILESYSTEM__ASSOCIATE, &ad);
1097} 1190}
1098 1191
1192/* Check whether a task can create a key. */
1193static int may_create_key(u32 ksid,
1194 struct task_struct *ctx)
1195{
1196 struct task_security_struct *tsec;
1197
1198 tsec = ctx->security;
1199
1200 return avc_has_perm(tsec->sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL);
1201}
1202
1099#define MAY_LINK 0 1203#define MAY_LINK 0
1100#define MAY_UNLINK 1 1204#define MAY_UNLINK 1
1101#define MAY_RMDIR 2 1205#define MAY_RMDIR 2
@@ -1518,8 +1622,10 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm)
1518 /* Default to the current task SID. */ 1622 /* Default to the current task SID. */
1519 bsec->sid = tsec->sid; 1623 bsec->sid = tsec->sid;
1520 1624
1521 /* Reset create SID on execve. */ 1625 /* Reset fs, key, and sock SIDs on execve. */
1522 tsec->create_sid = 0; 1626 tsec->create_sid = 0;
1627 tsec->keycreate_sid = 0;
1628 tsec->sockcreate_sid = 0;
1523 1629
1524 if (tsec->exec_sid) { 1630 if (tsec->exec_sid) {
1525 newsid = tsec->exec_sid; 1631 newsid = tsec->exec_sid;
@@ -1827,7 +1933,8 @@ static inline int selinux_option(char *option, int len)
1827{ 1933{
1828 return (match_prefix("context=", sizeof("context=")-1, option, len) || 1934 return (match_prefix("context=", sizeof("context=")-1, option, len) ||
1829 match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) || 1935 match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) ||
1830 match_prefix("defcontext=", sizeof("defcontext=")-1, option, len)); 1936 match_prefix("defcontext=", sizeof("defcontext=")-1, option, len) ||
1937 match_prefix("rootcontext=", sizeof("rootcontext=")-1, option, len));
1831} 1938}
1832 1939
1833static inline void take_option(char **to, char *from, int *first, int len) 1940static inline void take_option(char **to, char *from, int *first, int len)
@@ -1900,13 +2007,13 @@ static int selinux_sb_kern_mount(struct super_block *sb, void *data)
1900 return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); 2007 return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad);
1901} 2008}
1902 2009
1903static int selinux_sb_statfs(struct super_block *sb) 2010static int selinux_sb_statfs(struct dentry *dentry)
1904{ 2011{
1905 struct avc_audit_data ad; 2012 struct avc_audit_data ad;
1906 2013
1907 AVC_AUDIT_DATA_INIT(&ad,FS); 2014 AVC_AUDIT_DATA_INIT(&ad,FS);
1908 ad.u.fs.dentry = sb->s_root; 2015 ad.u.fs.dentry = dentry->d_sb->s_root;
1909 return superblock_has_perm(current, sb, FILESYSTEM__GETATTR, &ad); 2016 return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
1910} 2017}
1911 2018
1912static int selinux_mount(char * dev_name, 2019static int selinux_mount(char * dev_name,
@@ -2571,9 +2678,11 @@ static int selinux_task_alloc_security(struct task_struct *tsk)
2571 tsec2->osid = tsec1->osid; 2678 tsec2->osid = tsec1->osid;
2572 tsec2->sid = tsec1->sid; 2679 tsec2->sid = tsec1->sid;
2573 2680
2574 /* Retain the exec and create SIDs across fork */ 2681 /* Retain the exec, fs, key, and sock SIDs across fork */
2575 tsec2->exec_sid = tsec1->exec_sid; 2682 tsec2->exec_sid = tsec1->exec_sid;
2576 tsec2->create_sid = tsec1->create_sid; 2683 tsec2->create_sid = tsec1->create_sid;
2684 tsec2->keycreate_sid = tsec1->keycreate_sid;
2685 tsec2->sockcreate_sid = tsec1->sockcreate_sid;
2577 2686
2578 /* Retain ptracer SID across fork, if any. 2687 /* Retain ptracer SID across fork, if any.
2579 This will be reset by the ptrace hook upon any 2688 This will be reset by the ptrace hook upon any
@@ -2625,6 +2734,11 @@ static int selinux_task_getsid(struct task_struct *p)
2625 return task_has_perm(current, p, PROCESS__GETSESSION); 2734 return task_has_perm(current, p, PROCESS__GETSESSION);
2626} 2735}
2627 2736
2737static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
2738{
2739 selinux_get_task_sid(p, secid);
2740}
2741
2628static int selinux_task_setgroups(struct group_info *group_info) 2742static int selinux_task_setgroups(struct group_info *group_info)
2629{ 2743{
2630 /* See the comment for setuid above. */ 2744 /* See the comment for setuid above. */
@@ -2642,6 +2756,16 @@ static int selinux_task_setnice(struct task_struct *p, int nice)
2642 return task_has_perm(current,p, PROCESS__SETSCHED); 2756 return task_has_perm(current,p, PROCESS__SETSCHED);
2643} 2757}
2644 2758
2759static int selinux_task_setioprio(struct task_struct *p, int ioprio)
2760{
2761 return task_has_perm(current, p, PROCESS__SETSCHED);
2762}
2763
2764static int selinux_task_getioprio(struct task_struct *p)
2765{
2766 return task_has_perm(current, p, PROCESS__GETSCHED);
2767}
2768
2645static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) 2769static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
2646{ 2770{
2647 struct rlimit *old_rlim = current->signal->rlim + resource; 2771 struct rlimit *old_rlim = current->signal->rlim + resource;
@@ -2671,12 +2795,19 @@ static int selinux_task_getscheduler(struct task_struct *p)
2671 return task_has_perm(current, p, PROCESS__GETSCHED); 2795 return task_has_perm(current, p, PROCESS__GETSCHED);
2672} 2796}
2673 2797
2674static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig) 2798static int selinux_task_movememory(struct task_struct *p)
2799{
2800 return task_has_perm(current, p, PROCESS__SETSCHED);
2801}
2802
2803static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
2804 int sig, u32 secid)
2675{ 2805{
2676 u32 perm; 2806 u32 perm;
2677 int rc; 2807 int rc;
2808 struct task_security_struct *tsec;
2678 2809
2679 rc = secondary_ops->task_kill(p, info, sig); 2810 rc = secondary_ops->task_kill(p, info, sig, secid);
2680 if (rc) 2811 if (rc)
2681 return rc; 2812 return rc;
2682 2813
@@ -2687,8 +2818,12 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si
2687 perm = PROCESS__SIGNULL; /* null signal; existence test */ 2818 perm = PROCESS__SIGNULL; /* null signal; existence test */
2688 else 2819 else
2689 perm = signal_to_av(sig); 2820 perm = signal_to_av(sig);
2690 2821 tsec = p->security;
2691 return task_has_perm(current, p, perm); 2822 if (secid)
2823 rc = avc_has_perm(secid, tsec->sid, SECCLASS_PROCESS, perm, NULL);
2824 else
2825 rc = task_has_perm(current, p, perm);
2826 return rc;
2692} 2827}
2693 2828
2694static int selinux_task_prctl(int option, 2829static int selinux_task_prctl(int option,
@@ -2913,12 +3048,14 @@ static int selinux_socket_create(int family, int type,
2913{ 3048{
2914 int err = 0; 3049 int err = 0;
2915 struct task_security_struct *tsec; 3050 struct task_security_struct *tsec;
3051 u32 newsid;
2916 3052
2917 if (kern) 3053 if (kern)
2918 goto out; 3054 goto out;
2919 3055
2920 tsec = current->security; 3056 tsec = current->security;
2921 err = avc_has_perm(tsec->sid, tsec->sid, 3057 newsid = tsec->sockcreate_sid ? : tsec->sid;
3058 err = avc_has_perm(tsec->sid, newsid,
2922 socket_type_to_security_class(family, type, 3059 socket_type_to_security_class(family, type,
2923 protocol), SOCKET__CREATE, NULL); 3060 protocol), SOCKET__CREATE, NULL);
2924 3061
@@ -2931,12 +3068,14 @@ static void selinux_socket_post_create(struct socket *sock, int family,
2931{ 3068{
2932 struct inode_security_struct *isec; 3069 struct inode_security_struct *isec;
2933 struct task_security_struct *tsec; 3070 struct task_security_struct *tsec;
3071 u32 newsid;
2934 3072
2935 isec = SOCK_INODE(sock)->i_security; 3073 isec = SOCK_INODE(sock)->i_security;
2936 3074
2937 tsec = current->security; 3075 tsec = current->security;
3076 newsid = tsec->sockcreate_sid ? : tsec->sid;
2938 isec->sclass = socket_type_to_security_class(family, type, protocol); 3077 isec->sclass = socket_type_to_security_class(family, type, protocol);
2939 isec->sid = kern ? SECINITSID_KERNEL : tsec->sid; 3078 isec->sid = kern ? SECINITSID_KERNEL : newsid;
2940 isec->initialized = 1; 3079 isec->initialized = 1;
2941 3080
2942 return; 3081 return;
@@ -3214,47 +3353,17 @@ static int selinux_socket_unix_may_send(struct socket *sock,
3214 return 0; 3353 return 0;
3215} 3354}
3216 3355
3217static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) 3356static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
3357 struct avc_audit_data *ad, u32 sock_sid, u16 sock_class,
3358 u16 family, char *addrp, int len)
3218{ 3359{
3219 u16 family; 3360 int err = 0;
3220 char *addrp;
3221 int len, err = 0;
3222 u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0; 3361 u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
3223 u32 sock_sid = 0;
3224 u16 sock_class = 0;
3225 struct socket *sock;
3226 struct net_device *dev;
3227 struct avc_audit_data ad;
3228 3362
3229 family = sk->sk_family; 3363 if (!skb->dev)
3230 if (family != PF_INET && family != PF_INET6)
3231 goto out; 3364 goto out;
3232 3365
3233 /* Handle mapped IPv4 packets arriving via IPv6 sockets */ 3366 err = sel_netif_sids(skb->dev, &if_sid, NULL);
3234 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
3235 family = PF_INET;
3236
3237 read_lock_bh(&sk->sk_callback_lock);
3238 sock = sk->sk_socket;
3239 if (sock) {
3240 struct inode *inode;
3241 inode = SOCK_INODE(sock);
3242 if (inode) {
3243 struct inode_security_struct *isec;
3244 isec = inode->i_security;
3245 sock_sid = isec->sid;
3246 sock_class = isec->sclass;
3247 }
3248 }
3249 read_unlock_bh(&sk->sk_callback_lock);
3250 if (!sock_sid)
3251 goto out;
3252
3253 dev = skb->dev;
3254 if (!dev)
3255 goto out;
3256
3257 err = sel_netif_sids(dev, &if_sid, NULL);
3258 if (err) 3367 if (err)
3259 goto out; 3368 goto out;
3260 3369
@@ -3277,44 +3386,88 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3277 break; 3386 break;
3278 } 3387 }
3279 3388
3280 AVC_AUDIT_DATA_INIT(&ad, NET); 3389 err = avc_has_perm(sock_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
3281 ad.u.net.netif = dev->name;
3282 ad.u.net.family = family;
3283
3284 err = selinux_parse_skb(skb, &ad, &addrp, &len, 1);
3285 if (err)
3286 goto out;
3287
3288 err = avc_has_perm(sock_sid, if_sid, SECCLASS_NETIF, netif_perm, &ad);
3289 if (err) 3390 if (err)
3290 goto out; 3391 goto out;
3291 3392
3292 /* Fixme: this lookup is inefficient */
3293 err = security_node_sid(family, addrp, len, &node_sid); 3393 err = security_node_sid(family, addrp, len, &node_sid);
3294 if (err) 3394 if (err)
3295 goto out; 3395 goto out;
3296 3396
3297 err = avc_has_perm(sock_sid, node_sid, SECCLASS_NODE, node_perm, &ad); 3397 err = avc_has_perm(sock_sid, node_sid, SECCLASS_NODE, node_perm, ad);
3298 if (err) 3398 if (err)
3299 goto out; 3399 goto out;
3300 3400
3301 if (recv_perm) { 3401 if (recv_perm) {
3302 u32 port_sid; 3402 u32 port_sid;
3303 3403
3304 /* Fixme: make this more efficient */
3305 err = security_port_sid(sk->sk_family, sk->sk_type, 3404 err = security_port_sid(sk->sk_family, sk->sk_type,
3306 sk->sk_protocol, ntohs(ad.u.net.sport), 3405 sk->sk_protocol, ntohs(ad->u.net.sport),
3307 &port_sid); 3406 &port_sid);
3308 if (err) 3407 if (err)
3309 goto out; 3408 goto out;
3310 3409
3311 err = avc_has_perm(sock_sid, port_sid, 3410 err = avc_has_perm(sock_sid, port_sid,
3312 sock_class, recv_perm, &ad); 3411 sock_class, recv_perm, ad);
3313 } 3412 }
3314 3413
3315 if (!err) 3414out:
3316 err = selinux_xfrm_sock_rcv_skb(sock_sid, skb); 3415 return err;
3416}
3417
3418static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3419{
3420 u16 family;
3421 u16 sock_class = 0;
3422 char *addrp;
3423 int len, err = 0;
3424 u32 sock_sid = 0;
3425 struct socket *sock;
3426 struct avc_audit_data ad;
3427
3428 family = sk->sk_family;
3429 if (family != PF_INET && family != PF_INET6)
3430 goto out;
3431
3432 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
3433 if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP))
3434 family = PF_INET;
3435
3436 read_lock_bh(&sk->sk_callback_lock);
3437 sock = sk->sk_socket;
3438 if (sock) {
3439 struct inode *inode;
3440 inode = SOCK_INODE(sock);
3441 if (inode) {
3442 struct inode_security_struct *isec;
3443 isec = inode->i_security;
3444 sock_sid = isec->sid;
3445 sock_class = isec->sclass;
3446 }
3447 }
3448 read_unlock_bh(&sk->sk_callback_lock);
3449 if (!sock_sid)
3450 goto out;
3451
3452 AVC_AUDIT_DATA_INIT(&ad, NET);
3453 ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
3454 ad.u.net.family = family;
3455
3456 err = selinux_parse_skb(skb, &ad, &addrp, &len, 1);
3457 if (err)
3458 goto out;
3317 3459
3460 if (selinux_compat_net)
3461 err = selinux_sock_rcv_skb_compat(sk, skb, &ad, sock_sid,
3462 sock_class, family,
3463 addrp, len);
3464 else
3465 err = avc_has_perm(sock_sid, skb->secmark, SECCLASS_PACKET,
3466 PACKET__RECV, &ad);
3467 if (err)
3468 goto out;
3469
3470 err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
3318out: 3471out:
3319 return err; 3472 return err;
3320} 3473}
@@ -3374,7 +3527,13 @@ out:
3374static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen) 3527static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
3375{ 3528{
3376 int err = 0; 3529 int err = 0;
3377 u32 peer_sid = selinux_socket_getpeer_dgram(skb); 3530 u32 peer_sid;
3531
3532 if (skb->sk->sk_family == PF_UNIX)
3533 selinux_get_inode_sid(SOCK_INODE(skb->sk->sk_socket),
3534 &peer_sid);
3535 else
3536 peer_sid = selinux_socket_getpeer_dgram(skb);
3378 3537
3379 if (peer_sid == SECSID_NULL) 3538 if (peer_sid == SECSID_NULL)
3380 return -EINVAL; 3539 return -EINVAL;
@@ -3386,8 +3545,6 @@ static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata,
3386 return 0; 3545 return 0;
3387} 3546}
3388 3547
3389
3390
3391static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) 3548static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
3392{ 3549{
3393 return sk_alloc_security(sk, family, priority); 3550 return sk_alloc_security(sk, family, priority);
@@ -3454,42 +3611,18 @@ out:
3454 3611
3455#ifdef CONFIG_NETFILTER 3612#ifdef CONFIG_NETFILTER
3456 3613
3457static unsigned int selinux_ip_postroute_last(unsigned int hooknum, 3614static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev,
3458 struct sk_buff **pskb, 3615 struct inode_security_struct *isec,
3459 const struct net_device *in, 3616 struct avc_audit_data *ad,
3460 const struct net_device *out, 3617 u16 family, char *addrp, int len)
3461 int (*okfn)(struct sk_buff *),
3462 u16 family)
3463{ 3618{
3464 char *addrp; 3619 int err;
3465 int len, err = NF_ACCEPT;
3466 u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0; 3620 u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0;
3467 struct sock *sk;
3468 struct socket *sock;
3469 struct inode *inode;
3470 struct sk_buff *skb = *pskb;
3471 struct inode_security_struct *isec;
3472 struct avc_audit_data ad;
3473 struct net_device *dev = (struct net_device *)out;
3474 3621
3475 sk = skb->sk;
3476 if (!sk)
3477 goto out;
3478
3479 sock = sk->sk_socket;
3480 if (!sock)
3481 goto out;
3482
3483 inode = SOCK_INODE(sock);
3484 if (!inode)
3485 goto out;
3486
3487 err = sel_netif_sids(dev, &if_sid, NULL); 3622 err = sel_netif_sids(dev, &if_sid, NULL);
3488 if (err) 3623 if (err)
3489 goto out; 3624 goto out;
3490 3625
3491 isec = inode->i_security;
3492
3493 switch (isec->sclass) { 3626 switch (isec->sclass) {
3494 case SECCLASS_UDP_SOCKET: 3627 case SECCLASS_UDP_SOCKET:
3495 netif_perm = NETIF__UDP_SEND; 3628 netif_perm = NETIF__UDP_SEND;
@@ -3509,55 +3642,88 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3509 break; 3642 break;
3510 } 3643 }
3511 3644
3512 3645 err = avc_has_perm(isec->sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
3513 AVC_AUDIT_DATA_INIT(&ad, NET); 3646 if (err)
3514 ad.u.net.netif = dev->name;
3515 ad.u.net.family = family;
3516
3517 err = selinux_parse_skb(skb, &ad, &addrp,
3518 &len, 0) ? NF_DROP : NF_ACCEPT;
3519 if (err != NF_ACCEPT)
3520 goto out;
3521
3522 err = avc_has_perm(isec->sid, if_sid, SECCLASS_NETIF,
3523 netif_perm, &ad) ? NF_DROP : NF_ACCEPT;
3524 if (err != NF_ACCEPT)
3525 goto out; 3647 goto out;
3526 3648
3527 /* Fixme: this lookup is inefficient */ 3649 err = security_node_sid(family, addrp, len, &node_sid);
3528 err = security_node_sid(family, addrp, len, 3650 if (err)
3529 &node_sid) ? NF_DROP : NF_ACCEPT;
3530 if (err != NF_ACCEPT)
3531 goto out; 3651 goto out;
3532 3652
3533 err = avc_has_perm(isec->sid, node_sid, SECCLASS_NODE, 3653 err = avc_has_perm(isec->sid, node_sid, SECCLASS_NODE, node_perm, ad);
3534 node_perm, &ad) ? NF_DROP : NF_ACCEPT; 3654 if (err)
3535 if (err != NF_ACCEPT)
3536 goto out; 3655 goto out;
3537 3656
3538 if (send_perm) { 3657 if (send_perm) {
3539 u32 port_sid; 3658 u32 port_sid;
3540 3659
3541 /* Fixme: make this more efficient */
3542 err = security_port_sid(sk->sk_family, 3660 err = security_port_sid(sk->sk_family,
3543 sk->sk_type, 3661 sk->sk_type,
3544 sk->sk_protocol, 3662 sk->sk_protocol,
3545 ntohs(ad.u.net.dport), 3663 ntohs(ad->u.net.dport),
3546 &port_sid) ? NF_DROP : NF_ACCEPT; 3664 &port_sid);
3547 if (err != NF_ACCEPT) 3665 if (err)
3548 goto out; 3666 goto out;
3549 3667
3550 err = avc_has_perm(isec->sid, port_sid, isec->sclass, 3668 err = avc_has_perm(isec->sid, port_sid, isec->sclass,
3551 send_perm, &ad) ? NF_DROP : NF_ACCEPT; 3669 send_perm, ad);
3552 } 3670 }
3671out:
3672 return err;
3673}
3674
3675static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3676 struct sk_buff **pskb,
3677 const struct net_device *in,
3678 const struct net_device *out,
3679 int (*okfn)(struct sk_buff *),
3680 u16 family)
3681{
3682 char *addrp;
3683 int len, err = 0;
3684 struct sock *sk;
3685 struct socket *sock;
3686 struct inode *inode;
3687 struct sk_buff *skb = *pskb;
3688 struct inode_security_struct *isec;
3689 struct avc_audit_data ad;
3690 struct net_device *dev = (struct net_device *)out;
3553 3691
3554 if (err != NF_ACCEPT) 3692 sk = skb->sk;
3693 if (!sk)
3555 goto out; 3694 goto out;
3556 3695
3557 err = selinux_xfrm_postroute_last(isec->sid, skb); 3696 sock = sk->sk_socket;
3697 if (!sock)
3698 goto out;
3699
3700 inode = SOCK_INODE(sock);
3701 if (!inode)
3702 goto out;
3703
3704 isec = inode->i_security;
3705
3706 AVC_AUDIT_DATA_INIT(&ad, NET);
3707 ad.u.net.netif = dev->name;
3708 ad.u.net.family = family;
3558 3709
3710 err = selinux_parse_skb(skb, &ad, &addrp, &len, 0);
3711 if (err)
3712 goto out;
3713
3714 if (selinux_compat_net)
3715 err = selinux_ip_postroute_last_compat(sk, dev, isec, &ad,
3716 family, addrp, len);
3717 else
3718 err = avc_has_perm(isec->sid, skb->secmark, SECCLASS_PACKET,
3719 PACKET__SEND, &ad);
3720
3721 if (err)
3722 goto out;
3723
3724 err = selinux_xfrm_postroute_last(isec->sid, skb);
3559out: 3725out:
3560 return err; 3726 return err ? NF_DROP : NF_ACCEPT;
3561} 3727}
3562 3728
3563static unsigned int selinux_ipv4_postroute_last(unsigned int hooknum, 3729static unsigned int selinux_ipv4_postroute_last(unsigned int hooknum,
@@ -3586,32 +3752,32 @@ static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum,
3586 3752
3587static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) 3753static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
3588{ 3754{
3589 struct task_security_struct *tsec;
3590 struct av_decision avd;
3591 int err; 3755 int err;
3592 3756
3593 err = secondary_ops->netlink_send(sk, skb); 3757 err = secondary_ops->netlink_send(sk, skb);
3594 if (err) 3758 if (err)
3595 return err; 3759 return err;
3596 3760
3597 tsec = current->security;
3598
3599 avd.allowed = 0;
3600 avc_has_perm_noaudit(tsec->sid, tsec->sid,
3601 SECCLASS_CAPABILITY, ~0, &avd);
3602 cap_mask(NETLINK_CB(skb).eff_cap, avd.allowed);
3603
3604 if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS) 3761 if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
3605 err = selinux_nlmsg_perm(sk, skb); 3762 err = selinux_nlmsg_perm(sk, skb);
3606 3763
3607 return err; 3764 return err;
3608} 3765}
3609 3766
3610static int selinux_netlink_recv(struct sk_buff *skb) 3767static int selinux_netlink_recv(struct sk_buff *skb, int capability)
3611{ 3768{
3612 if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) 3769 int err;
3613 return -EPERM; 3770 struct avc_audit_data ad;
3614 return 0; 3771
3772 err = secondary_ops->netlink_recv(skb, capability);
3773 if (err)
3774 return err;
3775
3776 AVC_AUDIT_DATA_INIT(&ad, CAP);
3777 ad.u.cap = capability;
3778
3779 return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid,
3780 SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad);
3615} 3781}
3616 3782
3617static int ipc_alloc_security(struct task_struct *task, 3783static int ipc_alloc_security(struct task_struct *task,
@@ -4114,6 +4280,10 @@ static int selinux_getprocattr(struct task_struct *p,
4114 sid = tsec->exec_sid; 4280 sid = tsec->exec_sid;
4115 else if (!strcmp(name, "fscreate")) 4281 else if (!strcmp(name, "fscreate"))
4116 sid = tsec->create_sid; 4282 sid = tsec->create_sid;
4283 else if (!strcmp(name, "keycreate"))
4284 sid = tsec->keycreate_sid;
4285 else if (!strcmp(name, "sockcreate"))
4286 sid = tsec->sockcreate_sid;
4117 else 4287 else
4118 return -EINVAL; 4288 return -EINVAL;
4119 4289
@@ -4146,6 +4316,10 @@ static int selinux_setprocattr(struct task_struct *p,
4146 error = task_has_perm(current, p, PROCESS__SETEXEC); 4316 error = task_has_perm(current, p, PROCESS__SETEXEC);
4147 else if (!strcmp(name, "fscreate")) 4317 else if (!strcmp(name, "fscreate"))
4148 error = task_has_perm(current, p, PROCESS__SETFSCREATE); 4318 error = task_has_perm(current, p, PROCESS__SETFSCREATE);
4319 else if (!strcmp(name, "keycreate"))
4320 error = task_has_perm(current, p, PROCESS__SETKEYCREATE);
4321 else if (!strcmp(name, "sockcreate"))
4322 error = task_has_perm(current, p, PROCESS__SETSOCKCREATE);
4149 else if (!strcmp(name, "current")) 4323 else if (!strcmp(name, "current"))
4150 error = task_has_perm(current, p, PROCESS__SETCURRENT); 4324 error = task_has_perm(current, p, PROCESS__SETCURRENT);
4151 else 4325 else
@@ -4175,6 +4349,13 @@ static int selinux_setprocattr(struct task_struct *p,
4175 tsec->exec_sid = sid; 4349 tsec->exec_sid = sid;
4176 else if (!strcmp(name, "fscreate")) 4350 else if (!strcmp(name, "fscreate"))
4177 tsec->create_sid = sid; 4351 tsec->create_sid = sid;
4352 else if (!strcmp(name, "keycreate")) {
4353 error = may_create_key(sid, p);
4354 if (error)
4355 return error;
4356 tsec->keycreate_sid = sid;
4357 } else if (!strcmp(name, "sockcreate"))
4358 tsec->sockcreate_sid = sid;
4178 else if (!strcmp(name, "current")) { 4359 else if (!strcmp(name, "current")) {
4179 struct av_decision avd; 4360 struct av_decision avd;
4180 4361
@@ -4226,6 +4407,61 @@ static int selinux_setprocattr(struct task_struct *p,
4226 return size; 4407 return size;
4227} 4408}
4228 4409
4410#ifdef CONFIG_KEYS
4411
4412static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
4413 unsigned long flags)
4414{
4415 struct task_security_struct *tsec = tsk->security;
4416 struct key_security_struct *ksec;
4417
4418 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
4419 if (!ksec)
4420 return -ENOMEM;
4421
4422 ksec->obj = k;
4423 if (tsec->keycreate_sid)
4424 ksec->sid = tsec->keycreate_sid;
4425 else
4426 ksec->sid = tsec->sid;
4427 k->security = ksec;
4428
4429 return 0;
4430}
4431
4432static void selinux_key_free(struct key *k)
4433{
4434 struct key_security_struct *ksec = k->security;
4435
4436 k->security = NULL;
4437 kfree(ksec);
4438}
4439
4440static int selinux_key_permission(key_ref_t key_ref,
4441 struct task_struct *ctx,
4442 key_perm_t perm)
4443{
4444 struct key *key;
4445 struct task_security_struct *tsec;
4446 struct key_security_struct *ksec;
4447
4448 key = key_ref_to_ptr(key_ref);
4449
4450 tsec = ctx->security;
4451 ksec = key->security;
4452
4453 /* if no specific permissions are requested, we skip the
4454 permission check. No serious, additional covert channels
4455 appear to be created. */
4456 if (perm == 0)
4457 return 0;
4458
4459 return avc_has_perm(tsec->sid, ksec->sid,
4460 SECCLASS_KEY, perm, NULL);
4461}
4462
4463#endif
4464
4229static struct security_operations selinux_ops = { 4465static struct security_operations selinux_ops = {
4230 .ptrace = selinux_ptrace, 4466 .ptrace = selinux_ptrace,
4231 .capget = selinux_capget, 4467 .capget = selinux_capget,
@@ -4304,11 +4540,15 @@ static struct security_operations selinux_ops = {
4304 .task_setpgid = selinux_task_setpgid, 4540 .task_setpgid = selinux_task_setpgid,
4305 .task_getpgid = selinux_task_getpgid, 4541 .task_getpgid = selinux_task_getpgid,
4306 .task_getsid = selinux_task_getsid, 4542 .task_getsid = selinux_task_getsid,
4543 .task_getsecid = selinux_task_getsecid,
4307 .task_setgroups = selinux_task_setgroups, 4544 .task_setgroups = selinux_task_setgroups,
4308 .task_setnice = selinux_task_setnice, 4545 .task_setnice = selinux_task_setnice,
4546 .task_setioprio = selinux_task_setioprio,
4547 .task_getioprio = selinux_task_getioprio,
4309 .task_setrlimit = selinux_task_setrlimit, 4548 .task_setrlimit = selinux_task_setrlimit,
4310 .task_setscheduler = selinux_task_setscheduler, 4549 .task_setscheduler = selinux_task_setscheduler,
4311 .task_getscheduler = selinux_task_getscheduler, 4550 .task_getscheduler = selinux_task_getscheduler,
4551 .task_movememory = selinux_task_movememory,
4312 .task_kill = selinux_task_kill, 4552 .task_kill = selinux_task_kill,
4313 .task_wait = selinux_task_wait, 4553 .task_wait = selinux_task_wait,
4314 .task_prctl = selinux_task_prctl, 4554 .task_prctl = selinux_task_prctl,
@@ -4374,10 +4614,18 @@ static struct security_operations selinux_ops = {
4374 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, 4614 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
4375 .xfrm_policy_clone_security = selinux_xfrm_policy_clone, 4615 .xfrm_policy_clone_security = selinux_xfrm_policy_clone,
4376 .xfrm_policy_free_security = selinux_xfrm_policy_free, 4616 .xfrm_policy_free_security = selinux_xfrm_policy_free,
4617 .xfrm_policy_delete_security = selinux_xfrm_policy_delete,
4377 .xfrm_state_alloc_security = selinux_xfrm_state_alloc, 4618 .xfrm_state_alloc_security = selinux_xfrm_state_alloc,
4378 .xfrm_state_free_security = selinux_xfrm_state_free, 4619 .xfrm_state_free_security = selinux_xfrm_state_free,
4620 .xfrm_state_delete_security = selinux_xfrm_state_delete,
4379 .xfrm_policy_lookup = selinux_xfrm_policy_lookup, 4621 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
4380#endif 4622#endif
4623
4624#ifdef CONFIG_KEYS
4625 .key_alloc = selinux_key_alloc,
4626 .key_free = selinux_key_free,
4627 .key_permission = selinux_key_permission,
4628#endif
4381}; 4629};
4382 4630
4383static __init int selinux_init(void) 4631static __init int selinux_init(void)
@@ -4413,6 +4661,15 @@ static __init int selinux_init(void)
4413 } else { 4661 } else {
4414 printk(KERN_INFO "SELinux: Starting in permissive mode\n"); 4662 printk(KERN_INFO "SELinux: Starting in permissive mode\n");
4415 } 4663 }
4664
4665#ifdef CONFIG_KEYS
4666 /* Add security information to initial keyrings */
4667 selinux_key_alloc(&root_user_keyring, current,
4668 KEY_ALLOC_NOT_IN_QUOTA);
4669 selinux_key_alloc(&root_session_keyring, current,
4670 KEY_ALLOC_NOT_IN_QUOTA);
4671#endif
4672
4416 return 0; 4673 return 0;
4417} 4674}
4418 4675
@@ -4422,6 +4679,7 @@ void selinux_complete_init(void)
4422 4679
4423 /* Set up any superblocks initialized prior to the policy load. */ 4680 /* Set up any superblocks initialized prior to the policy load. */
4424 printk(KERN_INFO "SELinux: Setting up existing superblocks.\n"); 4681 printk(KERN_INFO "SELinux: Setting up existing superblocks.\n");
4682 spin_lock(&sb_lock);
4425 spin_lock(&sb_security_lock); 4683 spin_lock(&sb_security_lock);
4426next_sb: 4684next_sb:
4427 if (!list_empty(&superblock_security_head)) { 4685 if (!list_empty(&superblock_security_head)) {
@@ -4430,19 +4688,20 @@ next_sb:
4430 struct superblock_security_struct, 4688 struct superblock_security_struct,
4431 list); 4689 list);
4432 struct super_block *sb = sbsec->sb; 4690 struct super_block *sb = sbsec->sb;
4433 spin_lock(&sb_lock);
4434 sb->s_count++; 4691 sb->s_count++;
4435 spin_unlock(&sb_lock);
4436 spin_unlock(&sb_security_lock); 4692 spin_unlock(&sb_security_lock);
4693 spin_unlock(&sb_lock);
4437 down_read(&sb->s_umount); 4694 down_read(&sb->s_umount);
4438 if (sb->s_root) 4695 if (sb->s_root)
4439 superblock_doinit(sb, NULL); 4696 superblock_doinit(sb, NULL);
4440 drop_super(sb); 4697 drop_super(sb);
4698 spin_lock(&sb_lock);
4441 spin_lock(&sb_security_lock); 4699 spin_lock(&sb_security_lock);
4442 list_del_init(&sbsec->list); 4700 list_del_init(&sbsec->list);
4443 goto next_sb; 4701 goto next_sb;
4444 } 4702 }
4445 spin_unlock(&sb_security_lock); 4703 spin_unlock(&sb_security_lock);
4704 spin_unlock(&sb_lock);
4446} 4705}
4447 4706
4448/* SELinux requires early initialization in order to label 4707/* SELinux requires early initialization in order to label