fs/vfs/security: pass last path component to LSM on inode creation
authorEric Paris <eparis@redhat.com>
Tue, 1 Feb 2011 16:05:39 +0000 (11:05 -0500)
committerEric Paris <eparis@redhat.com>
Tue, 1 Feb 2011 16:12:29 +0000 (11:12 -0500)
SELinux would like to implement a new labeling behavior of newly created
inodes.  We currently label new inodes based on the parent and the creating
process.  This new behavior would also take into account the name of the
new object when deciding the new label.  This is not the (supposed) full path,
just the last component of the path.

This is very useful because creating /etc/shadow is different than creating
/etc/passwd but the kernel hooks are unable to differentiate these
operations.  We currently require that userspace realize it is doing some
difficult operation like that and than userspace jumps through SELinux hoops
to get things set up correctly.  This patch does not implement new
behavior, that is obviously contained in a seperate SELinux patch, but it
does pass the needed name down to the correct LSM hook.  If no such name
exists it is fine to pass NULL.

Signed-off-by: Eric Paris <eparis@redhat.com>
39 files changed:
fs/btrfs/inode.c
fs/btrfs/xattr.c
fs/btrfs/xattr.h
fs/ext2/ext2.h
fs/ext2/ialloc.c
fs/ext2/namei.c
fs/ext2/xattr.h
fs/ext2/xattr_security.c
fs/ext3/ialloc.c
fs/ext3/namei.c
fs/ext3/xattr.h
fs/ext3/xattr_security.c
fs/ext4/ialloc.c
fs/ext4/xattr.h
fs/ext4/xattr_security.c
fs/gfs2/inode.c
fs/jffs2/dir.c
fs/jffs2/nodelist.h
fs/jffs2/security.c
fs/jffs2/write.c
fs/jffs2/xattr.h
fs/jfs/jfs_xattr.h
fs/jfs/namei.c
fs/jfs/xattr.c
fs/ocfs2/namei.c
fs/ocfs2/refcounttree.c
fs/ocfs2/xattr.c
fs/ocfs2/xattr.h
fs/reiserfs/namei.c
fs/reiserfs/xattr_security.c
fs/xfs/linux-2.6/xfs_iops.c
include/linux/ext3_fs.h
include/linux/reiserfs_xattr.h
include/linux/security.h
mm/shmem.c
security/capability.c
security/security.c
security/selinux/hooks.c
security/smack/smack_lsm.c

index a0ff46a478953fa118e342e9684e5e869c3d3615..49c04bec6a9da1fa611b02a8e1b4e9f31aa492d4 100644 (file)
@@ -90,13 +90,14 @@ static noinline int cow_file_range(struct inode *inode,
                                   unsigned long *nr_written, int unlock);
 
 static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
-                                    struct inode *inode,  struct inode *dir)
+                                    struct inode *inode,  struct inode *dir,
+                                    const struct qstr *qstr)
 {
        int err;
 
        err = btrfs_init_acl(trans, inode, dir);
        if (!err)
-               err = btrfs_xattr_security_init(trans, inode, dir);
+               err = btrfs_xattr_security_init(trans, inode, dir, qstr);
        return err;
 }
 
@@ -4675,7 +4676,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_inode_security(trans, inode, dir);
+       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
@@ -4736,7 +4737,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_inode_security(trans, inode, dir);
+       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
@@ -4864,7 +4865,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
        drop_on_err = 1;
 
-       err = btrfs_init_inode_security(trans, inode, dir);
+       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
        if (err)
                goto out_fail;
 
@@ -6946,7 +6947,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_inode_security(trans, inode, dir);
+       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
index 698fdd2c739c9286e549c290983ed1f08138ef39..3338a7e61d25ea2c4a5b6505a489e0f7ad23eddd 100644 (file)
@@ -352,7 +352,8 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
 }
 
 int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
-                             struct inode *inode, struct inode *dir)
+                             struct inode *inode, struct inode *dir,
+                             const struct qstr *qstr)
 {
        int err;
        size_t len;
@@ -360,7 +361,8 @@ int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
        char *suffix;
        char *name;
 
-       err = security_inode_init_security(inode, dir, &suffix, &value, &len);
+       err = security_inode_init_security(inode, dir, qstr, &suffix, &value,
+                                          &len);
        if (err) {
                if (err == -EOPNOTSUPP)
                        return 0;
index 7a43fd640bbb54b97c63fe37ab2dbea9e28c00e0..b3cc8039134bc4ed59420f51b48ab72c04f2eedc 100644 (file)
@@ -37,6 +37,7 @@ extern int btrfs_setxattr(struct dentry *dentry, const char *name,
 extern int btrfs_removexattr(struct dentry *dentry, const char *name);
 
 extern int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
-                                    struct inode *inode, struct inode *dir);
+                                    struct inode *inode, struct inode *dir,
+                                    const struct qstr *qstr);
 
 #endif /* __XATTR__ */
index 6346a2acf326075b2e23739a2ba9b55ce6d56c33..1b48c337087293bfb95733d52def539f68ff219d 100644 (file)
@@ -110,7 +110,7 @@ extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
 extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *, int);
 
 /* ialloc.c */
-extern struct inode * ext2_new_inode (struct inode *, int);
+extern struct inode * ext2_new_inode (struct inode *, int, const struct qstr *);
 extern void ext2_free_inode (struct inode *);
 extern unsigned long ext2_count_free_inodes (struct super_block *);
 extern void ext2_check_inodes_bitmap (struct super_block *);
index ad70479aabff30d08d1b322846e7e3f49ecbe3d5..ee9ed31948e1229d123cbea2fcea5e45ff42aa3f 100644 (file)
@@ -429,7 +429,8 @@ found:
        return group;
 }
 
-struct inode *ext2_new_inode(struct inode *dir, int mode)
+struct inode *ext2_new_inode(struct inode *dir, int mode,
+                            const struct qstr *qstr)
 {
        struct super_block *sb;
        struct buffer_head *bitmap_bh = NULL;
@@ -585,7 +586,7 @@ got:
        if (err)
                goto fail_free_drop;
 
-       err = ext2_init_security(inode,dir);
+       err = ext2_init_security(inode, dir, qstr);
        if (err)
                goto fail_free_drop;
 
index f8aecd2e32976c40b1af182a13a312ae0b8e23fe..368d7049ac8933de05ea2e48ba35f1defcdb1175 100644 (file)
@@ -104,7 +104,7 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, st
 
        dquot_initialize(dir);
 
-       inode = ext2_new_inode(dir, mode);
+       inode = ext2_new_inode(dir, mode, &dentry->d_name);
        if (IS_ERR(inode))
                return PTR_ERR(inode);
 
@@ -133,7 +133,7 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_
 
        dquot_initialize(dir);
 
-       inode = ext2_new_inode (dir, mode);
+       inode = ext2_new_inode (dir, mode, &dentry->d_name);
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                init_special_inode(inode, inode->i_mode, rdev);
@@ -159,7 +159,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry,
 
        dquot_initialize(dir);
 
-       inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
+       inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO, &dentry->d_name);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out;
@@ -230,7 +230,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 
        inode_inc_link_count(dir);
 
-       inode = ext2_new_inode (dir, S_IFDIR | mode);
+       inode = ext2_new_inode(dir, S_IFDIR | mode, &dentry->d_name);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_dir;
index a1a1c2184616594c240151b115460856b53cfccf..5e41cccff7622a212fec0a8f2a43fe7e38d8b2d9 100644 (file)
@@ -116,9 +116,11 @@ exit_ext2_xattr(void)
 # endif  /* CONFIG_EXT2_FS_XATTR */
 
 #ifdef CONFIG_EXT2_FS_SECURITY
-extern int ext2_init_security(struct inode *inode, struct inode *dir);
+extern int ext2_init_security(struct inode *inode, struct inode *dir,
+                             const struct qstr *qstr);
 #else
-static inline int ext2_init_security(struct inode *inode, struct inode *dir)
+static inline int ext2_init_security(struct inode *inode, struct inode *dir,
+                                    const struct qstr *qstr)
 {
        return 0;
 }
index 3004e15d5da53a711e064981aeaab3cba7334e8c..5d979b4347b03c3b3820f6cb14c8566cdeb9497a 100644 (file)
@@ -47,14 +47,15 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
 }
 
 int
-ext2_init_security(struct inode *inode, struct inode *dir)
+ext2_init_security(struct inode *inode, struct inode *dir,
+                  const struct qstr *qstr)
 {
        int err;
        size_t len;
        void *value;
        char *name;
 
-       err = security_inode_init_security(inode, dir, &name, &value, &len);
+       err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
        if (err) {
                if (err == -EOPNOTSUPP)
                        return 0;
index 9724aef224600c17faf288464d43cb7c5766ad3e..bfc2dc43681d41c6b54fe405174cc480de1663e9 100644 (file)
@@ -404,7 +404,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
  * For other inodes, search forward from the parent directory's block
  * group to find a free inode.
  */
-struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
+struct inode *ext3_new_inode(handle_t *handle, struct inode * dir,
+                            const struct qstr *qstr, int mode)
 {
        struct super_block *sb;
        struct buffer_head *bitmap_bh = NULL;
@@ -589,7 +590,7 @@ got:
        if (err)
                goto fail_free_drop;
 
-       err = ext3_init_security(handle,inode, dir);
+       err = ext3_init_security(handle, inode, dir, qstr);
        if (err)
                goto fail_free_drop;
 
index bce9dce639b874989fc687173531728842557c24..a900033efcce7b605fe4a846b55743530c01c783 100644 (file)
@@ -1707,7 +1707,7 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
 
-       inode = ext3_new_inode (handle, dir, mode);
+       inode = ext3_new_inode (handle, dir, &dentry->d_name, mode);
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                inode->i_op = &ext3_file_inode_operations;
@@ -1743,7 +1743,7 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
 
-       inode = ext3_new_inode (handle, dir, mode);
+       inode = ext3_new_inode (handle, dir, &dentry->d_name, mode);
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                init_special_inode(inode, inode->i_mode, rdev);
@@ -1781,7 +1781,7 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
 
-       inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
+       inode = ext3_new_inode (handle, dir, &dentry->d_name, S_IFDIR | mode);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_stop;
@@ -2195,7 +2195,7 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
 
-       inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
+       inode = ext3_new_inode (handle, dir, &dentry->d_name, S_IFLNK|S_IRWXUGO);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_stop;
index 377fe720116995caa90f94821bfe808e2c0e4b9b..2be4f69bfa64b301d437e5130868f433a01d5f50 100644 (file)
@@ -128,10 +128,10 @@ exit_ext3_xattr(void)
 
 #ifdef CONFIG_EXT3_FS_SECURITY
 extern int ext3_init_security(handle_t *handle, struct inode *inode,
-                               struct inode *dir);
+                             struct inode *dir, const struct qstr *qstr);
 #else
 static inline int ext3_init_security(handle_t *handle, struct inode *inode,
-                               struct inode *dir)
+                                    struct inode *dir, const struct qstr *qstr)
 {
        return 0;
 }
index 03a99bfc59f90f1f7331251e70e71ce9f94253af..b8d9f83aa5c545f23b48f14530b6ee0578204a66 100644 (file)
@@ -49,14 +49,15 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
 }
 
 int
-ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir)
+ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
+                  const struct qstr *qstr)
 {
        int err;
        size_t len;
        void *value;
        char *name;
 
-       err = security_inode_init_security(inode, dir, &name, &value, &len);
+       err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
        if (err) {
                if (err == -EOPNOTSUPP)
                        return 0;
index 1ce240a23ebb84963ce2126b78f126657fd7d6df..49b6cfd1fc47325fea1a112ad59a3e14e2068e33 100644 (file)
@@ -1042,7 +1042,7 @@ got:
        if (err)
                goto fail_free_drop;
 
-       err = ext4_init_security(handle, inode, dir);
+       err = ext4_init_security(handle, inode, dir, qstr);
        if (err)
                goto fail_free_drop;
 
index 1ef16520b950c8a4c0c5385ee24f620b147065e2..25b7387ff183f880cdb9ccaf2529ca8c0f218a7b 100644 (file)
@@ -145,10 +145,10 @@ ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
 
 #ifdef CONFIG_EXT4_FS_SECURITY
 extern int ext4_init_security(handle_t *handle, struct inode *inode,
-                               struct inode *dir);
+                             struct inode *dir, const struct qstr *qstr);
 #else
 static inline int ext4_init_security(handle_t *handle, struct inode *inode,
-                               struct inode *dir)
+                                    struct inode *dir, const struct qstr *qstr)
 {
        return 0;
 }
index 9b21268e121c1a90f83465fa7a54292c2d8a56f0..007c3bfbf094221988855d9eb754bfdf430d569e 100644 (file)
@@ -49,14 +49,15 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
 }
 
 int
-ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir)
+ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
+                  const struct qstr *qstr)
 {
        int err;
        size_t len;
        void *value;
        char *name;
 
-       err = security_inode_init_security(inode, dir, &name, &value, &len);
+       err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
        if (err) {
                if (err == -EOPNOTSUPP)
                        return 0;
index 2232b3c780bd9678a2e80394b674444ee8401a14..de35ca7d7980eab4ea7ce7f5d6da98cf1adace7a 100644 (file)
@@ -791,14 +791,15 @@ fail:
        return error;
 }
 
-static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip)
+static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
+                             const struct qstr *qstr)
 {
        int err;
        size_t len;
        void *value;
        char *name;
 
-       err = security_inode_init_security(&ip->i_inode, &dip->i_inode,
+       err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
                                           &name, &value, &len);
 
        if (err) {
@@ -882,7 +883,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        if (error)
                goto fail_gunlock2;
 
-       error = gfs2_security_init(dip, GFS2_I(inode));
+       error = gfs2_security_init(dip, GFS2_I(inode), name);
        if (error)
                goto fail_gunlock2;
 
index 92978658ed1803bc289840500e8a220cbf032ffa..82faddd1f321b74e8efd4f11fe07449e409d7bbc 100644 (file)
@@ -215,8 +215,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
           no chance of AB-BA deadlock involving its f->sem). */
        mutex_unlock(&f->sem);
 
-       ret = jffs2_do_create(c, dir_f, f, ri,
-                             dentry->d_name.name, dentry->d_name.len);
+       ret = jffs2_do_create(c, dir_f, f, ri, &dentry->d_name);
        if (ret)
                goto fail;
 
@@ -386,7 +385,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
 
        jffs2_complete_reservation(c);
 
-       ret = jffs2_init_security(inode, dir_i);
+       ret = jffs2_init_security(inode, dir_i, &dentry->d_name);
        if (ret)
                goto fail;
 
@@ -530,7 +529,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
 
        jffs2_complete_reservation(c);
 
-       ret = jffs2_init_security(inode, dir_i);
+       ret = jffs2_init_security(inode, dir_i, &dentry->d_name);
        if (ret)
                goto fail;
 
@@ -703,7 +702,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
 
        jffs2_complete_reservation(c);
 
-       ret = jffs2_init_security(inode, dir_i);
+       ret = jffs2_init_security(inode, dir_i, &dentry->d_name);
        if (ret)
                goto fail;
 
index 5a53d9bdb2b584a3e1cb737ed028183d99f527e2..e4619b00f7c5dec65669f0b1dd9acdf135392185 100644 (file)
@@ -401,7 +401,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
                            struct jffs2_raw_inode *ri, unsigned char *buf,
                            uint32_t offset, uint32_t writelen, uint32_t *retlen);
 int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f,
-                   struct jffs2_raw_inode *ri, const char *name, int namelen);
+                   struct jffs2_raw_inode *ri, const struct qstr *qstr);
 int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name,
                    int namelen, struct jffs2_inode_info *dead_f, uint32_t time);
 int jffs2_do_link(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino,
index 239f51216a68ee6e9ec1f4dc156ff513b686bc85..cfeb7164b0853a0d163cf7552f89577743067575 100644 (file)
 #include "nodelist.h"
 
 /* ---- Initial Security Label Attachment -------------- */
-int jffs2_init_security(struct inode *inode, struct inode *dir)
+int jffs2_init_security(struct inode *inode, struct inode *dir,
+                       const struct qstr *qstr)
 {
        int rc;
        size_t len;
        void *value;
        char *name;
 
-       rc = security_inode_init_security(inode, dir, &name, &value, &len);
+       rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
        if (rc) {
                if (rc == -EOPNOTSUPP)
                        return 0;
index c819eb0e982d8b95a216a09ab9398c9bd7e3ea58..30d175b6d290698fad6a38f6bbafba755eee90b4 100644 (file)
@@ -424,7 +424,9 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
        return ret;
 }
 
-int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen)
+int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
+                   struct jffs2_inode_info *f, struct jffs2_raw_inode *ri,
+                   const struct qstr *qstr)
 {
        struct jffs2_raw_dirent *rd;
        struct jffs2_full_dnode *fn;
@@ -466,15 +468,15 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
        mutex_unlock(&f->sem);
        jffs2_complete_reservation(c);
 
-       ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode);
+       ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode, qstr);
        if (ret)
                return ret;
        ret = jffs2_init_acl_post(&f->vfs_inode);
        if (ret)
                return ret;
 
-       ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
-                               ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
+       ret = jffs2_reserve_space(c, sizeof(*rd)+qstr->len, &alloclen,
+                               ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(qstr->len));
 
        if (ret) {
                /* Eep. */
@@ -493,19 +495,19 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
 
        rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
        rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-       rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
+       rd->totlen = cpu_to_je32(sizeof(*rd) + qstr->len);
        rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
 
        rd->pino = cpu_to_je32(dir_f->inocache->ino);
        rd->version = cpu_to_je32(++dir_f->highest_version);
        rd->ino = ri->ino;
        rd->mctime = ri->ctime;
-       rd->nsize = namelen;
+       rd->nsize = qstr->len;
        rd->type = DT_REG;
        rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-       rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
+       rd->name_crc = cpu_to_je32(crc32(0, qstr->name, qstr->len));
 
-       fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL);
+       fd = jffs2_write_dirent(c, dir_f, rd, qstr->name, qstr->len, ALLOC_NORMAL);
 
        jffs2_free_raw_dirent(rd);
 
index cf4f5759b42b407ba614d1c40fd67b9db511e01a..7be4beb306f3ff06eb6df2a8427ca31cb2027e6f 100644 (file)
@@ -121,10 +121,11 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
 #endif /* CONFIG_JFFS2_FS_XATTR */
 
 #ifdef CONFIG_JFFS2_FS_SECURITY
-extern int jffs2_init_security(struct inode *inode, struct inode *dir);
+extern int jffs2_init_security(struct inode *inode, struct inode *dir,
+                              const struct qstr *qstr);
 extern const struct xattr_handler jffs2_security_xattr_handler;
 #else
-#define jffs2_init_security(inode,dir) (0)
+#define jffs2_init_security(inode,dir,qstr)    (0)
 #endif /* CONFIG_JFFS2_FS_SECURITY */
 
 #endif /* _JFFS2_FS_XATTR_H_ */
index 88b6cc535bf246cee2dc33487993fcd488b48dc2..e9e100fd7c09a90a7ba603e7f1282ae9ba15e164 100644 (file)
@@ -62,10 +62,11 @@ extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
 extern int jfs_removexattr(struct dentry *, const char *);
 
 #ifdef CONFIG_JFS_SECURITY
-extern int jfs_init_security(tid_t, struct inode *, struct inode *);
+extern int jfs_init_security(tid_t, struct inode *, struct inode *,
+                            const struct qstr *);
 #else
 static inline int jfs_init_security(tid_t tid, struct inode *inode,
-                                   struct inode *dir)
+                                   struct inode *dir, const struct qstr *qstr)
 {
        return 0;
 }
index 4414e3a42264f4c3372b5107f8b485687a7b7ed7..030b9174e416967a7b631620bfdbd697ec012620 100644 (file)
@@ -115,7 +115,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
        if (rc)
                goto out3;
 
-       rc = jfs_init_security(tid, ip, dip);
+       rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
        if (rc) {
                txAbort(tid, 0);
                goto out3;
@@ -253,7 +253,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
        if (rc)
                goto out3;
 
-       rc = jfs_init_security(tid, ip, dip);
+       rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
        if (rc) {
                txAbort(tid, 0);
                goto out3;
@@ -932,7 +932,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
        mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
 
-       rc = jfs_init_security(tid, ip, dip);
+       rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
        if (rc)
                goto out3;
 
@@ -1395,7 +1395,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
        if (rc)
                goto out3;
 
-       rc = jfs_init_security(tid, ip, dir);
+       rc = jfs_init_security(tid, ip, dir, &dentry->d_name);
        if (rc) {
                txAbort(tid, 0);
                goto out3;
index 2d7f165d0f1d0b6be01c2003f57fbd64182465ac..3fa4c32272dfa16453f4fbe6995354d219cf4d91 100644 (file)
@@ -1091,7 +1091,8 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
 }
 
 #ifdef CONFIG_JFS_SECURITY
-int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir)
+int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
+                     const struct qstr *qstr)
 {
        int rc;
        size_t len;
@@ -1099,7 +1100,8 @@ int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir)
        char *suffix;
        char *name;
 
-       rc = security_inode_init_security(inode, dir, &suffix, &value, &len);
+       rc = security_inode_init_security(inode, dir, qstr, &suffix, &value,
+                                         &len);
        if (rc) {
                if (rc == -EOPNOTSUPP)
                        return 0;
index d14cad6e2e412b29ea98e6678a653081deb5f308..bd8d6461a68b6e8ae0eb79f1263500595064d3e7 100644 (file)
@@ -294,7 +294,7 @@ static int ocfs2_mknod(struct inode *dir,
        }
 
        /* get security xattr */
-       status = ocfs2_init_security_get(inode, dir, &si);
+       status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);
        if (status) {
                if (status == -EOPNOTSUPP)
                        si.enable = 0;
@@ -1665,7 +1665,7 @@ static int ocfs2_symlink(struct inode *dir,
        }
 
        /* get security xattr */
-       status = ocfs2_init_security_get(inode, dir, &si);
+       status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);
        if (status) {
                if (status == -EOPNOTSUPP)
                        si.enable = 0;
index b5f9160e93e9119b949451bb3e5db66b3c1df62c..cd3f5b4832ef1cab3f371e495ffddb8dae63ef16 100644 (file)
@@ -4325,7 +4325,8 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir,
 
        /* If the security isn't preserved, we need to re-initialize them. */
        if (!preserve) {
-               error = ocfs2_init_security_and_acl(dir, new_orphan_inode);
+               error = ocfs2_init_security_and_acl(dir, new_orphan_inode,
+                                                   &new_dentry->d_name);
                if (error)
                        mlog_errno(error);
        }
index 67cd43914641f5d3d522c098763437e21b7c7f46..6bb602486c6bdf92a635855d120d8c724b34aef5 100644 (file)
@@ -7185,7 +7185,8 @@ out:
  * must not hold any lock expect i_mutex.
  */
 int ocfs2_init_security_and_acl(struct inode *dir,
-                               struct inode *inode)
+                               struct inode *inode,
+                               const struct qstr *qstr)
 {
        int ret = 0;
        struct buffer_head *dir_bh = NULL;
@@ -7193,7 +7194,7 @@ int ocfs2_init_security_and_acl(struct inode *dir,
                .enable = 1,
        };
 
-       ret = ocfs2_init_security_get(inode, dir, &si);
+       ret = ocfs2_init_security_get(inode, dir, qstr, &si);
        if (!ret) {
                ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
                                      si.name, si.value, si.value_len,
@@ -7261,13 +7262,14 @@ static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name,
 
 int ocfs2_init_security_get(struct inode *inode,
                            struct inode *dir,
+                           const struct qstr *qstr,
                            struct ocfs2_security_xattr_info *si)
 {
        /* check whether ocfs2 support feature xattr */
        if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
                return -EOPNOTSUPP;
-       return security_inode_init_security(inode, dir, &si->name, &si->value,
-                                           &si->value_len);
+       return security_inode_init_security(inode, dir, qstr, &si->name,
+                                           &si->value, &si->value_len);
 }
 
 int ocfs2_init_security_set(handle_t *handle,
index aa64bb37a65bd73a61d8f61e6ba6fd970f67686e..d63cfb72316b451c59bb15193461137f941109d5 100644 (file)
@@ -57,6 +57,7 @@ int ocfs2_has_inline_xattr_value_outside(struct inode *inode,
                                         struct ocfs2_dinode *di);
 int ocfs2_xattr_remove(struct inode *, struct buffer_head *);
 int ocfs2_init_security_get(struct inode *, struct inode *,
+                           const struct qstr *,
                            struct ocfs2_security_xattr_info *);
 int ocfs2_init_security_set(handle_t *, struct inode *,
                            struct buffer_head *,
@@ -94,5 +95,6 @@ int ocfs2_reflink_xattrs(struct inode *old_inode,
                         struct buffer_head *new_bh,
                         bool preserve_security);
 int ocfs2_init_security_and_acl(struct inode *dir,
-                               struct inode *inode);
+                               struct inode *inode,
+                               const struct qstr *qstr);
 #endif /* OCFS2_XATTR_H */
index ba5f51ec345829499982f17196fc61ac444429a0..d5b22ed067796c67d4e04dffce1e31bbe58dfa6c 100644 (file)
@@ -593,7 +593,7 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode,
        new_inode_init(inode, dir, mode);
 
        jbegin_count += reiserfs_cache_default_acl(dir);
-       retval = reiserfs_security_init(dir, inode, &security);
+       retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security);
        if (retval < 0) {
                drop_new_inode(inode);
                return retval;
@@ -667,7 +667,7 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
        new_inode_init(inode, dir, mode);
 
        jbegin_count += reiserfs_cache_default_acl(dir);
-       retval = reiserfs_security_init(dir, inode, &security);
+       retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security);
        if (retval < 0) {
                drop_new_inode(inode);
                return retval;
@@ -747,7 +747,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        new_inode_init(inode, dir, mode);
 
        jbegin_count += reiserfs_cache_default_acl(dir);
-       retval = reiserfs_security_init(dir, inode, &security);
+       retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security);
        if (retval < 0) {
                drop_new_inode(inode);
                return retval;
@@ -1032,7 +1032,8 @@ static int reiserfs_symlink(struct inode *parent_dir,
        }
        new_inode_init(inode, parent_dir, mode);
 
-       retval = reiserfs_security_init(parent_dir, inode, &security);
+       retval = reiserfs_security_init(parent_dir, inode, &dentry->d_name,
+                                       &security);
        if (retval < 0) {
                drop_new_inode(inode);
                return retval;
index 237c6928d3c69fe6901ea7abf74e4e6b1a220800..ef66c18a933266e9c658fde311f7a1d0e2d6d023 100644 (file)
@@ -54,6 +54,7 @@ static size_t security_list(struct dentry *dentry, char *list, size_t list_len,
  * of blocks needed for the transaction. If successful, reiserfs_security
  * must be released using reiserfs_security_free when the caller is done. */
 int reiserfs_security_init(struct inode *dir, struct inode *inode,
+                          const struct qstr *qstr,
                           struct reiserfs_security_handle *sec)
 {
        int blocks = 0;
@@ -65,7 +66,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
        if (IS_PRIVATE(dir))
                return 0;
 
-       error = security_inode_init_security(inode, dir, &sec->name,
+       error = security_inode_init_security(inode, dir, qstr, &sec->name,
                                             &sec->value, &sec->length);
        if (error) {
                if (error == -EOPNOTSUPP)
index 94d5fd6a2973042239bd22f19047947494f57581..d9298cf60266926bc5e1ec4a4ce7236db157178c 100644 (file)
@@ -103,7 +103,8 @@ xfs_mark_inode_dirty(
 STATIC int
 xfs_init_security(
        struct inode    *inode,
-       struct inode    *dir)
+       struct inode    *dir,
+       const struct qstr *qstr)
 {
        struct xfs_inode *ip = XFS_I(inode);
        size_t          length;
@@ -111,7 +112,7 @@ xfs_init_security(
        unsigned char   *name;
        int             error;
 
-       error = security_inode_init_security(inode, dir, (char **)&name,
+       error = security_inode_init_security(inode, dir, qstr, (char **)&name,
                                             &value, &length);
        if (error) {
                if (error == -EOPNOTSUPP)
@@ -195,7 +196,7 @@ xfs_vn_mknod(
 
        inode = VFS_I(ip);
 
-       error = xfs_init_security(inode, dir);
+       error = xfs_init_security(inode, dir, &dentry->d_name);
        if (unlikely(error))
                goto out_cleanup_inode;
 
@@ -368,7 +369,7 @@ xfs_vn_symlink(
 
        inode = VFS_I(cip);
 
-       error = xfs_init_security(inode, dir);
+       error = xfs_init_security(inode, dir, &dentry->d_name);
        if (unlikely(error))
                goto out_cleanup_inode;
 
index 6ce1bca01724dd1408e1f73e60fcdd58caad345c..87312a81dabafb402a37477ca98842b37c8d513f 100644 (file)
@@ -874,7 +874,8 @@ extern int ext3fs_dirhash(const char *name, int len, struct
                          dx_hash_info *hinfo);
 
 /* ialloc.c */
-extern struct inode * ext3_new_inode (handle_t *, struct inode *, int);
+extern struct inode * ext3_new_inode (handle_t *, struct inode *,
+                                     const struct qstr *, int);
 extern void ext3_free_inode (handle_t *, struct inode *);
 extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
 extern unsigned long ext3_count_free_inodes (struct super_block *);
index 3b94c91f20a6dfa6dc6c4553c44350042a560f23..6deef5dc95fb033493bde8e775fba572c47ee1ef 100644 (file)
@@ -63,6 +63,7 @@ extern const struct xattr_handler reiserfs_xattr_trusted_handler;
 extern const struct xattr_handler reiserfs_xattr_security_handler;
 #ifdef CONFIG_REISERFS_FS_SECURITY
 int reiserfs_security_init(struct inode *dir, struct inode *inode,
+                          const struct qstr *qstr,
                           struct reiserfs_security_handle *sec);
 int reiserfs_security_write(struct reiserfs_transaction_handle *th,
                            struct inode *inode,
@@ -130,6 +131,7 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
 #ifndef CONFIG_REISERFS_FS_SECURITY
 static inline int reiserfs_security_init(struct inode *dir,
                                         struct inode *inode,
+                                        const struct qstr *qstr,
                                         struct reiserfs_security_handle *sec)
 {
        return 0;
index c642bb8b8f5a4894b3878a0977a017b684efefe4..05dd5a64aa762c6126e4f9313a1f4965137d455d 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/fs.h>
 #include <linux/fsnotify.h>
 #include <linux/binfmts.h>
+#include <linux/dcache.h>
 #include <linux/signal.h>
 #include <linux/resource.h>
 #include <linux/sem.h>
@@ -315,6 +316,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     then it should return -EOPNOTSUPP to skip this processing.
  *     @inode contains the inode structure of the newly created inode.
  *     @dir contains the inode structure of the parent directory.
+ *     @qstr contains the last path component of the new object
  *     @name will be set to the allocated name suffix (e.g. selinux).
  *     @value will be set to the allocated attribute value.
  *     @len will be set to the length of the value.
@@ -1435,7 +1437,8 @@ struct security_operations {
        int (*inode_alloc_security) (struct inode *inode);
        void (*inode_free_security) (struct inode *inode);
        int (*inode_init_security) (struct inode *inode, struct inode *dir,
-                                   char **name, void **value, size_t *len);
+                                   const struct qstr *qstr, char **name,
+                                   void **value, size_t *len);
        int (*inode_create) (struct inode *dir,
                             struct dentry *dentry, int mode);
        int (*inode_link) (struct dentry *old_dentry,
@@ -1696,7 +1699,8 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
 int security_inode_alloc(struct inode *inode);
 void security_inode_free(struct inode *inode);
 int security_inode_init_security(struct inode *inode, struct inode *dir,
-                                 char **name, void **value, size_t *len);
+                                const struct qstr *qstr, char **name,
+                                void **value, size_t *len);
 int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
 int security_inode_link(struct dentry *old_dentry, struct inode *dir,
                         struct dentry *new_dentry);
@@ -2023,6 +2027,7 @@ static inline void security_inode_free(struct inode *inode)
 
 static inline int security_inode_init_security(struct inode *inode,
                                                struct inode *dir,
+                                               const struct qstr *qstr,
                                                char **name,
                                                void **value,
                                                size_t *len)
index 5ee67c9906022a15b566711da17b8c78e65fa16d..7c9cdc6fe137f24c2453181a2169976fb979df7d 100644 (file)
@@ -1843,8 +1843,9 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
 
        inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
        if (inode) {
-               error = security_inode_init_security(inode, dir, NULL, NULL,
-                                                    NULL);
+               error = security_inode_init_security(inode, dir,
+                                                    &dentry->d_name, NULL,
+                                                    NULL, NULL);
                if (error) {
                        if (error != -EOPNOTSUPP) {
                                iput(inode);
@@ -1983,8 +1984,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
        if (!inode)
                return -ENOSPC;
 
-       error = security_inode_init_security(inode, dir, NULL, NULL,
-                                            NULL);
+       error = security_inode_init_security(inode, dir, &dentry->d_name, NULL,
+                                            NULL, NULL);
        if (error) {
                if (error != -EOPNOTSUPP) {
                        iput(inode);
index 2a5df2b7da83be0c3d69d9bcd33dd3bd4d935a15..383d14dc12efbbeaeaecaa9309de14443c8d2a89 100644 (file)
@@ -118,7 +118,8 @@ static void cap_inode_free_security(struct inode *inode)
 }
 
 static int cap_inode_init_security(struct inode *inode, struct inode *dir,
-                                  char **name, void **value, size_t *len)
+                                  const struct qstr *qstr, char **name,
+                                  void **value, size_t *len)
 {
        return -EOPNOTSUPP;
 }
index b84a89dd59c6d3a7360b0e9480dcae3e13b9367f..4830f36e1ab563c28c83fd9669b5029109dbe550 100644 (file)
@@ -336,11 +336,13 @@ void security_inode_free(struct inode *inode)
 }
 
 int security_inode_init_security(struct inode *inode, struct inode *dir,
-                                 char **name, void **value, size_t *len)
+                                const struct qstr *qstr, char **name,
+                                void **value, size_t *len)
 {
        if (unlikely(IS_PRIVATE(inode)))
                return -EOPNOTSUPP;
-       return security_ops->inode_init_security(inode, dir, name, value, len);
+       return security_ops->inode_init_security(inode, dir, qstr, name, value,
+                                                len);
 }
 EXPORT_SYMBOL(security_inode_init_security);
 
index e276eb468536d0df5b091afa3f08fbf2352a8c81..099bbd07732fd947be736dd2b6da53c4ffdfd794 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/swap.h>
 #include <linux/spinlock.h>
 #include <linux/syscalls.h>
+#include <linux/dcache.h>
 #include <linux/file.h>
 #include <linux/fdtable.h>
 #include <linux/namei.h>
@@ -2509,8 +2510,8 @@ static void selinux_inode_free_security(struct inode *inode)
 }
 
 static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
-                                      char **name, void **value,
-                                      size_t *len)
+                                      const struct qstr *qstr, char **name,
+                                      void **value, size_t *len)
 {
        const struct task_security_struct *tsec = current_security();
        struct inode_security_struct *dsec;
index 123a499ded372408b7ef9380d03c11636f6cca8c..0c91a906b3f45bdcf39bf3b4253ef5debc438e60 100644 (file)
@@ -33,6 +33,7 @@
 #include <net/cipso_ipv4.h>
 #include <linux/audit.h>
 #include <linux/magic.h>
+#include <linux/dcache.h>
 #include "smack.h"
 
 #define task_security(task)    (task_cred_xxx((task), security))
@@ -501,6 +502,7 @@ static void smack_inode_free_security(struct inode *inode)
  * smack_inode_init_security - copy out the smack from an inode
  * @inode: the inode
  * @dir: unused
+ * @qstr: unused
  * @name: where to put the attribute name
  * @value: where to put the attribute value
  * @len: where to put the length of the attribute
@@ -508,7 +510,8 @@ static void smack_inode_free_security(struct inode *inode)
  * Returns 0 if it all works out, -ENOMEM if there's no memory
  */
 static int smack_inode_init_security(struct inode *inode, struct inode *dir,
-                                    char **name, void **value, size_t *len)
+                                    const struct qstr *qstr, char **name,
+                                    void **value, size_t *len)
 {
        char *isp = smk_of_inode(inode);
        char *dsp = smk_of_inode(dir);