[PATCH v3 2/7] selinux: Add accessor functions for inode->i_security

2015-10-26 Thread Andreas Gruenbacher
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

2015-10-27 Thread Stephen Smalley

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

2015-10-28 Thread Andreas Gruenbacher
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