Subject: [PATCH v12 6/9] LSM: Multiple concurrent LSMs

Change the infrastructure for Linux Security Modules (LSM)s
from a single vector of hook handlers to a list based method
for handling multiple concurrent modules. 

Changes for SELinux. Abstract access to security blobs.
Add the now required parameter to reset_security_ops().
Remove commoncap calls.

Signed-off-by: Casey Schaufler <ca...@schaufler-ca.com>

---
 security/selinux/hooks.c          |  410 ++++++++++++++++++-------------------
 security/selinux/include/objsec.h |    2 +
 security/selinux/include/xfrm.h   |    2 +-
 security/selinux/netlabel.c       |   13 +-
 security/selinux/selinuxfs.c      |    6 +-
 security/selinux/xfrm.c           |    9 +-
 6 files changed, 222 insertions(+), 220 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 61a5336..8ec7ea0 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -150,6 +150,7 @@ static int selinux_secmark_enabled(void)
  */
 static void cred_init_security(void)
 {
+       int rc;
        struct cred *cred = (struct cred *) current->real_cred;
        struct task_security_struct *tsec;
 
@@ -158,7 +159,9 @@ static void cred_init_security(void)
                panic("SELinux:  Failed to initialize initial task.\n");
 
        tsec->osid = tsec->sid = SECINITSID_KERNEL;
-       cred->security = tsec;
+       rc = lsm_set_init_cred(cred, tsec, &selinux_ops);
+       if (rc)
+               panic("SELinux:  Failed to initialize initial task.\n");
 }
 
 /*
@@ -168,7 +171,7 @@ static inline u32 cred_sid(const struct cred *cred)
 {
        const struct task_security_struct *tsec;
 
-       tsec = cred->security;
+       tsec = lsm_get_cred(cred, &selinux_ops);
        return tsec->sid;
 }
 
@@ -190,8 +193,9 @@ static inline u32 task_sid(const struct task_struct *task)
  */
 static inline u32 current_sid(void)
 {
-       const struct task_security_struct *tsec = current_security();
+       const struct task_security_struct *tsec;
 
+       tsec = lsm_get_cred(current_cred(), &selinux_ops);
        return tsec->sid;
 }
 
@@ -212,22 +216,23 @@ static int inode_alloc_security(struct inode *inode)
        isec->sid = SECINITSID_UNLABELED;
        isec->sclass = SECCLASS_FILE;
        isec->task_sid = sid;
-       inode->i_security = isec;
+       lsm_set_inode(inode, isec, &selinux_ops);
 
        return 0;
 }
 
 static void inode_free_security(struct inode *inode)
 {
-       struct inode_security_struct *isec = inode->i_security;
-       struct superblock_security_struct *sbsec = inode->i_sb->s_security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
+       struct superblock_security_struct *sbsec =
+                               lsm_get_super(inode->i_sb, &selinux_ops);
 
        spin_lock(&sbsec->isec_lock);
        if (!list_empty(&isec->list))
                list_del_init(&isec->list);
        spin_unlock(&sbsec->isec_lock);
 
-       inode->i_security = NULL;
+       lsm_set_inode(inode, NULL, &selinux_ops);
        kmem_cache_free(sel_inode_cache, isec);
 }
 
@@ -242,15 +247,15 @@ static int file_alloc_security(struct file *file)
 
        fsec->sid = sid;
        fsec->fown_sid = sid;
-       file->f_security = fsec;
+       lsm_set_file(file, fsec, &selinux_ops);
 
        return 0;
 }
 
 static void file_free_security(struct file *file)
 {
-       struct file_security_struct *fsec = file->f_security;
-       file->f_security = NULL;
+       struct file_security_struct *fsec = lsm_get_file(file, &selinux_ops);
+       lsm_set_file(file, NULL, &selinux_ops);
        kfree(fsec);
 }
 
@@ -269,15 +274,16 @@ static int superblock_alloc_security(struct super_block 
*sb)
        sbsec->sid = SECINITSID_UNLABELED;
        sbsec->def_sid = SECINITSID_FILE;
        sbsec->mntpoint_sid = SECINITSID_UNLABELED;
-       sb->s_security = sbsec;
+       lsm_set_super(sb, sbsec, &selinux_ops);
 
        return 0;
 }
 
 static void superblock_free_security(struct super_block *sb)
 {
-       struct superblock_security_struct *sbsec = sb->s_security;
-       sb->s_security = NULL;
+       struct superblock_security_struct *sbsec =
+                                               lsm_get_super(sb, &selinux_ops);
+       lsm_set_super(sb, NULL, &selinux_ops);
        kfree(sbsec);
 }
 
@@ -323,9 +329,10 @@ static int may_context_mount_sb_relabel(u32 sid,
                        struct superblock_security_struct *sbsec,
                        const struct cred *cred)
 {
-       const struct task_security_struct *tsec = cred->security;
+       const struct task_security_struct *tsec;
        int rc;
 
+       tsec = lsm_get_cred(cred, &selinux_ops);
        rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__RELABELFROM, NULL);
        if (rc)
@@ -340,8 +347,10 @@ static int may_context_mount_inode_relabel(u32 sid,
                        struct superblock_security_struct *sbsec,
                        const struct cred *cred)
 {
-       const struct task_security_struct *tsec = cred->security;
+       const struct task_security_struct *tsec;
        int rc;
+
+       tsec = lsm_get_cred(cred, &selinux_ops);
        rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__RELABELFROM, NULL);
        if (rc)
@@ -354,7 +363,8 @@ static int may_context_mount_inode_relabel(u32 sid,
 
 static int sb_finish_set_opts(struct super_block *sb)
 {
-       struct superblock_security_struct *sbsec = sb->s_security;
+       struct superblock_security_struct *sbsec =
+                                               lsm_get_super(sb, &selinux_ops);
        struct dentry *root = sb->s_root;
        struct inode *root_inode = root->d_inode;
        int rc = 0;
@@ -444,7 +454,8 @@ static int selinux_get_mnt_opts(const struct super_block 
*sb,
                                struct security_mnt_opts *opts)
 {
        int rc = 0, i;
-       struct superblock_security_struct *sbsec = sb->s_security;
+       struct superblock_security_struct *sbsec =
+                                               lsm_get_super(sb, &selinux_ops);
        char *context = NULL;
        u32 len;
        char tmp;
@@ -504,8 +515,9 @@ static int selinux_get_mnt_opts(const struct super_block 
*sb,
        }
        if (sbsec->flags & ROOTCONTEXT_MNT) {
                struct inode *root = sbsec->sb->s_root->d_inode;
-               struct inode_security_struct *isec = root->i_security;
+               struct inode_security_struct *isec;
 
+               isec = lsm_get_inode(root, &selinux_ops);
                rc = security_sid_to_context(isec->sid, &context, &len);
                if (rc)
                        goto out_free;
@@ -555,10 +567,12 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 {
        const struct cred *cred = current_cred();
        int rc = 0, i;
-       struct superblock_security_struct *sbsec = sb->s_security;
+       struct superblock_security_struct *sbsec =
+                                               lsm_get_super(sb, &selinux_ops);
        const char *name = sb->s_type->name;
        struct inode *inode = sbsec->sb->s_root->d_inode;
-       struct inode_security_struct *root_isec = inode->i_security;
+       struct inode_security_struct *root_isec =
+                                       lsm_get_inode(inode, &selinux_ops);
        u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
        u32 defcontext_sid = 0;
        char **mount_options = opts->mnt_opts;
@@ -753,8 +767,10 @@ out_double_mount:
 static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
                                        struct super_block *newsb)
 {
-       const struct superblock_security_struct *oldsbsec = oldsb->s_security;
-       struct superblock_security_struct *newsbsec = newsb->s_security;
+       const struct superblock_security_struct *oldsbsec =
+                                       lsm_get_super(oldsb, &selinux_ops);
+       struct superblock_security_struct *newsbsec =
+                                       lsm_get_super(newsb, &selinux_ops);
 
        int set_fscontext =     (oldsbsec->flags & FSCONTEXT_MNT);
        int set_context =       (oldsbsec->flags & CONTEXT_MNT);
@@ -789,16 +805,19 @@ static void selinux_sb_clone_mnt_opts(const struct 
super_block *oldsb,
                        newsbsec->sid = sid;
                if (!set_rootcontext) {
                        struct inode *newinode = newsb->s_root->d_inode;
-                       struct inode_security_struct *newisec = 
newinode->i_security;
+                       struct inode_security_struct *newisec =
+                                       lsm_get_inode(newinode, &selinux_ops);
                        newisec->sid = sid;
                }
                newsbsec->mntpoint_sid = sid;
        }
        if (set_rootcontext) {
                const struct inode *oldinode = oldsb->s_root->d_inode;
-               const struct inode_security_struct *oldisec = 
oldinode->i_security;
+               const struct inode_security_struct *oldisec =
+                                       lsm_get_inode(oldinode, &selinux_ops);
                struct inode *newinode = newsb->s_root->d_inode;
-               struct inode_security_struct *newisec = newinode->i_security;
+               struct inode_security_struct *newisec =
+                                       lsm_get_inode(newinode, &selinux_ops);
 
                newisec->sid = oldisec->sid;
        }
@@ -1162,7 +1181,7 @@ static int selinux_proc_get_sid(struct dentry *dentry,
 static int inode_doinit_with_dentry(struct inode *inode, struct dentry 
*opt_dentry)
 {
        struct superblock_security_struct *sbsec = NULL;
-       struct inode_security_struct *isec = inode->i_security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
        u32 sid;
        struct dentry *dentry;
 #define INITCONTEXTLEN 255
@@ -1177,7 +1196,7 @@ static int inode_doinit_with_dentry(struct inode *inode, 
struct dentry *opt_dent
        if (isec->initialized)
                goto out_unlock;
 
-       sbsec = inode->i_sb->s_security;
+       sbsec = lsm_get_super(inode->i_sb, &selinux_ops);
        if (!(sbsec->flags & SE_SBINITIALIZED)) {
                /* Defer initialization until selinux_complete_init,
                   after the initial policy is loaded and the security
@@ -1389,8 +1408,10 @@ static int task_has_perm(const struct task_struct *tsk1,
        u32 sid1, sid2;
 
        rcu_read_lock();
-       __tsec1 = __task_cred(tsk1)->security;  sid1 = __tsec1->sid;
-       __tsec2 = __task_cred(tsk2)->security;  sid2 = __tsec2->sid;
+       __tsec1 = lsm_get_cred(__task_cred(tsk1), &selinux_ops);
+       sid1 = __tsec1->sid;
+       __tsec2 = lsm_get_cred(__task_cred(tsk2), &selinux_ops);
+       sid2 = __tsec2->sid;
        rcu_read_unlock();
        return avc_has_perm(sid1, sid2, SECCLASS_PROCESS, perms, NULL);
 }
@@ -1480,7 +1501,7 @@ static int inode_has_perm(const struct cred *cred,
                return 0;
 
        sid = cred_sid(cred);
-       isec = inode->i_security;
+       isec = lsm_get_inode(inode, &selinux_ops);
 
        return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, 
flags);
 }
@@ -1527,7 +1548,7 @@ static int file_has_perm(const struct cred *cred,
                         struct file *file,
                         u32 av)
 {
-       struct file_security_struct *fsec = file->f_security;
+       struct file_security_struct *fsec = lsm_get_file(file, &selinux_ops);
        struct inode *inode = file->f_path.dentry->d_inode;
        struct common_audit_data ad;
        u32 sid = cred_sid(cred);
@@ -1559,15 +1580,16 @@ static int may_create(struct inode *dir,
                      struct dentry *dentry,
                      u16 tclass)
 {
-       const struct task_security_struct *tsec = current_security();
+       const struct task_security_struct *tsec =
+                               lsm_get_cred(current_cred(), &selinux_ops);
        struct inode_security_struct *dsec;
        struct superblock_security_struct *sbsec;
        u32 sid, newsid;
        struct common_audit_data ad;
        int rc;
 
-       dsec = dir->i_security;
-       sbsec = dir->i_sb->s_security;
+       dsec = lsm_get_inode(dir, &selinux_ops);
+       sbsec = lsm_get_super(dir->i_sb, &selinux_ops);
 
        sid = tsec->sid;
        newsid = tsec->create_sid;
@@ -1622,8 +1644,8 @@ static int may_link(struct inode *dir,
        u32 av;
        int rc;
 
-       dsec = dir->i_security;
-       isec = dentry->d_inode->i_security;
+       dsec = lsm_get_inode(dir, &selinux_ops);
+       isec = lsm_get_inode(dentry->d_inode, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry;
@@ -1666,10 +1688,10 @@ static inline int may_rename(struct inode *old_dir,
        int old_is_dir, new_is_dir;
        int rc;
 
-       old_dsec = old_dir->i_security;
-       old_isec = old_dentry->d_inode->i_security;
+       old_dsec = lsm_get_inode(old_dir, &selinux_ops);
+       old_isec = lsm_get_inode(old_dentry->d_inode, &selinux_ops);
        old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
-       new_dsec = new_dir->i_security;
+       new_dsec = lsm_get_inode(new_dir, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_DENTRY;
 
@@ -1697,7 +1719,7 @@ static inline int may_rename(struct inode *old_dir,
        if (rc)
                return rc;
        if (new_dentry->d_inode) {
-               new_isec = new_dentry->d_inode->i_security;
+               new_isec = lsm_get_inode(new_dentry->d_inode, &selinux_ops);
                new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode);
                rc = avc_has_perm(sid, new_isec->sid,
                                  new_isec->sclass,
@@ -1718,7 +1740,7 @@ static int superblock_has_perm(const struct cred *cred,
        struct superblock_security_struct *sbsec;
        u32 sid = cred_sid(cred);
 
-       sbsec = sb->s_security;
+       sbsec = lsm_get_super(sb, &selinux_ops);
        return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
 }
 
@@ -1792,12 +1814,6 @@ static inline u32 open_file_to_av(struct file *file)
 static int selinux_ptrace_access_check(struct task_struct *child,
                                     unsigned int mode)
 {
-       int rc;
-
-       rc = cap_ptrace_access_check(child, mode);
-       if (rc)
-               return rc;
-
        if (mode & PTRACE_MODE_READ) {
                u32 sid = current_sid();
                u32 csid = task_sid(child);
@@ -1809,12 +1825,6 @@ static int selinux_ptrace_access_check(struct 
task_struct *child,
 
 static int selinux_ptrace_traceme(struct task_struct *parent)
 {
-       int rc;
-
-       rc = cap_ptrace_traceme(parent);
-       if (rc)
-               return rc;
-
        return task_has_perm(parent, current, PROCESS__PTRACE);
 }
 
@@ -1835,13 +1845,6 @@ static int selinux_capset(struct cred *new, const struct 
cred *old,
                          const kernel_cap_t *inheritable,
                          const kernel_cap_t *permitted)
 {
-       int error;
-
-       error = cap_capset(new, old,
-                                     effective, inheritable, permitted);
-       if (error)
-               return error;
-
        return cred_has_perm(old, new, PROCESS__SETCAP);
 }
 
@@ -1858,12 +1861,6 @@ static int selinux_capset(struct cred *new, const struct 
cred *old,
 static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
                           int cap, int audit)
 {
-       int rc;
-
-       rc = cap_capable(cred, ns, cap, audit);
-       if (rc)
-               return rc;
-
        return cred_has_capability(cred, cap, audit);
 }
 
@@ -1960,18 +1957,14 @@ static int selinux_bprm_set_creds(struct linux_binprm 
*bprm)
        struct inode *inode = bprm->file->f_path.dentry->d_inode;
        int rc;
 
-       rc = cap_bprm_set_creds(bprm);
-       if (rc)
-               return rc;
-
        /* SELinux context only depends on initial program or script and not
         * the script interpreter */
        if (bprm->cred_prepared)
                return 0;
 
-       old_tsec = current_security();
-       new_tsec = bprm->cred->security;
-       isec = inode->i_security;
+       old_tsec = lsm_get_cred(current_cred(), &selinux_ops);
+       new_tsec = lsm_get_cred(bprm->cred, &selinux_ops);
+       isec = lsm_get_inode(inode, &selinux_ops);
 
        /* Default to the current task SID. */
        new_tsec->sid = old_tsec->sid;
@@ -2046,7 +2039,8 @@ static int selinux_bprm_set_creds(struct linux_binprm 
*bprm)
                        rcu_read_lock();
                        tracer = ptrace_parent(current);
                        if (likely(tracer != NULL)) {
-                               sec = __task_cred(tracer)->security;
+                               sec = lsm_get_cred(__task_cred(tracer),
+                                                  &selinux_ops);
                                ptsid = sec->sid;
                        }
                        rcu_read_unlock();
@@ -2069,7 +2063,8 @@ static int selinux_bprm_set_creds(struct linux_binprm 
*bprm)
 
 static int selinux_bprm_secureexec(struct linux_binprm *bprm)
 {
-       const struct task_security_struct *tsec = current_security();
+       const struct task_security_struct *tsec =
+                               lsm_get_cred(current_cred(), &selinux_ops);
        u32 sid, osid;
        int atsecure = 0;
 
@@ -2085,7 +2080,7 @@ static int selinux_bprm_secureexec(struct linux_binprm 
*bprm)
                                        PROCESS__NOATSECURE, NULL);
        }
 
-       return (atsecure || cap_bprm_secureexec(bprm));
+       return atsecure;
 }
 
 static int match_file(const void *p, struct file *file, unsigned fd)
@@ -2151,7 +2146,7 @@ static void selinux_bprm_committing_creds(struct 
linux_binprm *bprm)
        struct rlimit *rlim, *initrlim;
        int rc, i;
 
-       new_tsec = bprm->cred->security;
+       new_tsec = lsm_get_cred(bprm->cred, &selinux_ops);
        if (new_tsec->sid == new_tsec->osid)
                return;
 
@@ -2192,7 +2187,8 @@ static void selinux_bprm_committing_creds(struct 
linux_binprm *bprm)
  */
 static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
 {
-       const struct task_security_struct *tsec = current_security();
+       const struct task_security_struct *tsec =
+                               lsm_get_cred(current_cred(), &selinux_ops);
        struct itimerval itimer;
        u32 osid, sid;
        int rc, i;
@@ -2339,7 +2335,8 @@ static int selinux_sb_remount(struct super_block *sb, 
void *data)
        int rc, i, *flags;
        struct security_mnt_opts opts;
        char *secdata, **mount_options;
-       struct superblock_security_struct *sbsec = sb->s_security;
+       struct superblock_security_struct *sbsec =
+                                               lsm_get_super(sb, &selinux_ops);
 
        if (!(sbsec->flags & SE_SBINITIALIZED))
                return 0;
@@ -2391,7 +2388,8 @@ static int selinux_sb_remount(struct super_block *sb, 
void *data)
                        break;
                case ROOTCONTEXT_MNT: {
                        struct inode_security_struct *root_isec;
-                       root_isec = sb->s_root->d_inode->i_security;
+                       root_isec = lsm_get_inode(sb->s_root->d_inode,
+                                                               &selinux_ops);
 
                        if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, 
sid))
                                goto out_bad_option;
@@ -2487,15 +2485,16 @@ static int selinux_inode_init_security(struct inode 
*inode, struct inode *dir,
                                       const struct qstr *qstr, char **name,
                                       void **value, size_t *len)
 {
-       const struct task_security_struct *tsec = current_security();
+       const struct task_security_struct *tsec =
+                               lsm_get_cred(current_cred(), &selinux_ops);
        struct inode_security_struct *dsec;
        struct superblock_security_struct *sbsec;
        u32 sid, newsid, clen;
        int rc;
        char *namep = NULL, *context;
 
-       dsec = dir->i_security;
-       sbsec = dir->i_sb->s_security;
+       dsec = lsm_get_inode(dir, &selinux_ops);
+       sbsec = lsm_get_super(dir->i_sb, &selinux_ops);
 
        sid = tsec->sid;
        newsid = tsec->create_sid;
@@ -2519,7 +2518,8 @@ static int selinux_inode_init_security(struct inode 
*inode, struct inode *dir,
 
        /* Possibly defer initialization to selinux_complete_init. */
        if (sbsec->flags & SE_SBINITIALIZED) {
-               struct inode_security_struct *isec = inode->i_security;
+               struct inode_security_struct *isec =
+                                       lsm_get_inode(inode, &selinux_ops);
                isec->sclass = inode_mode_to_security_class(inode->i_mode);
                isec->sid = newsid;
                isec->initialized = 1;
@@ -2608,7 +2608,7 @@ static noinline int audit_inode_permission(struct inode 
*inode,
                                           unsigned flags)
 {
        struct common_audit_data ad;
-       struct inode_security_struct *isec = inode->i_security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
        int rc;
 
        ad.type = LSM_AUDIT_DATA_INODE;
@@ -2648,7 +2648,7 @@ static int selinux_inode_permission(struct inode *inode, 
int mask)
        perms = file_mask_to_av(inode->i_mode, mask);
 
        sid = cred_sid(cred);
-       isec = inode->i_security;
+       isec = lsm_get_inode(inode, &selinux_ops);
 
        rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd);
        audited = avc_audit_required(perms, &avd, rc,
@@ -2723,7 +2723,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, 
const char *name,
                                  const void *value, size_t size, int flags)
 {
        struct inode *inode = dentry->d_inode;
-       struct inode_security_struct *isec = inode->i_security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
        struct superblock_security_struct *sbsec;
        struct common_audit_data ad;
        u32 newsid, sid = current_sid();
@@ -2732,7 +2732,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, 
const char *name,
        if (strcmp(name, XATTR_NAME_SELINUX))
                return selinux_inode_setotherxattr(dentry, name);
 
-       sbsec = inode->i_sb->s_security;
+       sbsec = lsm_get_super(inode->i_sb, &selinux_ops);
        if (!(sbsec->flags & SE_SBLABELSUPP))
                return -EOPNOTSUPP;
 
@@ -2800,7 +2800,7 @@ static void selinux_inode_post_setxattr(struct dentry 
*dentry, const char *name,
                                        int flags)
 {
        struct inode *inode = dentry->d_inode;
-       struct inode_security_struct *isec = inode->i_security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
        u32 newsid;
        int rc;
 
@@ -2855,7 +2855,7 @@ static int selinux_inode_getsecurity(const struct inode 
*inode, const char *name
        u32 size;
        int error;
        char *context = NULL;
-       struct inode_security_struct *isec = inode->i_security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
 
        if (strcmp(name, XATTR_SELINUX_SUFFIX))
                return -EOPNOTSUPP;
@@ -2891,7 +2891,7 @@ out_nofree:
 static int selinux_inode_setsecurity(struct inode *inode, const char *name,
                                     const void *value, size_t size, int flags)
 {
-       struct inode_security_struct *isec = inode->i_security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
        u32 newsid;
        int rc;
 
@@ -2920,7 +2920,7 @@ static int selinux_inode_listsecurity(struct inode 
*inode, char *buffer, size_t
 
 static void selinux_inode_getsecid(const struct inode *inode, u32 *secid)
 {
-       struct inode_security_struct *isec = inode->i_security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
        *secid = isec->sid;
 }
 
@@ -2942,8 +2942,8 @@ static int selinux_revalidate_file_permission(struct file 
*file, int mask)
 static int selinux_file_permission(struct file *file, int mask)
 {
        struct inode *inode = file->f_path.dentry->d_inode;
-       struct file_security_struct *fsec = file->f_security;
-       struct inode_security_struct *isec = inode->i_security;
+       struct file_security_struct *fsec = lsm_get_file(file, &selinux_ops);
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
        u32 sid = current_sid();
 
        if (!mask)
@@ -3177,7 +3177,7 @@ static int selinux_file_set_fowner(struct file *file)
 {
        struct file_security_struct *fsec;
 
-       fsec = file->f_security;
+       fsec = lsm_get_file(file, &selinux_ops);
        fsec->fown_sid = current_sid();
 
        return 0;
@@ -3194,7 +3194,7 @@ static int selinux_file_send_sigiotask(struct task_struct 
*tsk,
        /* struct fown_struct is never outside the context of a struct file */
        file = container_of(fown, struct file, f_owner);
 
-       fsec = file->f_security;
+       fsec = lsm_get_file(file, &selinux_ops);
 
        if (!signum)
                perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
@@ -3217,8 +3217,8 @@ static int selinux_file_open(struct file *file, const 
struct cred *cred)
        struct file_security_struct *fsec;
        struct inode_security_struct *isec;
 
-       fsec = file->f_security;
-       isec = file->f_path.dentry->d_inode->i_security;
+       fsec = lsm_get_file(file, &selinux_ops);
+       isec = lsm_get_inode(file->f_path.dentry->d_inode, &selinux_ops);
        /*
         * Save inode label and policy sequence number
         * at open-time so that selinux_file_permission
@@ -3257,7 +3257,7 @@ static int selinux_cred_alloc_blank(struct cred *cred, 
gfp_t gfp)
        if (!tsec)
                return -ENOMEM;
 
-       cred->security = tsec;
+       lsm_set_cred(cred, tsec, &selinux_ops);
        return 0;
 }
 
@@ -3266,14 +3266,14 @@ static int selinux_cred_alloc_blank(struct cred *cred, 
gfp_t gfp)
  */
 static void selinux_cred_free(struct cred *cred)
 {
-       struct task_security_struct *tsec = cred->security;
+       struct task_security_struct *tsec = lsm_get_cred(cred, &selinux_ops);
 
        /*
         * cred->security == NULL if security_cred_alloc_blank() or
         * security_prepare_creds() returned an error.
         */
-       BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE);
-       cred->security = (void *) 0x7UL;
+       BUG_ON(tsec && (unsigned long) tsec < PAGE_SIZE);
+       lsm_set_cred(cred, NULL, &selinux_ops);
        kfree(tsec);
 }
 
@@ -3286,13 +3286,13 @@ static int selinux_cred_prepare(struct cred *new, const 
struct cred *old,
        const struct task_security_struct *old_tsec;
        struct task_security_struct *tsec;
 
-       old_tsec = old->security;
+       old_tsec = lsm_get_cred(old, &selinux_ops);
 
        tsec = kmemdup(old_tsec, sizeof(struct task_security_struct), gfp);
        if (!tsec)
                return -ENOMEM;
 
-       new->security = tsec;
+       lsm_set_cred(new, tsec, &selinux_ops);
        return 0;
 }
 
@@ -3301,9 +3301,15 @@ static int selinux_cred_prepare(struct cred *new, const 
struct cred *old,
  */
 static void selinux_cred_transfer(struct cred *new, const struct cred *old)
 {
-       const struct task_security_struct *old_tsec = old->security;
-       struct task_security_struct *tsec = new->security;
+       const struct task_security_struct *old_tsec;
+       struct task_security_struct *tsec;
 
+       old_tsec = lsm_get_cred(old, &selinux_ops);
+       tsec = lsm_get_cred(new, &selinux_ops);
+
+       /*
+        * This is a data copy, not a pointer assignment.
+        */
        *tsec = *old_tsec;
 }
 
@@ -3313,7 +3319,7 @@ static void selinux_cred_transfer(struct cred *new, const 
struct cred *old)
  */
 static int selinux_kernel_act_as(struct cred *new, u32 secid)
 {
-       struct task_security_struct *tsec = new->security;
+       struct task_security_struct *tsec = lsm_get_cred(new, &selinux_ops);
        u32 sid = current_sid();
        int ret;
 
@@ -3336,8 +3342,8 @@ static int selinux_kernel_act_as(struct cred *new, u32 
secid)
  */
 static int selinux_kernel_create_files_as(struct cred *new, struct inode 
*inode)
 {
-       struct inode_security_struct *isec = inode->i_security;
-       struct task_security_struct *tsec = new->security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
+       struct task_security_struct *tsec = lsm_get_cred(new, &selinux_ops);
        u32 sid = current_sid();
        int ret;
 
@@ -3387,23 +3393,11 @@ static void selinux_task_getsecid(struct task_struct 
*p, u32 *secid)
 
 static int selinux_task_setnice(struct task_struct *p, int nice)
 {
-       int rc;
-
-       rc = cap_task_setnice(p, nice);
-       if (rc)
-               return rc;
-
        return current_has_perm(p, PROCESS__SETSCHED);
 }
 
 static int selinux_task_setioprio(struct task_struct *p, int ioprio)
 {
-       int rc;
-
-       rc = cap_task_setioprio(p, ioprio);
-       if (rc)
-               return rc;
-
        return current_has_perm(p, PROCESS__SETSCHED);
 }
 
@@ -3429,12 +3423,6 @@ static int selinux_task_setrlimit(struct task_struct *p, 
unsigned int resource,
 
 static int selinux_task_setscheduler(struct task_struct *p)
 {
-       int rc;
-
-       rc = cap_task_setscheduler(p);
-       if (rc)
-               return rc;
-
        return current_has_perm(p, PROCESS__SETSCHED);
 }
 
@@ -3474,7 +3462,7 @@ static int selinux_task_wait(struct task_struct *p)
 static void selinux_task_to_inode(struct task_struct *p,
                                  struct inode *inode)
 {
-       struct inode_security_struct *isec = inode->i_security;
+       struct inode_security_struct *isec = lsm_get_inode(inode, &selinux_ops);
        u32 sid = task_sid(p);
 
        isec->sid = sid;
@@ -3729,7 +3717,7 @@ static int socket_sockcreate_sid(const struct 
task_security_struct *tsec,
 
 static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
 {
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
        u32 tsid = task_sid(task);
@@ -3747,7 +3735,8 @@ static int sock_has_perm(struct task_struct *task, struct 
sock *sk, u32 perms)
 static int selinux_socket_create(int family, int type,
                                 int protocol, int kern)
 {
-       const struct task_security_struct *tsec = current_security();
+       const struct task_security_struct *tsec =
+                               lsm_get_cred(current_cred(), &selinux_ops);
        u32 newsid;
        u16 secclass;
        int rc;
@@ -3766,8 +3755,10 @@ static int selinux_socket_create(int family, int type,
 static int selinux_socket_post_create(struct socket *sock, int family,
                                      int type, int protocol, int kern)
 {
-       const struct task_security_struct *tsec = current_security();
-       struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
+       const struct task_security_struct *tsec =
+                               lsm_get_cred(current_cred(), &selinux_ops);
+       struct inode_security_struct *isec =
+                               lsm_get_inode(SOCK_INODE(sock), &selinux_ops);
        struct sk_security_struct *sksec;
        int err = 0;
 
@@ -3784,7 +3775,7 @@ static int selinux_socket_post_create(struct socket 
*sock, int family,
        isec->initialized = 1;
 
        if (sock->sk) {
-               sksec = sock->sk->sk_security;
+               sksec = lsm_get_sock(sock->sk, &selinux_ops);
                sksec->sid = isec->sid;
                sksec->sclass = isec->sclass;
                err = selinux_netlbl_socket_post_create(sock->sk, family);
@@ -3815,7 +3806,8 @@ static int selinux_socket_bind(struct socket *sock, 
struct sockaddr *address, in
        family = sk->sk_family;
        if (family == PF_INET || family == PF_INET6) {
                char *addrp;
-               struct sk_security_struct *sksec = sk->sk_security;
+               struct sk_security_struct *sksec =
+                                       lsm_get_sock(sk, &selinux_ops);
                struct common_audit_data ad;
                struct lsm_network_audit net = {0,};
                struct sockaddr_in *addr4 = NULL;
@@ -3899,7 +3891,7 @@ out:
 static int selinux_socket_connect(struct socket *sock, struct sockaddr 
*address, int addrlen)
 {
        struct sock *sk = sock->sk;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        int err;
 
        err = sock_has_perm(current, sk, SOCKET__CONNECT);
@@ -3967,9 +3959,9 @@ static int selinux_socket_accept(struct socket *sock, 
struct socket *newsock)
        if (err)
                return err;
 
-       newisec = SOCK_INODE(newsock)->i_security;
+       newisec = lsm_get_inode(SOCK_INODE(newsock), &selinux_ops);
 
-       isec = SOCK_INODE(sock)->i_security;
+       isec = lsm_get_inode(SOCK_INODE(sock), &selinux_ops);
        newisec->sclass = isec->sclass;
        newisec->sid = isec->sid;
        newisec->initialized = 1;
@@ -4025,9 +4017,12 @@ static int selinux_socket_unix_stream_connect(struct 
sock *sock,
                                              struct sock *other,
                                              struct sock *newsk)
 {
-       struct sk_security_struct *sksec_sock = sock->sk_security;
-       struct sk_security_struct *sksec_other = other->sk_security;
-       struct sk_security_struct *sksec_new = newsk->sk_security;
+       struct sk_security_struct *sksec_sock =
+                                       lsm_get_sock(sock, &selinux_ops);
+       struct sk_security_struct *sksec_other =
+                                       lsm_get_sock(other, &selinux_ops);
+       struct sk_security_struct *sksec_new =
+                                       lsm_get_sock(newsk, &selinux_ops);
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
        int err;
@@ -4058,8 +4053,8 @@ static int selinux_socket_unix_stream_connect(struct sock 
*sock,
 static int selinux_socket_unix_may_send(struct socket *sock,
                                        struct socket *other)
 {
-       struct sk_security_struct *ssec = sock->sk->sk_security;
-       struct sk_security_struct *osec = other->sk->sk_security;
+       struct sk_security_struct *ssec = lsm_get_sock(sock->sk, &selinux_ops);
+       struct sk_security_struct *osec = lsm_get_sock(other->sk, &selinux_ops);
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
 
@@ -4098,7 +4093,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, 
struct sk_buff *skb,
                                       u16 family)
 {
        int err = 0;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        u32 sk_sid = sksec->sid;
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
@@ -4130,7 +4125,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, 
struct sk_buff *skb,
 static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        int err;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        u16 family = sk->sk_family;
        u32 sk_sid = sksec->sid;
        struct common_audit_data ad;
@@ -4200,7 +4195,7 @@ static int selinux_socket_getpeersec_stream(struct socket 
*sock, char __user *op
        int err = 0;
        char *scontext;
        u32 scontext_len;
-       struct sk_security_struct *sksec = sock->sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sock->sk, &selinux_ops);
        u32 peer_sid = SECSID_NULL;
 
        if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
@@ -4265,24 +4260,24 @@ static int selinux_sk_alloc_security(struct sock *sk, 
int family, gfp_t priority
        sksec->peer_sid = SECINITSID_UNLABELED;
        sksec->sid = SECINITSID_UNLABELED;
        selinux_netlbl_sk_security_reset(sksec);
-       sk->sk_security = sksec;
+       lsm_set_sock(sk, sksec, &selinux_ops);
 
        return 0;
 }
 
 static void selinux_sk_free_security(struct sock *sk)
 {
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
 
-       sk->sk_security = NULL;
+       lsm_set_sock(sk, NULL, &selinux_ops);
        selinux_netlbl_sk_security_free(sksec);
        kfree(sksec);
 }
 
 static void selinux_sk_clone_security(const struct sock *sk, struct sock 
*newsk)
 {
-       struct sk_security_struct *sksec = sk->sk_security;
-       struct sk_security_struct *newsksec = newsk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
+       struct sk_security_struct *newsksec = lsm_get_sock(newsk, &selinux_ops);
 
        newsksec->sid = sksec->sid;
        newsksec->peer_sid = sksec->peer_sid;
@@ -4296,7 +4291,8 @@ static void selinux_sk_getsecid(struct sock *sk, u32 
*secid)
        if (!sk)
                *secid = SECINITSID_ANY_SOCKET;
        else {
-               struct sk_security_struct *sksec = sk->sk_security;
+               struct sk_security_struct *sksec =
+                                       lsm_get_sock(sk, &selinux_ops);
 
                *secid = sksec->sid;
        }
@@ -4304,8 +4300,9 @@ static void selinux_sk_getsecid(struct sock *sk, u32 
*secid)
 
 static void selinux_sock_graft(struct sock *sk, struct socket *parent)
 {
-       struct inode_security_struct *isec = SOCK_INODE(parent)->i_security;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct inode_security_struct *isec =
+                       lsm_get_inode(SOCK_INODE(parent), &selinux_ops);
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
 
        if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
            sk->sk_family == PF_UNIX)
@@ -4316,7 +4313,7 @@ static void selinux_sock_graft(struct sock *sk, struct 
socket *parent)
 static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
                                     struct request_sock *req)
 {
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        int err;
        u16 family = sk->sk_family;
        u32 newsid;
@@ -4346,7 +4343,7 @@ static int selinux_inet_conn_request(struct sock *sk, 
struct sk_buff *skb,
 static void selinux_inet_csk_clone(struct sock *newsk,
                                   const struct request_sock *req)
 {
-       struct sk_security_struct *newsksec = newsk->sk_security;
+       struct sk_security_struct *newsksec = lsm_get_sock(newsk, &selinux_ops);
 
        newsksec->sid = req->secid;
        newsksec->peer_sid = req->peer_secid;
@@ -4363,7 +4360,7 @@ static void selinux_inet_csk_clone(struct sock *newsk,
 static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
 {
        u16 family = sk->sk_family;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
 
        /* handle mapped IPv4 packets arriving via IPv6 sockets */
        if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
@@ -4377,7 +4374,7 @@ static int selinux_secmark_relabel_packet(u32 sid)
        const struct task_security_struct *__tsec;
        u32 tsid;
 
-       __tsec = current_security();
+       __tsec = lsm_get_cred(current_cred(), &selinux_ops);
        tsid = __tsec->sid;
 
        return avc_has_perm(tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO, 
NULL);
@@ -4416,7 +4413,7 @@ static int selinux_tun_dev_create(void)
 
 static void selinux_tun_dev_post_create(struct sock *sk)
 {
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
 
        /* we don't currently perform any NetLabel based labeling here and it
         * isn't clear that we would want to do so anyway; while we could apply
@@ -4434,7 +4431,7 @@ static void selinux_tun_dev_post_create(struct sock *sk)
 
 static int selinux_tun_dev_attach(struct sock *sk)
 {
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        u32 sid = current_sid();
        int err;
 
@@ -4457,7 +4454,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct 
sk_buff *skb)
        int err = 0;
        u32 perm;
        struct nlmsghdr *nlh;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
 
        if (skb->len < NLMSG_SPACE(0)) {
                err = -EINVAL;
@@ -4577,7 +4574,8 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
         * because we want to make sure we apply the necessary labeling
         * before IPsec is applied so we can leverage AH protection */
        if (skb->sk) {
-               struct sk_security_struct *sksec = skb->sk->sk_security;
+               struct sk_security_struct *sksec =
+                                       lsm_get_sock(skb->sk, &selinux_ops);
                sid = sksec->sid;
        } else
                sid = SECINITSID_KERNEL;
@@ -4609,7 +4607,7 @@ static unsigned int selinux_ip_postroute_compat(struct 
sk_buff *skb,
 
        if (sk == NULL)
                return NF_ACCEPT;
-       sksec = sk->sk_security;
+       sksec = lsm_get_sock(sk, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
@@ -4677,7 +4675,8 @@ static unsigned int selinux_ip_postroute(struct sk_buff 
*skb, int ifindex,
                        peer_sid = SECINITSID_KERNEL;
                }
        } else {
-               struct sk_security_struct *sksec = sk->sk_security;
+               struct sk_security_struct *sksec =
+                                       lsm_get_sock(sk, &selinux_ops);
                peer_sid = sksec->sid;
                secmark_perm = PACKET__SEND;
        }
@@ -4738,12 +4737,6 @@ static unsigned int selinux_ipv6_postroute(unsigned int 
hooknum,
 
 static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
-       int err;
-
-       err = cap_netlink_send(sk, skb);
-       if (err)
-               return err;
-
        return selinux_nlmsg_perm(sk, skb);
 }
 
@@ -4761,15 +4754,15 @@ static int ipc_alloc_security(struct task_struct *task,
        sid = task_sid(task);
        isec->sclass = sclass;
        isec->sid = sid;
-       perm->security = isec;
+       lsm_set_ipc(perm, isec, &selinux_ops);
 
        return 0;
 }
 
 static void ipc_free_security(struct kern_ipc_perm *perm)
 {
-       struct ipc_security_struct *isec = perm->security;
-       perm->security = NULL;
+       struct ipc_security_struct *isec = lsm_get_ipc(perm, &selinux_ops);
+       lsm_set_ipc(perm, NULL, &selinux_ops);
        kfree(isec);
 }
 
@@ -4782,16 +4775,16 @@ static int msg_msg_alloc_security(struct msg_msg *msg)
                return -ENOMEM;
 
        msec->sid = SECINITSID_UNLABELED;
-       msg->security = msec;
+       lsm_set_msg(msg, msec, &selinux_ops);
 
        return 0;
 }
 
 static void msg_msg_free_security(struct msg_msg *msg)
 {
-       struct msg_security_struct *msec = msg->security;
+       struct msg_security_struct *msec = lsm_get_msg(msg, &selinux_ops);
 
-       msg->security = NULL;
+       lsm_set_msg(msg, NULL, &selinux_ops);
        kfree(msec);
 }
 
@@ -4802,7 +4795,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
        struct common_audit_data ad;
        u32 sid = current_sid();
 
-       isec = ipc_perms->security;
+       isec = lsm_get_ipc(ipc_perms, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = ipc_perms->key;
@@ -4832,7 +4825,7 @@ static int selinux_msg_queue_alloc_security(struct 
msg_queue *msq)
        if (rc)
                return rc;
 
-       isec = msq->q_perm.security;
+       isec = lsm_get_ipc(&msq->q_perm, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
@@ -4857,7 +4850,7 @@ static int selinux_msg_queue_associate(struct msg_queue 
*msq, int msqflg)
        struct common_audit_data ad;
        u32 sid = current_sid();
 
-       isec = msq->q_perm.security;
+       isec = lsm_get_ipc(&msq->q_perm, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
@@ -4902,8 +4895,8 @@ static int selinux_msg_queue_msgsnd(struct msg_queue 
*msq, struct msg_msg *msg,
        u32 sid = current_sid();
        int rc;
 
-       isec = msq->q_perm.security;
-       msec = msg->security;
+       isec = lsm_get_ipc(&msq->q_perm, &selinux_ops);
+       msec = lsm_get_msg(msg, &selinux_ops);
 
        /*
         * First time through, need to assign label to the message
@@ -4947,8 +4940,8 @@ static int selinux_msg_queue_msgrcv(struct msg_queue 
*msq, struct msg_msg *msg,
        u32 sid = task_sid(target);
        int rc;
 
-       isec = msq->q_perm.security;
-       msec = msg->security;
+       isec = lsm_get_ipc(&msq->q_perm, &selinux_ops);
+       msec = lsm_get_msg(msg, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
@@ -4973,7 +4966,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel 
*shp)
        if (rc)
                return rc;
 
-       isec = shp->shm_perm.security;
+       isec = lsm_get_ipc(&shp->shm_perm, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = shp->shm_perm.key;
@@ -4998,7 +4991,7 @@ static int selinux_shm_associate(struct shmid_kernel 
*shp, int shmflg)
        struct common_audit_data ad;
        u32 sid = current_sid();
 
-       isec = shp->shm_perm.security;
+       isec = lsm_get_ipc(&shp->shm_perm, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = shp->shm_perm.key;
@@ -5065,7 +5058,7 @@ static int selinux_sem_alloc_security(struct sem_array 
*sma)
        if (rc)
                return rc;
 
-       isec = sma->sem_perm.security;
+       isec = lsm_get_ipc(&sma->sem_perm, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = sma->sem_perm.key;
@@ -5090,7 +5083,7 @@ static int selinux_sem_associate(struct sem_array *sma, 
int semflg)
        struct common_audit_data ad;
        u32 sid = current_sid();
 
-       isec = sma->sem_perm.security;
+       isec = lsm_get_ipc(&sma->sem_perm, &selinux_ops);
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = sma->sem_perm.key;
@@ -5172,7 +5165,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm 
*ipcp, short flag)
 
 static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
 {
-       struct ipc_security_struct *isec = ipcp->security;
+       struct ipc_security_struct *isec = lsm_get_ipc(ipcp, &selinux_ops);
        *secid = isec->sid;
 }
 
@@ -5197,7 +5190,7 @@ static int selinux_getprocattr(struct task_struct *p,
        }
 
        rcu_read_lock();
-       __tsec = __task_cred(p)->security;
+       __tsec = lsm_get_cred(__task_cred(p), &selinux_ops);
 
        if (!strcmp(name, "current"))
                sid = __tsec->sid;
@@ -5306,7 +5299,7 @@ static int selinux_setprocattr(struct task_struct *p,
           operation.  See selinux_bprm_set_creds for the execve
           checks and may_create for the file creation checks. The
           operation will then fail if the context is not permitted. */
-       tsec = new->security;
+       tsec = lsm_get_cred(new, &selinux_ops);
        if (!strcmp(name, "exec")) {
                tsec->exec_sid = sid;
        } else if (!strcmp(name, "fscreate")) {
@@ -5420,21 +5413,21 @@ static int selinux_key_alloc(struct key *k, const 
struct cred *cred,
        if (!ksec)
                return -ENOMEM;
 
-       tsec = cred->security;
+       tsec = lsm_get_cred(cred, &selinux_ops);
        if (tsec->keycreate_sid)
                ksec->sid = tsec->keycreate_sid;
        else
                ksec->sid = tsec->sid;
 
-       k->security = ksec;
+       lsm_set_key(k, ksec, &selinux_ops);
        return 0;
 }
 
 static void selinux_key_free(struct key *k)
 {
-       struct key_security_struct *ksec = k->security;
+       struct key_security_struct *ksec = lsm_get_key(k, &selinux_ops);
 
-       k->security = NULL;
+       lsm_set_key(k, NULL, &selinux_ops);
        kfree(ksec);
 }
 
@@ -5455,14 +5448,14 @@ static int selinux_key_permission(key_ref_t key_ref,
        sid = cred_sid(cred);
 
        key = key_ref_to_ptr(key_ref);
-       ksec = key->security;
+       ksec = lsm_get_key(key, &selinux_ops);
 
        return avc_has_perm(sid, ksec->sid, SECCLASS_KEY, perm, NULL);
 }
 
 static int selinux_key_getsecurity(struct key *key, char **_buffer)
 {
-       struct key_security_struct *ksec = key->security;
+       struct key_security_struct *ksec = lsm_get_key(key, &selinux_ops);
        char *context = NULL;
        unsigned len;
        int rc;
@@ -5476,7 +5469,7 @@ static int selinux_key_getsecurity(struct key *key, char 
**_buffer)
 
 #endif
 
-static struct security_operations selinux_ops = {
+struct security_operations selinux_ops = {
        .name =                         "selinux",
 
        .ptrace_access_check =          selinux_ptrace_access_check,
@@ -5676,13 +5669,13 @@ static struct security_operations selinux_ops = {
 
 static __init int selinux_init(void)
 {
-       if (!security_module_enable(&selinux_ops)) {
-               selinux_enabled = 0;
+       if (!selinux_enabled) {
+               pr_info("SELinux:  Disabled at boot.\n");
                return 0;
        }
 
-       if (!selinux_enabled) {
-               printk(KERN_INFO "SELinux:  Disabled at boot.\n");
+       if (!security_module_enable(&selinux_ops)) {
+               selinux_enabled = 0;
                return 0;
        }
 
@@ -5694,13 +5687,10 @@ static __init int selinux_init(void)
        default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
 
        sel_inode_cache = kmem_cache_create("selinux_inode_security",
-                                           sizeof(struct 
inode_security_struct),
-                                           0, SLAB_PANIC, NULL);
+                                   sizeof(struct inode_security_struct),
+                                   0, SLAB_PANIC, NULL);
        avc_init();
 
-       if (register_security(&selinux_ops))
-               panic("SELinux: Unable to register with kernel.\n");
-
        if (selinux_enforcing)
                printk(KERN_DEBUG "SELinux:  Starting in enforcing mode\n");
        else
@@ -5824,6 +5814,8 @@ static int selinux_disabled;
 
 int selinux_disable(void)
 {
+       int rc;
+
        if (ss_initialized) {
                /* Not permitted after initial policy load. */
                return -EINVAL;
@@ -5834,13 +5826,17 @@ int selinux_disable(void)
                return -EINVAL;
        }
 
+       rc = reset_security_ops(&selinux_ops);
+       if (rc) {
+               pr_info("SELinux:  Runtime disable disallowed.\n");
+               return rc;
+       }
+
        printk(KERN_INFO "SELinux:  Disabled at runtime.\n");
 
        selinux_disabled = 1;
        selinux_enabled = 0;
 
-       reset_security_ops();
-
        /* Try to destroy the avc node cache */
        avc_disable();
 
diff --git a/security/selinux/include/objsec.h 
b/security/selinux/include/objsec.h
index 26c7eee..1d1dd10 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -24,6 +24,7 @@
 #include <linux/binfmts.h>
 #include <linux/in.h>
 #include <linux/spinlock.h>
+#include <linux/lsm.h>
 #include "flask.h"
 #include "avc.h"
 
@@ -115,5 +116,6 @@ struct key_security_struct {
 };
 
 extern unsigned int selinux_checkreqprot;
+extern struct security_operations selinux_ops;
 
 #endif /* _SELINUX_OBJSEC_H_ */
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 65f67cb..1219221 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -31,7 +31,7 @@ static inline struct inode_security_struct 
*get_sock_isec(struct sock *sk)
        if (!sk->sk_socket)
                return NULL;
 
-       return SOCK_INODE(sk->sk_socket)->i_security;
+       return lsm_get_inode(SOCK_INODE(sk->sk_socket), &selinux_ops);
 }
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index da4b8b2..7a9cbd0 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -81,7 +81,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff 
*skb,
 static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
 {
        int rc;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        struct netlbl_lsm_secattr *secattr;
 
        if (sksec->nlbl_secattr != NULL)
@@ -221,7 +221,8 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
         * being labeled by it's parent socket, if it is just exit */
        sk = skb->sk;
        if (sk != NULL) {
-               struct sk_security_struct *sksec = sk->sk_security;
+               struct sk_security_struct *sksec =
+                                       lsm_get_sock(sk, &selinux_ops);
                if (sksec->nlbl_state != NLBL_REQSKB)
                        return 0;
                secattr = sksec->nlbl_secattr;
@@ -283,7 +284,7 @@ inet_conn_request_return:
  */
 void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
 {
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
 
        if (family == PF_INET)
                sksec->nlbl_state = NLBL_LABELED;
@@ -304,7 +305,7 @@ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 
family)
 int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
 {
        int rc;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        struct netlbl_lsm_secattr *secattr;
 
        if (family != PF_INET)
@@ -402,7 +403,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
 {
        int rc = 0;
        struct sock *sk = sock->sk;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        struct netlbl_lsm_secattr secattr;
 
        if (level == IPPROTO_IP && optname == IP_OPTIONS &&
@@ -435,7 +436,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
 int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
 {
        int rc;
-       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *sksec = lsm_get_sock(sk, &selinux_ops);
        struct netlbl_lsm_secattr *secattr;
 
        if (sksec->nlbl_state != NLBL_REQSKB &&
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 3a6e873..415c6b7 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -83,7 +83,7 @@ static int task_has_security(struct task_struct *tsk,
        u32 sid = 0;
 
        rcu_read_lock();
-       tsec = __task_cred(tsk)->security;
+       tsec = lsm_get_cred(__task_cred(tsk), &selinux_ops);
        if (tsec)
                sid = tsec->sid;
        rcu_read_unlock();
@@ -1264,7 +1264,7 @@ static int sel_make_bools(void)
                if (len >= PAGE_SIZE)
                        goto out;
 
-               isec = (struct inode_security_struct *)inode->i_security;
+               isec = lsm_get_inode(inode, &selinux_ops);
                ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, 
&sid);
                if (ret)
                        goto out;
@@ -1831,7 +1831,7 @@ static int sel_fill_super(struct super_block *sb, void 
*data, int silent)
                goto err;
 
        inode->i_ino = ++sel_last_ino;
-       isec = (struct inode_security_struct *)inode->i_security;
+       isec = lsm_get_inode(inode, &selinux_ops);
        isec->sid = SECINITSID_DEVNULL;
        isec->sclass = SECCLASS_CHR_FILE;
        isec->initialized = 1;
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 48665ec..02979a3 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -198,7 +198,8 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx 
**ctxp,
        struct xfrm_user_sec_ctx *uctx, u32 sid)
 {
        int rc = 0;
-       const struct task_security_struct *tsec = current_security();
+       const struct task_security_struct *tsec =
+                               lsm_get_cred(current_cred(), &selinux_ops);
        struct xfrm_sec_ctx *ctx = NULL;
        char *ctx_str = NULL;
        u32 str_len;
@@ -334,7 +335,8 @@ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
  */
 int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
 {
-       const struct task_security_struct *tsec = current_security();
+       const struct task_security_struct *tsec =
+                               lsm_get_cred(current_cred(), &selinux_ops);
        int rc = 0;
 
        if (ctx) {
@@ -379,7 +381,8 @@ void selinux_xfrm_state_free(struct xfrm_state *x)
   */
 int selinux_xfrm_state_delete(struct xfrm_state *x)
 {
-       const struct task_security_struct *tsec = current_security();
+       const struct task_security_struct *tsec =
+                               lsm_get_cred(current_cred(), &selinux_ops);
        struct xfrm_sec_ctx *ctx = x->security;
        int rc = 0;
 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to