Re: [Yaffs] [PATCH] yaffs: set security attribute at file cr…

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: Stephen Smalley
Date:  
To: yaffs
Subject: Re: [Yaffs] [PATCH] yaffs: set security attribute at file creation
On Thu, 2012-08-16 at 14:54 -0400, Stephen Smalley wrote:
> Add support to yaffs to set the security attribute of new inodes when
> they are created. This parallels similar support in other filesystems,
> and is a requirement for SELinux and other MAC systems. This support
> is used by SE Android, http://selinuxproject.org/page/SEAndroid
>
> Signed-off-by: Stephen Smalley <>


Sorry, I see that they changed the hook interface again in v3.2; I'll
update the patch to also handle kernels >= 3.2.

> ---
> yaffs_vfs_multi.c | 43 +++++++++++++++++++++++++++++++++++++++++++
> yaffs_vfs_single.c | 39 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 82 insertions(+)
>
> diff --git a/yaffs_vfs_multi.c b/yaffs_vfs_multi.c
> index ce41d6c..462ebdb 100644
> --- a/yaffs_vfs_multi.c
> +++ b/yaffs_vfs_multi.c
> @@ -71,6 +71,7 @@
> #include <linux/slab.h>
> #include <linux/init.h>
> #include <linux/fs.h>
> +#include <linux/security.h>
> #include <linux/proc_fs.h>
> #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
> #include <linux/smp_lock.h>
> @@ -1618,6 +1619,46 @@ out:
> #define YCRED(x) (x->cred)
> #endif
>
> +static int yaffs_init_security(struct inode *dir, struct dentry *dentry,
> +                   struct inode *inode)
> +{
> +    int err;
> +    size_t size;
> +    void *value;
> +    char *suffix;
> +    char name[XATTR_NAME_MAX];
> +    struct yaffs_dev *dev;
> +    struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
> +    int result;
> +
> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
> +    err = security_inode_init_security(inode, dir, &dentry->d_name,
> +                       &suffix, &value, &size);
> +#else
> +    err = security_inode_init_security(inode, dir, &suffix, &value, &size);
> +#endif
> +    if (err) {
> +        if (err == -EOPNOTSUPP)
> +            return 0;
> +        return err;
> +    }
> +    snprintf(name, sizeof name, "%s%s", XATTR_SECURITY_PREFIX, suffix);
> +
> +    /* inlined yaffs_setxattr: no instantiated dentry yet */
> +    dev = obj->my_dev;
> +    yaffs_gross_lock(dev);
> +    result = yaffs_set_xattrib(obj, name, value, size, 0);
> +    if (result == YAFFS_OK)
> +        err = 0;
> +    else if (result < 0)
> +        err = result;
> +    yaffs_gross_unlock(dev);
> +
> +    kfree(value);
> +    kfree(suffix);
> +    return err;
> +}
> +
>  #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
>  static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
>                 dev_t rdev)
> @@ -1694,6 +1735,7 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,

>
>      if (obj) {
>          inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
> +        yaffs_init_security(dir, dentry, inode);
>          d_instantiate(dentry, inode);
>          update_dir_time(dir);
>          yaffs_trace(YAFFS_TRACE_OS,
> @@ -1827,6 +1869,7 @@ static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
>          struct inode *inode;

>
>          inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
> +        yaffs_init_security(dir, dentry, inode);
>          d_instantiate(dentry, inode);
>          update_dir_time(dir);
>          yaffs_trace(YAFFS_TRACE_OS, "symlink created OK");
> diff --git a/yaffs_vfs_single.c b/yaffs_vfs_single.c
> index 8d41f69..5ce7a55 100644
> --- a/yaffs_vfs_single.c
> +++ b/yaffs_vfs_single.c
> @@ -41,6 +41,7 @@
>  #include <linux/slab.h>
>  #include <linux/init.h>
>  #include <linux/fs.h>
> +#include <linux/security.h>
>  #include <linux/proc_fs.h>
>  #include <linux/pagemap.h>
>  #include <linux/mtd/mtd.h>
> @@ -187,6 +188,42 @@ struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
>      return inode;
>  }

>
> +static int yaffs_init_security(struct inode *dir, struct dentry *dentry,
> +                   struct inode *inode)
> +{
> +    int err;
> +    size_t size;
> +    void *value;
> +    char *suffix;
> +    char name[XATTR_NAME_MAX];
> +    struct yaffs_dev *dev;
> +    struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
> +    int result;
> +
> +    err = security_inode_init_security(inode, dir, &dentry->d_name,
> +                       &suffix, &value, &size);
> +    if (err) {
> +        if (err == -EOPNOTSUPP)
> +            return 0;
> +        return err;
> +    }
> +    snprintf(name, sizeof name, "%s%s", XATTR_SECURITY_PREFIX, suffix);
> +
> +    /* inlined yaffs_setxattr: no instantiated dentry yet */
> +    dev = obj->my_dev;
> +    yaffs_gross_lock(dev);
> +    result = yaffs_set_xattrib(obj, name, value, size, 0);
> +    if (result == YAFFS_OK)
> +        err = 0;
> +    else if (result < 0)
> +        err = result;
> +    yaffs_gross_unlock(dev);
> +
> +    kfree(value);
> +    kfree(suffix);
> +    return err;
> +}
> +
>  static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
>                 dev_t rdev)
>  {
> @@ -259,6 +296,7 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,

>
>
>      inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
> +    yaffs_init_security(dir, dentry, inode);
>      d_instantiate(dentry, inode);
>      update_dir_time(dir);
>      yaffs_trace(YAFFS_TRACE_OS,
> @@ -357,6 +395,7 @@ static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
>      }

>
>      inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
> +    yaffs_init_security(dir, dentry, inode);
>      d_instantiate(dentry, inode);
>      update_dir_time(dir);
>      yaffs_trace(YAFFS_TRACE_OS, "symlink created OK");
> -- 
> 1.7.11.2

>
>


--
Stephen Smalley
National Security Agency