[PATCH v3 2/7] selinux: Add accessor functions for inode->i_security
Add functions dentry_security and inode_security for accessing inode->i_security. These functions initially don't do much, but they will later be used to revalidate the security labels when necessary. Signed-off-by: Andreas Gruenbacher --- security/selinux/hooks.c | 101 ++- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index fc8f626..65e8689 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -241,6 +241,24 @@ static int inode_alloc_security(struct inode *inode) return 0; } +/* + * Get the security label of a dentry's inode. + */ +static struct inode_security_struct *dentry_security(struct dentry *dentry) +{ + struct inode *inode = d_backing_inode(dentry); + + return inode->i_security; +} + +/* + * Get the security label of an inode. + */ +static struct inode_security_struct *inode_security(struct inode *inode) +{ + return inode->i_security; +} + static void inode_free_rcu(struct rcu_head *head) { struct inode_security_struct *isec; @@ -564,8 +582,8 @@ static int selinux_get_mnt_opts(const struct super_block *sb, opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; } if (sbsec->flags & ROOTCONTEXT_MNT) { - struct inode *root = d_backing_inode(sbsec->sb->s_root); - struct inode_security_struct *isec = root->i_security; + struct dentry *root = sbsec->sb->s_root; + struct inode_security_struct *isec = dentry_security(root); rc = security_sid_to_context(isec->sid, &context, &len); if (rc) @@ -620,8 +638,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, int rc = 0, i; struct superblock_security_struct *sbsec = sb->s_security; const char *name = sb->s_type->name; - struct inode *inode = d_backing_inode(sbsec->sb->s_root); - struct inode_security_struct *root_isec = inode->i_security; + struct dentry *root = sbsec->sb->s_root; + struct inode_security_struct *root_isec = dentry_security(root); u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; u32 defcontext_sid = 0; char **mount_options = opts->mnt_opts; @@ -852,8 +870,8 @@ static int selinux_cmp_sb_context(const struct super_block *oldsb, if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid) goto mismatch; if (oldflags & ROOTCONTEXT_MNT) { - struct inode_security_struct *oldroot = d_backing_inode(oldsb->s_root)->i_security; - struct inode_security_struct *newroot = d_backing_inode(newsb->s_root)->i_security; + struct inode_security_struct *oldroot = dentry_security(oldsb->s_root); + struct inode_security_struct *newroot = dentry_security(newsb->s_root); if (oldroot->sid != newroot->sid) goto mismatch; } @@ -903,17 +921,14 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, if (!set_fscontext) newsbsec->sid = sid; if (!set_rootcontext) { - struct inode *newinode = d_backing_inode(newsb->s_root); - struct inode_security_struct *newisec = newinode->i_security; + struct inode_security_struct *newisec = dentry_security(newsb->s_root); newisec->sid = sid; } newsbsec->mntpoint_sid = sid; } if (set_rootcontext) { - const struct inode *oldinode = d_backing_inode(oldsb->s_root); - const struct inode_security_struct *oldisec = oldinode->i_security; - struct inode *newinode = d_backing_inode(newsb->s_root); - struct inode_security_struct *newisec = newinode->i_security; + const struct inode_security_struct *oldisec = dentry_security(oldsb->s_root); + struct inode_security_struct *newisec = dentry_security(newsb->s_root); newisec->sid = oldisec->sid; } @@ -1623,7 +1638,7 @@ static int inode_has_perm(const struct cred *cred, return 0; sid = cred_sid(cred); - isec = inode->i_security; + isec = inode_security(inode); return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp); } @@ -1712,13 +1727,13 @@ out: /* * Determine the label for an inode that might be unioned. */ -static int selinux_determine_inode_label(const struct inode *dir, +static int selinux_determine_inode_label(struct inode *dir, const struct qstr *name, u16 tclass, u32 *_new_isid) { const struct superblock_security_struct *sbsec = dir->i_sb->s_security; - const struct i
Re: [PATCH v3 2/7] selinux: Add accessor functions for inode->i_security
On 10/26/2015 05:15 PM, Andreas Gruenbacher wrote: Add functions dentry_security and inode_security for accessing inode->i_security. These functions initially don't do much, but they will later be used to revalidate the security labels when necessary. Signed-off-by: Andreas Gruenbacher --- security/selinux/hooks.c | 101 ++- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index fc8f626..65e8689 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -241,6 +241,24 @@ static int inode_alloc_security(struct inode *inode) return 0; } +/* + * Get the security label of a dentry's inode. + */ +static struct inode_security_struct *dentry_security(struct dentry *dentry) +{ + struct inode *inode = d_backing_inode(dentry); + + return inode->i_security; +} + +/* + * Get the security label of an inode. + */ +static struct inode_security_struct *inode_security(struct inode *inode) +{ + return inode->i_security; +} + static void inode_free_rcu(struct rcu_head *head) { struct inode_security_struct *isec; @@ -2207,7 +,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) struct task_security_struct *new_tsec; struct inode_security_struct *isec; struct common_audit_data ad; - struct inode *inode = file_inode(bprm->file); int rc; /* SELinux context only depends on initial program or script and not @@ -2217,7 +2231,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) old_tsec = current_security(); new_tsec = bprm->cred->security; - isec = inode->i_security; + isec = dentry_security(bprm->file->f_path.dentry); IIUC, this could change which inode label gets used when using overlayfs (the overlay inode or the underlying inode). Not sure whether the current code is correct for overlayfs (overlayfs + SELinux support still in progress). @@ -3154,7 +3168,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 = inode_security(inode); Was it intentional to not do this for selinux_inode_getsecurity() and selinux_inode_getsecid()? @@ -3241,8 +3254,8 @@ int ioctl_has_perm(const struct cred *cred, struct file *file, { struct common_audit_data ad; struct file_security_struct *fsec = file->f_security; - struct inode *inode = file_inode(file); - struct inode_security_struct *isec = inode->i_security; + struct dentry *dentry = file->f_path.dentry; + struct inode_security_struct *isec = dentry_security(dentry); struct lsm_ioctlop_audit ioctl; u32 ssid = cred_sid(cred); int rc; @@ -3263,7 +3276,7 @@ int ioctl_has_perm(const struct cred *cred, struct file *file, goto out; } - if (unlikely(IS_PRIVATE(inode))) + if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass, @@ -3506,7 +3519,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred) struct inode_security_struct *isec; fsec = file->f_security; - isec = file_inode(file)->i_security; + isec = dentry_security(file->f_path.dentry); Similarly for these cases, switching from file_inode(file) to d_backing_inode(dentry) could affect overlayfs interaction IIUC. cc'd David for clarification. -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 2/7] selinux: Add accessor functions for inode->i_security
On Tue, Oct 27, 2015 at 6:20 PM, Stephen Smalley wrote: > On 10/26/2015 05:15 PM, Andreas Gruenbacher wrote: >> @@ -2217,7 +2231,7 @@ static int selinux_bprm_set_creds(struct >> linux_binprm *bprm) >> >> old_tsec = current_security(); >> new_tsec = bprm->cred->security; >> - isec = inode->i_security; >> + isec = dentry_security(bprm->file->f_path.dentry); > > IIUC, this could change which inode label gets used when using overlayfs > (the overlay inode or the underlying inode). Not sure whether the current > code is correct for overlayfs (overlayfs + SELinux support still in > progress). Okay, let's stick with inode_security, at least for now. >> @@ -3154,7 +3168,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 = inode_security(inode); > > Was it intentional to not do this for selinux_inode_getsecurity() and > selinux_inode_getsecid()? These two hooks both pass in a const inode *, so that needs to be changed first. Then, selinux_inode_getsecurity should obviously use inode_security. I'm not really sure about selinux_inode_getsecid though: can it be call it from a non-sleeping context? >> @@ -3241,8 +3254,8 @@ int ioctl_has_perm(const struct cred *cred, struct >> file *file, >> { >> struct common_audit_data ad; >> struct file_security_struct *fsec = file->f_security; >> - struct inode *inode = file_inode(file); >> - struct inode_security_struct *isec = inode->i_security; >> + struct dentry *dentry = file->f_path.dentry; >> + struct inode_security_struct *isec = dentry_security(dentry); >> struct lsm_ioctlop_audit ioctl; >> u32 ssid = cred_sid(cred); >> int rc; >> @@ -3263,7 +3276,7 @@ int ioctl_has_perm(const struct cred *cred, struct >> file *file, >> goto out; >> } >> >> - if (unlikely(IS_PRIVATE(inode))) >> + if (unlikely(IS_PRIVATE(dentry->d_inode))) >> return 0; >> >> rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass, >> @@ -3506,7 +3519,7 @@ static int selinux_file_open(struct file *file, >> const struct cred *cred) >> struct inode_security_struct *isec; >> >> fsec = file->f_security; >> - isec = file_inode(file)->i_security; >> + isec = dentry_security(file->f_path.dentry); > > > Similarly for these cases, switching from file_inode(file) to > d_backing_inode(dentry) could affect overlayfs interaction IIUC. Okay, let's stick with inode_security as well for now. Thanks, Andreas -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html