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 <casey@xxxxxxxxxxxxxxxx> --- 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; -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with the words "unsubscribe selinux" without quotes as the message.