aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-06-28 16:29:51 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-06-28 16:29:51 -0400
commit959d921f5eb8878ea16049a7f6e9bcbb6dfbcb88 (patch)
tree83fb4d2756fab97f508b5dccaac7578ba63a76e0 /security/selinux/hooks.c
parentf112bb48994e56868870a080773c392f774fa9a2 (diff)
parent7017310ad737880d8520a7fc7e25a26b2e7e37f0 (diff)
Merge branch 'labeled-nfs' into linux-next
* labeled-nfs: NFS: Apply v4.1 capabilities to v4.2 NFS: Add in v4.2 callback operation NFS: Make callbacks minor version generic Kconfig: Add Kconfig entry for Labeled NFS V4 client NFS: Extend NFS xattr handlers to accept the security namespace NFS: Client implementation of Labeled-NFS NFS: Add label lifecycle management NFS:Add labels to client function prototypes NFSv4: Extend fattr bitmaps to support all 3 words NFSv4: Introduce new label structure NFSv4: Add label recommended attribute and NFSv4 flags NFSv4.2: Added NFS v4.2 support to the NFS client SELinux: Add new labeling type native labels LSM: Add flags field to security_sb_set_mnt_opts for in kernel mount data. Security: Add Hook to test if the particular xattr is part of a MAC model. Security: Add hook to calculate context based on a negative dentry. NFS: Add NFSv4.2 protocol constants Conflicts: fs/nfs/nfs4proc.c
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c92
1 files changed, 81 insertions, 11 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5c6f2cd2d095..9f8e9b2e717a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -81,6 +81,7 @@
81#include <linux/syslog.h> 81#include <linux/syslog.h>
82#include <linux/user_namespace.h> 82#include <linux/user_namespace.h>
83#include <linux/export.h> 83#include <linux/export.h>
84#include <linux/security.h>
84#include <linux/msg.h> 85#include <linux/msg.h>
85#include <linux/shm.h> 86#include <linux/shm.h>
86 87
@@ -284,13 +285,14 @@ static void superblock_free_security(struct super_block *sb)
284 285
285/* The file system's label must be initialized prior to use. */ 286/* The file system's label must be initialized prior to use. */
286 287
287static const char *labeling_behaviors[6] = { 288static const char *labeling_behaviors[7] = {
288 "uses xattr", 289 "uses xattr",
289 "uses transition SIDs", 290 "uses transition SIDs",
290 "uses task SIDs", 291 "uses task SIDs",
291 "uses genfs_contexts", 292 "uses genfs_contexts",
292 "not configured for labeling", 293 "not configured for labeling",
293 "uses mountpoint labeling", 294 "uses mountpoint labeling",
295 "uses native labeling",
294}; 296};
295 297
296static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); 298static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
@@ -552,7 +554,9 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
552 * labeling information. 554 * labeling information.
553 */ 555 */
554static int selinux_set_mnt_opts(struct super_block *sb, 556static int selinux_set_mnt_opts(struct super_block *sb,
555 struct security_mnt_opts *opts) 557 struct security_mnt_opts *opts,
558 unsigned long kern_flags,
559 unsigned long *set_kern_flags)
556{ 560{
557 const struct cred *cred = current_cred(); 561 const struct cred *cred = current_cred();
558 int rc = 0, i; 562 int rc = 0, i;
@@ -580,6 +584,12 @@ static int selinux_set_mnt_opts(struct super_block *sb,
580 "before the security server is initialized\n"); 584 "before the security server is initialized\n");
581 goto out; 585 goto out;
582 } 586 }
587 if (kern_flags && !set_kern_flags) {
588 /* Specifying internal flags without providing a place to
589 * place the results is not allowed */
590 rc = -EINVAL;
591 goto out;
592 }
583 593
584 /* 594 /*
585 * Binary mount data FS will come through this function twice. Once 595 * Binary mount data FS will come through this function twice. Once
@@ -670,14 +680,21 @@ static int selinux_set_mnt_opts(struct super_block *sb,
670 if (strcmp(sb->s_type->name, "proc") == 0) 680 if (strcmp(sb->s_type->name, "proc") == 0)
671 sbsec->flags |= SE_SBPROC; 681 sbsec->flags |= SE_SBPROC;
672 682
673 /* Determine the labeling behavior to use for this filesystem type. */ 683 if (!sbsec->behavior) {
674 rc = security_fs_use((sbsec->flags & SE_SBPROC) ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid); 684 /*
675 if (rc) { 685 * Determine the labeling behavior to use for this
676 printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", 686 * filesystem type.
677 __func__, sb->s_type->name, rc); 687 */
678 goto out; 688 rc = security_fs_use((sbsec->flags & SE_SBPROC) ?
689 "proc" : sb->s_type->name,
690 &sbsec->behavior, &sbsec->sid);
691 if (rc) {
692 printk(KERN_WARNING
693 "%s: security_fs_use(%s) returned %d\n",
694 __func__, sb->s_type->name, rc);
695 goto out;
696 }
679 } 697 }
680
681 /* sets the context of the superblock for the fs being mounted. */ 698 /* sets the context of the superblock for the fs being mounted. */
682 if (fscontext_sid) { 699 if (fscontext_sid) {
683 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred); 700 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
@@ -692,6 +709,11 @@ static int selinux_set_mnt_opts(struct super_block *sb,
692 * sets the label used on all file below the mountpoint, and will set 709 * sets the label used on all file below the mountpoint, and will set
693 * the superblock context if not already set. 710 * the superblock context if not already set.
694 */ 711 */
712 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
713 sbsec->behavior = SECURITY_FS_USE_NATIVE;
714 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
715 }
716
695 if (context_sid) { 717 if (context_sid) {
696 if (!fscontext_sid) { 718 if (!fscontext_sid) {
697 rc = may_context_mount_sb_relabel(context_sid, sbsec, 719 rc = may_context_mount_sb_relabel(context_sid, sbsec,
@@ -723,7 +745,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
723 } 745 }
724 746
725 if (defcontext_sid) { 747 if (defcontext_sid) {
726 if (sbsec->behavior != SECURITY_FS_USE_XATTR) { 748 if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
749 sbsec->behavior != SECURITY_FS_USE_NATIVE) {
727 rc = -EINVAL; 750 rc = -EINVAL;
728 printk(KERN_WARNING "SELinux: defcontext option is " 751 printk(KERN_WARNING "SELinux: defcontext option is "
729 "invalid for this filesystem type\n"); 752 "invalid for this filesystem type\n");
@@ -980,7 +1003,7 @@ static int superblock_doinit(struct super_block *sb, void *data)
980 goto out_err; 1003 goto out_err;
981 1004
982out: 1005out:
983 rc = selinux_set_mnt_opts(sb, &opts); 1006 rc = selinux_set_mnt_opts(sb, &opts, 0, NULL);
984 1007
985out_err: 1008out_err:
986 security_free_mnt_opts(&opts); 1009 security_free_mnt_opts(&opts);
@@ -1222,6 +1245,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1222 } 1245 }
1223 1246
1224 switch (sbsec->behavior) { 1247 switch (sbsec->behavior) {
1248 case SECURITY_FS_USE_NATIVE:
1249 break;
1225 case SECURITY_FS_USE_XATTR: 1250 case SECURITY_FS_USE_XATTR:
1226 if (!inode->i_op->getxattr) { 1251 if (!inode->i_op->getxattr) {
1227 isec->sid = sbsec->def_sid; 1252 isec->sid = sbsec->def_sid;
@@ -2515,6 +2540,40 @@ static void selinux_inode_free_security(struct inode *inode)
2515 inode_free_security(inode); 2540 inode_free_security(inode);
2516} 2541}
2517 2542
2543static int selinux_dentry_init_security(struct dentry *dentry, int mode,
2544 struct qstr *name, void **ctx,
2545 u32 *ctxlen)
2546{
2547 const struct cred *cred = current_cred();
2548 struct task_security_struct *tsec;
2549 struct inode_security_struct *dsec;
2550 struct superblock_security_struct *sbsec;
2551 struct inode *dir = dentry->d_parent->d_inode;
2552 u32 newsid;
2553 int rc;
2554
2555 tsec = cred->security;
2556 dsec = dir->i_security;
2557 sbsec = dir->i_sb->s_security;
2558
2559 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
2560 newsid = tsec->create_sid;
2561 } else {
2562 rc = security_transition_sid(tsec->sid, dsec->sid,
2563 inode_mode_to_security_class(mode),
2564 name,
2565 &newsid);
2566 if (rc) {
2567 printk(KERN_WARNING
2568 "%s: security_transition_sid failed, rc=%d\n",
2569 __func__, -rc);
2570 return rc;
2571 }
2572 }
2573
2574 return security_sid_to_context(newsid, (char **)ctx, ctxlen);
2575}
2576
2518static int selinux_inode_init_security(struct inode *inode, struct inode *dir, 2577static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2519 const struct qstr *qstr, char **name, 2578 const struct qstr *qstr, char **name,
2520 void **value, size_t *len) 2579 void **value, size_t *len)
@@ -2849,7 +2908,10 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
2849 return; 2908 return;
2850 } 2909 }
2851 2910
2911 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2852 isec->sid = newsid; 2912 isec->sid = newsid;
2913 isec->initialized = 1;
2914
2853 return; 2915 return;
2854} 2916}
2855 2917
@@ -2937,6 +2999,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
2937 if (rc) 2999 if (rc)
2938 return rc; 3000 return rc;
2939 3001
3002 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2940 isec->sid = newsid; 3003 isec->sid = newsid;
2941 isec->initialized = 1; 3004 isec->initialized = 1;
2942 return 0; 3005 return 0;
@@ -5420,6 +5483,11 @@ abort_change:
5420 return error; 5483 return error;
5421} 5484}
5422 5485
5486static int selinux_ismaclabel(const char *name)
5487{
5488 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
5489}
5490
5423static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 5491static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
5424{ 5492{
5425 return security_sid_to_context(secid, secdata, seclen); 5493 return security_sid_to_context(secid, secdata, seclen);
@@ -5562,6 +5630,7 @@ static struct security_operations selinux_ops = {
5562 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, 5630 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts,
5563 .sb_parse_opts_str = selinux_parse_opts_str, 5631 .sb_parse_opts_str = selinux_parse_opts_str,
5564 5632
5633 .dentry_init_security = selinux_dentry_init_security,
5565 5634
5566 .inode_alloc_security = selinux_inode_alloc_security, 5635 .inode_alloc_security = selinux_inode_alloc_security,
5567 .inode_free_security = selinux_inode_free_security, 5636 .inode_free_security = selinux_inode_free_security,
@@ -5657,6 +5726,7 @@ static struct security_operations selinux_ops = {
5657 .getprocattr = selinux_getprocattr, 5726 .getprocattr = selinux_getprocattr,
5658 .setprocattr = selinux_setprocattr, 5727 .setprocattr = selinux_setprocattr,
5659 5728
5729 .ismaclabel = selinux_ismaclabel,
5660 .secid_to_secctx = selinux_secid_to_secctx, 5730 .secid_to_secctx = selinux_secid_to_secctx,
5661 .secctx_to_secid = selinux_secctx_to_secid, 5731 .secctx_to_secid = selinux_secctx_to_secid,
5662 .release_secctx = selinux_release_secctx, 5732 .release_secctx = selinux_release_secctx,