Subject: LSM: SELinux changes to allow LSM stacking Change security blob accesses to use the lsm_get/lsm_set interfaces. This requires removal of the cred pointer poisoning in selinux_cred_free. Signed-off-by: Casey Schaufler <casey@xxxxxxxxxxxxxxxx> --- security/Kconfig | 7 +- security/selinux/hooks.c | 264 +++++++++++++++++++++---------------- security/selinux/include/objsec.h | 2 + security/selinux/include/xfrm.h | 2 +- security/selinux/selinuxfs.c | 6 +- security/selinux/xfrm.c | 9 +- 6 files changed, 167 insertions(+), 123 deletions(-) diff --git a/security/Kconfig b/security/Kconfig index cf83c27..fccab76 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -126,12 +126,15 @@ source security/yama/Kconfig config SECURITY_COMPOSER bool "Allow multiple concurrent LSMs" depends on SECURITY && \ - !SECURITY_SELINUX + !(SECURITY_SELINUX && SECURITY_SMACK) default n help Allows multiple security modules to be used concurrently. Only LSMs that have been made composer friendly may be used - when set. Smack, TOMOYO, AppArmor and Yama are composer friendly. + when set. Smack, TOMOYO, AppArmor, SELinux and Yama are + composer friendly. Smack and SELinux have conflicting uses + of the CIPSO IP option. Until a resolution is found they + may not be used together. If you are unsure how to answer this question, answer N. diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6c77f63..d1e0145 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -158,7 +158,7 @@ static void cred_init_security(void) panic("SELinux: Failed to initialize initial task.\n"); tsec->osid = tsec->sid = SECINITSID_KERNEL; - cred->security = tsec; + lsm_set_cred(cred, tsec, &selinux_ops); } /* @@ -168,7 +168,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 +190,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 +213,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 +244,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 +271,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 +326,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 +344,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 +360,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 +451,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 +512,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 +564,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 +764,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 +802,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 +1178,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 +1193,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 +1405,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 +1498,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 +1545,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 +1577,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 +1641,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 +1685,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 +1716,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 +1737,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); } @@ -1969,9 +1988,9 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) 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 +2065,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 +2089,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; @@ -2186,7 +2207,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; @@ -2227,7 +2248,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; @@ -2374,7 +2396,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; @@ -2426,7 +2449,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; @@ -2522,15 +2546,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; @@ -2554,7 +2579,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; @@ -2643,7 +2669,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; @@ -2683,7 +2709,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, @@ -2758,7 +2784,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(); @@ -2767,7 +2793,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; @@ -2835,7 +2861,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; @@ -2890,7 +2916,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; @@ -2926,7 +2952,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; @@ -2955,7 +2981,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; } @@ -2977,8 +3003,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) @@ -3212,7 +3238,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; @@ -3229,7 +3255,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 */ @@ -3252,8 +3278,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 @@ -3292,7 +3318,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; } @@ -3301,14 +3327,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); } @@ -3321,13 +3347,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; } @@ -3336,9 +3362,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; } @@ -3348,7 +3380,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; @@ -3371,8 +3403,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; @@ -3509,7 +3541,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; @@ -3782,7 +3814,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; @@ -3801,8 +3834,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; @@ -4002,9 +4037,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; @@ -4339,7 +4374,8 @@ 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 inode_security_struct *isec = + lsm_get_inode(SOCK_INODE(parent), &selinux_ops); struct sk_security_struct *sksec = sk->sk_security; if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 || @@ -4412,7 +4448,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); @@ -4796,15 +4832,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); } @@ -4817,16 +4853,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); } @@ -4837,7 +4873,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; @@ -4867,7 +4903,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; @@ -4892,7 +4928,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; @@ -4937,8 +4973,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 @@ -4982,8 +5018,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; @@ -5008,7 +5044,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; @@ -5033,7 +5069,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; @@ -5100,7 +5136,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; @@ -5125,7 +5161,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; @@ -5207,7 +5243,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; } @@ -5232,7 +5268,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; @@ -5341,7 +5377,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")) { @@ -5455,21 +5491,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); } @@ -5490,14 +5526,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; @@ -5511,7 +5547,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, 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 c220f31..1e4b4f2 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/selinuxfs.c b/security/selinux/selinuxfs.c index 298e695..7f42abe 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.