From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S262444AbVG0SaX (ORCPT ); Wed, 27 Jul 2005 14:30:23 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S262432AbVG0S2q (ORCPT ); Wed, 27 Jul 2005 14:28:46 -0400 Received: from e1.ny.us.ibm.com ([32.97.182.141]:38821 "EHLO e1.ny.us.ibm.com") by vger.kernel.org with ESMTP id S262371AbVG0S0I (ORCPT ); Wed, 27 Jul 2005 14:26:08 -0400 Date: Wed, 27 Jul 2005 13:26:30 -0500 From: serue@us.ibm.com To: lkml Cc: Chris Wright , Stephen Smalley , James Morris , Andrew Morton , Michael Halcrow , David Safford , Reiner Sailer , Gerrit Huizenga , Emily Ratliff Subject: [patch 10/15] lsm stacking v0.3: selinux: use security_*_value API Message-ID: <20050727182630.GK22483@serge.austin.ibm.com> References: <20050727181732.GA22483@serge.austin.ibm.com> <20050727181921.GB22483@serge.austin.ibm.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20050727181921.GB22483@serge.austin.ibm.com> User-Agent: Mutt/1.5.8i Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Convert SELinux to use the security_*_value_type API for storing and using information appended to kernel objects, instead of directly using the void*. Signed-off-by: Serge Hallyn -- hooks.c | 446 +++++++++++++++++++++++++++++++++++++++--------------------- selinuxfs.c | 10 - 2 files changed, 300 insertions(+), 156 deletions(-) Index: linux-2.6.13-rc3/security/selinux/hooks.c =================================================================== --- linux-2.6.13-rc3.orig/security/selinux/hooks.c 2005-07-25 14:40:42.000000000 -0500 +++ linux-2.6.13-rc3/security/selinux/hooks.c 2005-07-25 14:55:39.000000000 -0500 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -127,30 +128,30 @@ static int task_alloc_security(struct ta return -ENOMEM; memset(tsec, 0, sizeof(struct task_security_struct)); - tsec->magic = SELINUX_MAGIC; tsec->task = task; tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED; - task->security = tsec; + security_set_value_type(&task->security, SELINUX_LSM_ID, tsec); return 0; } static void task_free_security(struct task_struct *task) { - struct task_security_struct *tsec = task->security; - - if (!tsec || tsec->magic != SELINUX_MAGIC) - return; + struct task_security_struct *tsec; + + tsec = security_del_value_type(&task->security, SELINUX_LSM_ID, + struct task_security_struct); - task->security = NULL; kfree(tsec); } static int inode_alloc_security(struct inode *inode) { - struct task_security_struct *tsec = current->security; + struct task_security_struct *tsec; struct inode_security_struct *isec; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL); if (!isec) return -ENOMEM; @@ -158,68 +159,71 @@ static int inode_alloc_security(struct i memset(isec, 0, sizeof(struct inode_security_struct)); init_MUTEX(&isec->sem); INIT_LIST_HEAD(&isec->list); - isec->magic = SELINUX_MAGIC; isec->inode = inode; isec->sid = SECINITSID_UNLABELED; isec->sclass = SECCLASS_FILE; - if (tsec && tsec->magic == SELINUX_MAGIC) + if (tsec) isec->task_sid = tsec->sid; else isec->task_sid = SECINITSID_UNLABELED; - inode->i_security = isec; + security_set_value_type(&inode->i_security, SELINUX_LSM_ID, isec); 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; + struct superblock_security_struct *sbsec; - if (!isec || isec->magic != SELINUX_MAGIC) + isec = security_del_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + if (!isec) return; + sbsec = security_get_value_type(&inode->i_sb->s_security, + SELINUX_LSM_ID, struct superblock_security_struct); + spin_lock(&sbsec->isec_lock); if (!list_empty(&isec->list)) list_del_init(&isec->list); spin_unlock(&sbsec->isec_lock); - inode->i_security = NULL; kfree(isec); } static int file_alloc_security(struct file *file) { - struct task_security_struct *tsec = current->security; + struct task_security_struct *tsec; struct file_security_struct *fsec; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC); if (!fsec) return -ENOMEM; memset(fsec, 0, sizeof(struct file_security_struct)); - fsec->magic = SELINUX_MAGIC; fsec->file = file; - if (tsec && tsec->magic == SELINUX_MAGIC) { + if (tsec) { fsec->sid = tsec->sid; fsec->fown_sid = tsec->sid; } else { fsec->sid = SECINITSID_UNLABELED; fsec->fown_sid = SECINITSID_UNLABELED; } - file->f_security = fsec; + security_set_value_type(&file->f_security, SELINUX_LSM_ID, fsec); return 0; } static void file_free_security(struct file *file) { - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec; - if (!fsec || fsec->magic != SELINUX_MAGIC) - return; + fsec = security_del_value_type(&file->f_security, SELINUX_LSM_ID, + struct file_security_struct); - file->f_security = NULL; kfree(fsec); } @@ -236,20 +240,21 @@ static int superblock_alloc_security(str INIT_LIST_HEAD(&sbsec->list); INIT_LIST_HEAD(&sbsec->isec_head); spin_lock_init(&sbsec->isec_lock); - sbsec->magic = SELINUX_MAGIC; sbsec->sb = sb; sbsec->sid = SECINITSID_UNLABELED; sbsec->def_sid = SECINITSID_FILE; - sb->s_security = sbsec; + security_set_value_type(&sb->s_security, SELINUX_LSM_ID, sbsec); return 0; } static void superblock_free_security(struct super_block *sb) { - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec; - if (!sbsec || sbsec->magic != SELINUX_MAGIC) + sbsec = security_del_value_type(&sb->s_security, SELINUX_LSM_ID, + struct superblock_security_struct); + if (!sbsec) return; spin_lock(&sb_security_lock); @@ -257,7 +262,6 @@ static void superblock_free_security(str list_del_init(&sbsec->list); spin_unlock(&sb_security_lock); - sb->s_security = NULL; kfree(sbsec); } @@ -274,22 +278,23 @@ static int sk_alloc_security(struct sock return -ENOMEM; memset(ssec, 0, sizeof(*ssec)); - ssec->magic = SELINUX_MAGIC; ssec->sk = sk; ssec->peer_sid = SECINITSID_UNLABELED; - sk->sk_security = ssec; + security_set_value_type(&sk->sk_security, SELINUX_LSM_ID, ssec); return 0; } static void sk_free_security(struct sock *sk) { - struct sk_security_struct *ssec = sk->sk_security; + struct sk_security_struct *ssec; - if (sk->sk_family != PF_UNIX || ssec->magic != SELINUX_MAGIC) + if (sk->sk_family != PF_UNIX) return; - sk->sk_security = NULL; + ssec = security_del_value_type(&sk->sk_security, SELINUX_LSM_ID, + struct sk_security_struct); + kfree(ssec); } #endif /* CONFIG_SECURITY_NETWORK */ @@ -336,8 +341,13 @@ static int try_context_mount(struct supe const char *name; u32 sid; int alloc = 0, rc = 0, seen = 0; - struct task_security_struct *tsec = current->security; - struct superblock_security_struct *sbsec = sb->s_security; + struct task_security_struct *tsec; + struct superblock_security_struct *sbsec; + + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + sbsec = security_get_value_type(&sb->s_security, SELINUX_LSM_ID, + struct superblock_security_struct); if (!data) goto out; @@ -503,11 +513,14 @@ out: static int superblock_doinit(struct super_block *sb, void *data) { - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec; struct dentry *root = sb->s_root; struct inode *inode = root->d_inode; int rc = 0; + sbsec = security_get_value_type(&sb->s_security, SELINUX_LSM_ID, + struct superblock_security_struct); + down(&sbsec->sem); if (sbsec->initialized) goto out; @@ -732,7 +745,7 @@ static int selinux_proc_get_sid(struct p 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; u32 sid; struct dentry *dentry; #define INITCONTEXTLEN 255 @@ -741,6 +754,9 @@ static int inode_doinit_with_dentry(stru int rc = 0; int hold_sem = 0; + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + if (isec->initialized) goto out; @@ -749,7 +765,8 @@ static int inode_doinit_with_dentry(stru if (isec->initialized) goto out; - sbsec = inode->i_sb->s_security; + sbsec = security_get_value_type(&inode->i_sb->s_security, + SELINUX_LSM_ID, struct superblock_security_struct); if (!sbsec->initialized) { /* Defer initialization until selinux_complete_init, after the initial policy is loaded and the security @@ -923,8 +940,10 @@ static int task_has_perm(struct task_str { struct task_security_struct *tsec1, *tsec2; - tsec1 = tsk1->security; - tsec2 = tsk2->security; + tsec1 = security_get_value_type(&tsk1->security, SELINUX_LSM_ID, + struct task_security_struct); + tsec2 = security_get_value_type(&tsk2->security, SELINUX_LSM_ID, + struct task_security_struct); return avc_has_perm(tsec1->sid, tsec2->sid, SECCLASS_PROCESS, perms, NULL); } @@ -936,7 +955,8 @@ static int task_has_capability(struct ta struct task_security_struct *tsec; struct avc_audit_data ad; - tsec = tsk->security; + tsec = security_get_value_type(&tsk->security, SELINUX_LSM_ID, + struct task_security_struct); AVC_AUDIT_DATA_INIT(&ad,CAP); ad.tsk = tsk; @@ -952,7 +972,8 @@ static int task_has_system(struct task_s { struct task_security_struct *tsec; - tsec = tsk->security; + tsec = security_get_value_type(&tsk->security, SELINUX_LSM_ID, + struct task_security_struct); return avc_has_perm(tsec->sid, SECINITSID_KERNEL, SECCLASS_SYSTEM, perms, NULL); @@ -970,8 +991,10 @@ static int inode_has_perm(struct task_st struct inode_security_struct *isec; struct avc_audit_data ad; - tsec = tsk->security; - isec = inode->i_security; + tsec = security_get_value_type(&tsk->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); if (!adp) { adp = &ad; @@ -1010,14 +1033,19 @@ static inline int file_has_perm(struct t struct file *file, u32 av) { - struct task_security_struct *tsec = tsk->security; - struct file_security_struct *fsec = file->f_security; + struct task_security_struct *tsec; + struct file_security_struct *fsec; struct vfsmount *mnt = file->f_vfsmnt; struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; struct avc_audit_data ad; int rc; + tsec = security_get_value_type(&tsk->security, SELINUX_LSM_ID, + struct task_security_struct); + fsec = security_get_value_type(&file->f_security, SELINUX_LSM_ID, + struct file_security_struct); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.mnt = mnt; ad.u.fs.dentry = dentry; @@ -1050,9 +1078,12 @@ static int may_create(struct inode *dir, struct avc_audit_data ad; int rc; - tsec = current->security; - dsec = dir->i_security; - sbsec = dir->i_sb->s_security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + dsec = security_get_value_type(&dir->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + sbsec = security_get_value_type(&dir->i_sb->s_security, SELINUX_LSM_ID, + struct superblock_security_struct); AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.dentry = dentry; @@ -1097,9 +1128,12 @@ static int may_link(struct inode *dir, u32 av; int rc; - tsec = current->security; - dsec = dir->i_security; - isec = dentry->d_inode->i_security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + dsec = security_get_value_type(&dir->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + isec = security_get_value_type(&dentry->d_inode->i_security, + SELINUX_LSM_ID, struct inode_security_struct); AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.dentry = dentry; @@ -1141,11 +1175,15 @@ static inline int may_rename(struct inod int old_is_dir, new_is_dir; int rc; - tsec = current->security; - old_dsec = old_dir->i_security; - old_isec = old_dentry->d_inode->i_security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + old_dsec = security_get_value_type(&old_dir->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + old_isec = security_get_value_type(&old_dentry->d_inode->i_security, + SELINUX_LSM_ID, struct inode_security_struct); old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); - new_dsec = new_dir->i_security; + new_dsec = security_get_value_type(&new_dir->i_security, SELINUX_LSM_ID, + struct inode_security_struct); AVC_AUDIT_DATA_INIT(&ad, FS); @@ -1173,7 +1211,8 @@ static inline int may_rename(struct inod if (rc) return rc; if (new_dentry->d_inode) { - new_isec = new_dentry->d_inode->i_security; + new_isec = security_get_value_type(&new_dentry->d_inode->i_security, + SELINUX_LSM_ID, struct inode_security_struct); new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode); rc = avc_has_perm(tsec->sid, new_isec->sid, new_isec->sclass, @@ -1194,8 +1233,10 @@ static int superblock_has_perm(struct ta struct task_security_struct *tsec; struct superblock_security_struct *sbsec; - tsec = tsk->security; - sbsec = sb->s_security; + tsec = security_get_value_type(&tsk->security, SELINUX_LSM_ID, + struct task_security_struct); + sbsec = security_get_value_type(&sb->s_security, SELINUX_LSM_ID, + struct superblock_security_struct); return avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad); } @@ -1248,8 +1289,13 @@ static inline u32 file_to_av(struct file /* Set an inode's SID to a specified value. */ static int inode_security_set_sid(struct inode *inode, u32 sid) { - struct inode_security_struct *isec = inode->i_security; - struct superblock_security_struct *sbsec = inode->i_sb->s_security; + struct inode_security_struct *isec; + struct superblock_security_struct *sbsec; + + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + sbsec = security_get_value_type(&inode->i_sb->s_security, + SELINUX_LSM_ID, struct superblock_security_struct); if (!sbsec->initialized) { /* Defer initialization to selinux_complete_init. */ @@ -1278,9 +1324,12 @@ static int post_create(struct inode *dir unsigned int len; int rc; - tsec = current->security; - dsec = dir->i_security; - sbsec = dir->i_sb->s_security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + dsec = security_get_value_type(&dir->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + sbsec = security_get_value_type(&dir->i_sb->s_security, SELINUX_LSM_ID, + struct superblock_security_struct); inode = dentry->d_inode; if (!inode) { @@ -1347,13 +1396,17 @@ static int post_create(struct inode *dir static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) { - struct task_security_struct *psec = parent->security; - struct task_security_struct *csec = child->security; + struct task_security_struct *psec; + struct task_security_struct *csec; int rc; rc = secondary_ops->ptrace(parent,child); if (rc) return rc; + psec = security_get_value_type(&parent->security, SELINUX_LSM_ID, + struct task_security_struct); + csec = security_get_value_type(&child->security, SELINUX_LSM_ID, + struct task_security_struct); rc = task_has_perm(parent, child, PROCESS__PTRACE); /* Save the SID of the tracing process for later use in apply_creds. */ @@ -1415,7 +1468,8 @@ static int selinux_sysctl(ctl_table *tab if (rc) return rc; - tsec = current->security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); rc = selinux_proc_get_sid(table->de, (op == 001) ? SECCLASS_DIR : SECCLASS_FILE, &tsid); @@ -1550,12 +1604,11 @@ static int selinux_bprm_alloc_security(s return -ENOMEM; memset(bsec, 0, sizeof *bsec); - bsec->magic = SELINUX_MAGIC; bsec->bprm = bprm; bsec->sid = SECINITSID_UNLABELED; bsec->set = 0; - bprm->security = bsec; + security_set_value_type(&bprm->security, SELINUX_LSM_ID, bsec); return 0; } @@ -1573,13 +1626,16 @@ static int selinux_bprm_set_security(str if (rc) return rc; - bsec = bprm->security; + bsec = security_get_value_type(&bprm->security, SELINUX_LSM_ID, + struct bprm_security_struct); if (bsec->set) return 0; - tsec = current->security; - isec = inode->i_security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); /* Default to the current task SID. */ bsec->sid = tsec->sid; @@ -1642,9 +1698,11 @@ static int selinux_bprm_check_security ( static int selinux_bprm_secureexec (struct linux_binprm *bprm) { - struct task_security_struct *tsec = current->security; + struct task_security_struct *tsec; int atsecure = 0; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); if (tsec->osid != tsec->sid) { /* Enable secure mode for SIDs transitions unless the noatsecure permission is granted between @@ -1659,8 +1717,11 @@ static int selinux_bprm_secureexec (stru static void selinux_bprm_free_security(struct linux_binprm *bprm) { - kfree(bprm->security); - bprm->security = NULL; + struct bprm_security_struct *bsec; + + bsec = security_del_value_type(&bprm->security, SELINUX_LSM_ID, + struct bprm_security_struct); + kfree(bsec); } extern struct vfsmount *selinuxfs_mount; @@ -1757,9 +1818,10 @@ static void selinux_bprm_apply_creds(str secondary_ops->bprm_apply_creds(bprm, unsafe); - tsec = current->security; - - bsec = bprm->security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + bsec = security_get_value_type(&bprm->security, SELINUX_LSM_ID, + struct bprm_security_struct); sid = bsec->sid; tsec->osid = tsec->sid; @@ -1802,8 +1864,10 @@ static void selinux_bprm_post_apply_cred struct bprm_security_struct *bsec; int rc, i; - tsec = current->security; - bsec = bprm->security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + bsec = security_get_value_type(&bprm->security, SELINUX_LSM_ID, + struct bprm_security_struct); if (bsec->unsafe) { force_sig_specific(SIGKILL, current); @@ -2163,9 +2227,9 @@ static int selinux_inode_getattr(struct static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) { - struct task_security_struct *tsec = current->security; + struct task_security_struct *tsec; struct inode *inode = dentry->d_inode; - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec; struct superblock_security_struct *sbsec; struct avc_audit_data ad; u32 newsid; @@ -2185,7 +2249,8 @@ static int selinux_inode_setxattr(struct return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); } - sbsec = inode->i_sb->s_security; + sbsec = security_get_value_type(&inode->i_sb->s_security, + SELINUX_LSM_ID, struct superblock_security_struct); if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) return -EOPNOTSUPP; @@ -2195,6 +2260,10 @@ static int selinux_inode_setxattr(struct AVC_AUDIT_DATA_INIT(&ad,FS); ad.u.fs.dentry = dentry; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, FILE__RELABELFROM, &ad); if (rc) @@ -2225,10 +2294,13 @@ static void selinux_inode_post_setxattr( 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; u32 newsid; int rc; + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + if (strcmp(name, XATTR_NAME_SELINUX)) { /* Not an attribute we recognize, so nothing to do. */ return; @@ -2248,7 +2320,10 @@ static void selinux_inode_post_setxattr( static int selinux_inode_getxattr (struct dentry *dentry, char *name) { struct inode *inode = dentry->d_inode; - struct superblock_security_struct *sbsec = inode->i_sb->s_security; + struct superblock_security_struct *sbsec; + + sbsec = security_get_value_type(&inode->i_sb->s_security, + SELINUX_LSM_ID, struct superblock_security_struct); if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) return -EOPNOTSUPP; @@ -2285,7 +2360,7 @@ static int selinux_inode_removexattr (st static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size) { - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec; char *context; unsigned len; int rc; @@ -2295,6 +2370,9 @@ static int selinux_inode_getsecurity(str if (strcmp(name, XATTR_SELINUX_SUFFIX)) return -EOPNOTSUPP; + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + rc = security_sid_to_context(isec->sid, &context, &len); if (rc) return rc; @@ -2315,13 +2393,16 @@ static int selinux_inode_getsecurity(str 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; u32 newsid; int rc; if (strcmp(name, XATTR_SELINUX_SUFFIX)) return -EOPNOTSUPP; + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); + if (!value || !size) return -EACCES; @@ -2568,8 +2649,10 @@ static int selinux_file_set_fowner(struc struct task_security_struct *tsec; struct file_security_struct *fsec; - tsec = current->security; - fsec = file->f_security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + fsec = security_get_value_type(&file->f_security, SELINUX_LSM_ID, + struct file_security_struct); fsec->fown_sid = tsec->sid; return 0; @@ -2586,8 +2669,10 @@ static int selinux_file_send_sigiotask(s /* struct fown_struct is never outside the context of a struct file */ file = (struct file *)((long)fown - offsetof(struct file,f_owner)); - tsec = tsk->security; - fsec = file->f_security; + tsec = security_get_value_type(&tsk->security, SELINUX_LSM_ID, + struct task_security_struct); + fsec = security_get_value_type(&file->f_security, SELINUX_LSM_ID, + struct file_security_struct); if (!signum) perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ @@ -2621,12 +2706,14 @@ static int selinux_task_alloc_security(s struct task_security_struct *tsec1, *tsec2; int rc; - tsec1 = current->security; + tsec1 = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); rc = task_alloc_security(tsk); if (rc) return rc; - tsec2 = tsk->security; + tsec2 = security_get_value_type(&tsk->security, SELINUX_LSM_ID, + struct task_security_struct); tsec2->osid = tsec1->osid; tsec2->sid = tsec1->sid; @@ -2779,7 +2866,8 @@ static void selinux_task_reparent_to_ini secondary_ops->task_reparent_to_init(p); - tsec = p->security; + tsec = security_get_value_type(&p->security, SELINUX_LSM_ID, + struct task_security_struct); tsec->osid = tsec->sid; tsec->sid = SECINITSID_KERNEL; return; @@ -2788,8 +2876,13 @@ static void selinux_task_reparent_to_ini static void selinux_task_to_inode(struct task_struct *p, struct inode *inode) { - struct task_security_struct *tsec = p->security; - struct inode_security_struct *isec = inode->i_security; + struct task_security_struct *tsec; + struct inode_security_struct *isec; + + tsec = security_get_value_type(&p->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); isec->sid = tsec->sid; isec->initialized = 1; @@ -2957,8 +3050,10 @@ static int socket_has_perm(struct task_s struct avc_audit_data ad; int err = 0; - tsec = task->security; - isec = SOCK_INODE(sock)->i_security; + tsec = security_get_value_type(&task->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&SOCK_INODE(sock)->i_security, SELINUX_LSM_ID, + struct inode_security_struct); if (isec->sid == SECINITSID_KERNEL) goto out; @@ -2980,7 +3075,8 @@ static int selinux_socket_create(int fam if (kern) goto out; - tsec = current->security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); err = avc_has_perm(tsec->sid, tsec->sid, socket_type_to_security_class(family, type, protocol), SOCKET__CREATE, NULL); @@ -2995,9 +3091,11 @@ static void selinux_socket_post_create(s struct inode_security_struct *isec; struct task_security_struct *tsec; - isec = SOCK_INODE(sock)->i_security; + isec = security_get_value_type(&SOCK_INODE(sock)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); - tsec = current->security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); isec->sclass = socket_type_to_security_class(family, type, protocol); isec->sid = kern ? SECINITSID_KERNEL : tsec->sid; isec->initialized = 1; @@ -3035,8 +3133,10 @@ static int selinux_socket_bind(struct so struct sock *sk = sock->sk; u32 sid, node_perm, addrlen; - tsec = current->security; - isec = SOCK_INODE(sock)->i_security; + tsec = security_get_value_type(¤t->security, + SELINUX_LSM_ID, struct task_security_struct); + isec = security_get_value_type(&SOCK_INODE(sock)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); if (family == PF_INET) { addr4 = (struct sockaddr_in *)address; @@ -3114,7 +3214,8 @@ static int selinux_socket_connect(struct /* * If a TCP socket, check name_connect permission for the port. */ - isec = SOCK_INODE(sock)->i_security; + isec = security_get_value_type(&SOCK_INODE(sock)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); if (isec->sclass == SECCLASS_TCP_SOCKET) { struct sock *sk = sock->sk; struct avc_audit_data ad; @@ -3168,9 +3269,11 @@ static int selinux_socket_accept(struct if (err) return err; - newisec = SOCK_INODE(newsock)->i_security; + newisec = security_get_value_type(&SOCK_INODE(newsock)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); - isec = SOCK_INODE(sock)->i_security; + isec = security_get_value_type(&SOCK_INODE(sock)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); newisec->sclass = isec->sclass; newisec->sid = isec->sid; newisec->initialized = 1; @@ -3230,8 +3333,10 @@ static int selinux_socket_unix_stream_co if (err) return err; - isec = SOCK_INODE(sock)->i_security; - other_isec = SOCK_INODE(other)->i_security; + isec = security_get_value_type(&SOCK_INODE(sock)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); + other_isec = security_get_value_type(&SOCK_INODE(other)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); AVC_AUDIT_DATA_INIT(&ad,NET); ad.u.net.sk = other->sk; @@ -3243,11 +3348,13 @@ static int selinux_socket_unix_stream_co return err; /* connecting socket */ - ssec = sock->sk->sk_security; + ssec = security_get_value_type(&sock->sk->sk_security, SELINUX_LSM_ID, + struct sk_security_struct); ssec->peer_sid = other_isec->sid; /* server child socket */ - ssec = newsk->sk_security; + ssec = security_get_value_type(&newsk->sk_security, SELINUX_LSM_ID, + struct sk_security_struct); ssec->peer_sid = isec->sid; return 0; @@ -3261,8 +3368,10 @@ static int selinux_socket_unix_may_send( struct avc_audit_data ad; int err; - isec = SOCK_INODE(sock)->i_security; - other_isec = SOCK_INODE(other)->i_security; + isec = security_get_value_type(&SOCK_INODE(sock)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); + other_isec = security_get_value_type(&SOCK_INODE(other)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); AVC_AUDIT_DATA_INIT(&ad,NET); ad.u.net.sk = other->sk; @@ -3302,7 +3411,8 @@ static int selinux_socket_sock_rcv_skb(s inode = SOCK_INODE(sock); if (inode) { struct inode_security_struct *isec; - isec = inode->i_security; + isec = security_get_value_type(&inode->i_security, + SELINUX_LSM_ID, struct inode_security_struct); sock_sid = isec->sid; sock_class = isec->sclass; } @@ -3385,13 +3495,15 @@ static int selinux_socket_getpeersec(str struct sk_security_struct *ssec; struct inode_security_struct *isec; - isec = SOCK_INODE(sock)->i_security; + isec = security_get_value_type(&SOCK_INODE(sock)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); if (isec->sclass != SECCLASS_UNIX_STREAM_SOCKET) { err = -ENOPROTOOPT; goto out; } - ssec = sock->sk->sk_security; + ssec = security_get_value_type(&sock->sk->sk_security, SELINUX_LSM_ID, + struct sk_security_struct); err = security_sid_to_context(ssec->peer_sid, &scontext, &scontext_len); if (err) @@ -3430,7 +3542,10 @@ static int selinux_nlmsg_perm(struct soc u32 perm; struct nlmsghdr *nlh; struct socket *sock = sk->sk_socket; - struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; + struct inode_security_struct *isec; + + isec = security_get_value_type(&SOCK_INODE(sock)->i_security, + SELINUX_LSM_ID, struct inode_security_struct); if (skb->len < NLMSG_SPACE(0)) { err = -EINVAL; @@ -3496,7 +3611,8 @@ static unsigned int selinux_ip_postroute if (err) goto out; - isec = inode->i_security; + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); switch (isec->sclass) { case SECCLASS_UDP_SOCKET: @@ -3606,7 +3722,8 @@ static int selinux_netlink_send(struct s if (err) return err; - tsec = current->security; + tsec = security_get_value_type(¤t->security, + SELINUX_LSM_ID, struct task_security_struct); avd.allowed = 0; avc_has_perm_noaudit(tsec->sid, tsec->sid, @@ -3630,15 +3747,17 @@ static int ipc_alloc_security(struct tas struct kern_ipc_perm *perm, u16 sclass) { - struct task_security_struct *tsec = task->security; + struct task_security_struct *tsec; struct ipc_security_struct *isec; + tsec = security_get_value_type(&task->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = kmalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); if (!isec) return -ENOMEM; memset(isec, 0, sizeof(struct ipc_security_struct)); - isec->magic = SELINUX_MAGIC; isec->sclass = sclass; isec->ipc_perm = perm; if (tsec) { @@ -3646,18 +3765,18 @@ static int ipc_alloc_security(struct tas } else { isec->sid = SECINITSID_UNLABELED; } - perm->security = isec; + security_set_value_type(&perm->security, SELINUX_LSM_ID, isec); return 0; } static void ipc_free_security(struct kern_ipc_perm *perm) { - struct ipc_security_struct *isec = perm->security; - if (!isec || isec->magic != SELINUX_MAGIC) - return; + struct ipc_security_struct *isec; + + isec = security_del_value_type(&perm->security, SELINUX_LSM_ID, + struct ipc_security_struct); - perm->security = NULL; kfree(isec); } @@ -3670,21 +3789,20 @@ static int msg_msg_alloc_security(struct return -ENOMEM; memset(msec, 0, sizeof(struct msg_security_struct)); - msec->magic = SELINUX_MAGIC; msec->msg = msg; msec->sid = SECINITSID_UNLABELED; - msg->security = msec; + security_set_value_type(&msg->security, SELINUX_LSM_ID, msec); return 0; } static void msg_msg_free_security(struct msg_msg *msg) { - struct msg_security_struct *msec = msg->security; - if (!msec || msec->magic != SELINUX_MAGIC) - return; + struct msg_security_struct *msec; + + msec = security_del_value_type(&msg->security, SELINUX_LSM_ID, + struct msg_security_struct); - msg->security = NULL; kfree(msec); } @@ -3695,8 +3813,10 @@ static int ipc_has_perm(struct kern_ipc_ struct ipc_security_struct *isec; struct avc_audit_data ad; - tsec = current->security; - isec = ipc_perms->security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&ipc_perms->security, SELINUX_LSM_ID, + struct ipc_security_struct); AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = ipc_perms->key; @@ -3726,8 +3846,10 @@ static int selinux_msg_queue_alloc_secur if (rc) return rc; - tsec = current->security; - isec = msq->q_perm.security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&msq->q_perm.security, SELINUX_LSM_ID, + struct ipc_security_struct); AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = msq->q_perm.key; @@ -3752,8 +3874,10 @@ static int selinux_msg_queue_associate(s struct ipc_security_struct *isec; struct avc_audit_data ad; - tsec = current->security; - isec = msq->q_perm.security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&msq->q_perm.security, SELINUX_LSM_ID, + struct ipc_security_struct); AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = msq->q_perm.key; @@ -3798,9 +3922,12 @@ static int selinux_msg_queue_msgsnd(stru struct avc_audit_data ad; int rc; - tsec = current->security; - isec = msq->q_perm.security; - msec = msg->security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&msq->q_perm.security, SELINUX_LSM_ID, + struct ipc_security_struct); + msec = security_get_value_type(&msg->security, SELINUX_LSM_ID, + struct msg_security_struct); /* * First time through, need to assign label to the message @@ -3846,9 +3973,12 @@ static int selinux_msg_queue_msgrcv(stru struct avc_audit_data ad; int rc; - tsec = target->security; - isec = msq->q_perm.security; - msec = msg->security; + tsec = security_get_value_type(&target->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&msq->q_perm.security, SELINUX_LSM_ID, + struct ipc_security_struct); + msec = security_get_value_type(&msg->security, SELINUX_LSM_ID, + struct msg_security_struct); AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = msq->q_perm.key; @@ -3873,8 +4003,10 @@ static int selinux_shm_alloc_security(st if (rc) return rc; - tsec = current->security; - isec = shp->shm_perm.security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&shp->shm_perm.security, SELINUX_LSM_ID, + struct ipc_security_struct); AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = shp->shm_perm.key; @@ -3899,8 +4031,10 @@ static int selinux_shm_associate(struct struct ipc_security_struct *isec; struct avc_audit_data ad; - tsec = current->security; - isec = shp->shm_perm.security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&shp->shm_perm.security, SELINUX_LSM_ID, + struct ipc_security_struct); AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = shp->shm_perm.key; @@ -3972,8 +4106,10 @@ static int selinux_sem_alloc_security(st if (rc) return rc; - tsec = current->security; - isec = sma->sem_perm.security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&sma->sem_perm.security, SELINUX_LSM_ID, + struct ipc_security_struct); AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = sma->sem_perm.key; @@ -3998,8 +4134,10 @@ static int selinux_sem_associate(struct struct ipc_security_struct *isec; struct avc_audit_data ad; - tsec = current->security; - isec = sma->sem_perm.security; + tsec = security_get_value_type(¤t->security, SELINUX_LSM_ID, + struct task_security_struct); + isec = security_get_value_type(&sma->sem_perm.security, SELINUX_LSM_ID, + struct ipc_security_struct); AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = sma->sem_perm.key; @@ -4133,7 +4271,8 @@ static int selinux_getprocattr(struct ta if (!size) return -ERANGE; - tsec = p->security; + tsec = security_get_value_type(&p->security, SELINUX_LSM_ID, + struct task_security_struct); if (!strcmp(name, "current")) sid = tsec->sid; @@ -4208,7 +4347,8 @@ static int selinux_setprocattr(struct ta operation. See selinux_bprm_set_security for the execve checks and may_create for the file creation checks. The operation will then fail if the context is not permitted. */ - tsec = p->security; + tsec = security_get_value_type(&p->security, SELINUX_LSM_ID, + struct task_security_struct); if (!strcmp(name, "exec")) tsec->exec_sid = sid; else if (!strcmp(name, "fscreate")) Index: linux-2.6.13-rc3/security/selinux/selinuxfs.c =================================================================== --- linux-2.6.13-rc3.orig/security/selinux/selinuxfs.c 2005-07-25 14:40:12.000000000 -0500 +++ linux-2.6.13-rc3/security/selinux/selinuxfs.c 2005-07-25 14:55:39.000000000 -0500 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -59,7 +60,8 @@ static int task_has_security(struct task { struct task_security_struct *tsec; - tsec = tsk->security; + tsec = security_get_value_type(&tsk->security, SELINUX_LSM_ID, + struct task_security_struct); if (!tsec) return -EACCES; @@ -982,7 +984,8 @@ static int sel_make_bools(void) ret = -ENAMETOOLONG; goto err; } - isec = (struct inode_security_struct*)inode->i_security; + isec = security_get_value_type(&inode->i_security, + SELINUX_LSM_ID, struct inode_security_struct); if ((ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid))) goto err; isec->sid = sid; @@ -1267,7 +1270,8 @@ static int sel_fill_super(struct super_b inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); if (!inode) goto out; - isec = (struct inode_security_struct*)inode->i_security; + isec = security_get_value_type(&inode->i_security, SELINUX_LSM_ID, + struct inode_security_struct); isec->sid = SECINITSID_DEVNULL; isec->sclass = SECCLASS_CHR_FILE; isec->initialized = 1;