All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
@ 2010-12-03 21:45 Eric Paris
  2010-12-03 21:45 ` [RFC PATCH 2/2] SELinux: Use dentry name in new object labeling Eric Paris
  2010-12-04  4:20 ` [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation Casey Schaufler
  0 siblings, 2 replies; 16+ messages in thread
From: Eric Paris @ 2010-12-03 21:45 UTC (permalink / raw)
  To: selinux; +Cc: eparis, sds, jmorris, linux-security-module, viro, hch

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 that userspace jump 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>
---

 fs/btrfs/inode.c               |   11 ++++++-----
 fs/btrfs/xattr.c               |    3 ++-
 fs/btrfs/xattr.h               |    1 +
 fs/ext2/ext2.h                 |    2 +-
 fs/ext2/ialloc.c               |    4 ++--
 fs/ext2/namei.c                |    8 ++++----
 fs/ext2/xattr.h                |    4 ++--
 fs/ext2/xattr_security.c       |    4 ++--
 fs/ext3/ialloc.c               |    5 +++--
 fs/ext3/namei.c                |    8 ++++----
 fs/ext3/xattr.h                |    8 ++++----
 fs/ext3/xattr_security.c       |    5 +++--
 fs/ext4/ialloc.c               |    2 +-
 fs/ext4/migrate.c              |    2 +-
 fs/ext4/xattr.h                |    8 ++++----
 fs/ext4/xattr_security.c       |    5 +++--
 fs/gfs2/inode.c                |    7 ++++---
 fs/jffs2/dir.c                 |    9 ++++-----
 fs/jffs2/nodelist.h            |    2 +-
 fs/jffs2/security.c            |    5 +++--
 fs/jffs2/write.c               |   16 ++++++++--------
 fs/jffs2/xattr.h               |    5 +++--
 fs/jfs/jfs_xattr.h             |    5 +++--
 fs/jfs/namei.c                 |    8 ++++----
 fs/jfs/xattr.c                 |    5 +++--
 fs/ocfs2/namei.c               |    4 ++--
 fs/ocfs2/refcounttree.c        |    3 ++-
 fs/ocfs2/xattr.c               |   12 +++++++-----
 fs/ocfs2/xattr.h               |    6 ++++--
 fs/reiserfs/namei.c            |    8 ++++----
 fs/reiserfs/xattr_security.c   |    5 +++--
 fs/xfs/linux-2.6/xfs_iops.c    |    9 +++++----
 include/linux/ext3_fs.h        |    2 +-
 include/linux/reiserfs_xattr.h |    6 ++++--
 include/linux/security.h       |   13 ++++++++-----
 mm/shmem.c                     |    8 ++++----
 security/capability.c          |    5 +++--
 security/security.c            |    8 +++++---
 security/selinux/hooks.c       |    6 +++---
 security/smack/smack_lsm.c     |    6 ++++--
 40 files changed, 135 insertions(+), 108 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8039390..7a993ad 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -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,
+				     const struct qstr *qstr,
 				     struct inode *inode,  struct inode *dir)
 {
 	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, qstr, inode, dir);
 	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, &dentry->d_name, inode, dir);
 	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, &dentry->d_name, inode, dir);
 	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, &dentry->d_name, inode, dir);
 	if (err)
 		goto out_fail;
 
@@ -6940,7 +6941,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, &dentry->d_name, inode, dir);
 	if (err) {
 		drop_inode = 1;
 		goto out_unlock;
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 698fdd2..7e9dd88 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -352,6 +352,7 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
 }
 
 int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
+			      const struct qstr *qstr,
 			      struct inode *inode, struct inode *dir)
 {
 	int err;
@@ -360,7 +361,7 @@ 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(qstr, inode, dir, &suffix, &value, &len);
 	if (err) {
 		if (err == -EOPNOTSUPP)
 			return 0;
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h
index 7a43fd6..1e1d9b0 100644
--- a/fs/btrfs/xattr.h
+++ b/fs/btrfs/xattr.h
@@ -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,
+				     const struct qstr *qstr,
 				     struct inode *inode, struct inode *dir);
 
 #endif /* __XATTR__ */
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 6346a2a..1b48c33 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -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 *);
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index ad70479..5be2348 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -429,7 +429,7 @@ 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 +585,7 @@ got:
 	if (err)
 		goto fail_free_drop;
 
-	err = ext2_init_security(inode,dir);
+	err = ext2_init_security(qstr, inode, dir);
 	if (err)
 		goto fail_free_drop;
 
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index f8aecd2..368d704 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -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;
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h
index a1a1c21..7460429 100644
--- a/fs/ext2/xattr.h
+++ b/fs/ext2/xattr.h
@@ -116,9 +116,9 @@ 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(const struct qstr *qstr, struct inode *inode, struct inode *dir);
 #else
-static inline int ext2_init_security(struct inode *inode, struct inode *dir)
+static inline int ext2_init_security(const struct qstr *qstr, struct inode *inode, struct inode *dir)
 {
 	return 0;
 }
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index 3004e15..e06c1c9 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -47,14 +47,14 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
 }
 
 int
-ext2_init_security(struct inode *inode, struct inode *dir)
+ext2_init_security(const struct qstr *qstr, struct inode *inode, struct inode *dir)
 {
 	int err;
 	size_t len;
 	void *value;
 	char *name;
 
-	err = security_inode_init_security(inode, dir, &name, &value, &len);
+	err = security_inode_init_security(qstr, inode, dir, &name, &value, &len);
 	if (err) {
 		if (err == -EOPNOTSUPP)
 			return 0;
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 9724aef..7fb0940 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -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, qstr, inode, dir);
 	if (err)
 		goto fail_free_drop;
 
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index bce9dce..a900033 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -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;
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index 377fe72..7cb86ba 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -127,11 +127,11 @@ exit_ext3_xattr(void)
 # endif  /* CONFIG_EXT3_FS_XATTR */
 
 #ifdef CONFIG_EXT3_FS_SECURITY
-extern int ext3_init_security(handle_t *handle, struct inode *inode,
-				struct inode *dir);
+extern int ext3_init_security(handle_t *handle, const struct qstr *qstr,
+				struct inode *inode, struct inode *dir);
 #else
-static inline int ext3_init_security(handle_t *handle, struct inode *inode,
-				struct inode *dir)
+static inline int ext3_init_security(handle_t *handle, const struct qstr *qstr,
+				struct inode *inode, struct inode *dir)
 {
 	return 0;
 }
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index 03a99bf..c0159b3 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -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, const struct qstr *qstr, struct inode *inode,
+		struct inode *dir)
 {
 	int err;
 	size_t len;
 	void *value;
 	char *name;
 
-	err = security_inode_init_security(inode, dir, &name, &value, &len);
+	err = security_inode_init_security(qstr, inode, dir, &name, &value, &len);
 	if (err) {
 		if (err == -EOPNOTSUPP)
 			return 0;
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 1ce240a..22b7628 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -1042,7 +1042,7 @@ got:
 	if (err)
 		goto fail_free_drop;
 
-	err = ext4_init_security(handle, inode, dir);
+	err = ext4_init_security(handle, qstr, inode, dir);
 	if (err)
 		goto fail_free_drop;
 
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 25f3a97..b0a126f 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -496,7 +496,7 @@ int ext4_ext_migrate(struct inode *inode)
 	goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) *
 		EXT4_INODES_PER_GROUP(inode->i_sb)) + 1;
 	tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
-				   S_IFREG, 0, goal);
+				   S_IFREG, NULL, goal);
 	if (IS_ERR(tmp_inode)) {
 		retval = -ENOMEM;
 		ext4_journal_stop(handle);
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index 1ef1652..93051a9 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -144,11 +144,11 @@ ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
 # endif  /* CONFIG_EXT4_FS_XATTR */
 
 #ifdef CONFIG_EXT4_FS_SECURITY
-extern int ext4_init_security(handle_t *handle, struct inode *inode,
-				struct inode *dir);
+extern int ext4_init_security(handle_t *handle, const struct qstr *qstr,
+				struct inode *inode, struct inode *dir);
 #else
-static inline int ext4_init_security(handle_t *handle, struct inode *inode,
-				struct inode *dir)
+static inline int ext4_init_security(handle_t *handle, const struct qstr *qstr,
+				struct inode *inode, struct inode *dir)
 {
 	return 0;
 }
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index 9b21268..1390ff3 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -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, const struct qstr *qstr, struct inode *inode,
+		struct inode *dir)
 {
 	int err;
 	size_t len;
 	void *value;
 	char *name;
 
-	err = security_inode_init_security(inode, dir, &name, &value, &len);
+	err = security_inode_init_security(qstr, inode, dir, &name, &value, &len);
 	if (err) {
 		if (err == -EOPNOTSUPP)
 			return 0;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index e1213f7..7de62cf 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -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(qstr, &ip->i_inode, &dip->i_inode,
 					   &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;
 
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 9297865..82faddd 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -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;
 
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index 5a53d9b..e4619b0 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -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,
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
index 239f512..ddc389e 100644
--- a/fs/jffs2/security.c
+++ b/fs/jffs2/security.c
@@ -23,14 +23,15 @@
 #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(qstr, inode, dir, &name, &value, &len);
 	if (rc) {
 		if (rc == -EOPNOTSUPP)
 			return 0;
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index c819eb0..ef2e592 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -424,7 +424,7 @@ 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 +466,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 +493,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);
 
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h
index cf4f575..7be4beb 100644
--- a/fs/jffs2/xattr.h
+++ b/fs/jffs2/xattr.h
@@ -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_ */
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h
index 88b6cc5..e9e100f 100644
--- a/fs/jfs/jfs_xattr.h
+++ b/fs/jfs/jfs_xattr.h
@@ -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;
 }
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 231ca4a..ff0fda9 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -114,7 +114,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;
@@ -252,7 +252,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;
@@ -931,7 +931,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;
 
@@ -1394,7 +1394,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;
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 2d7f165..61fbe00 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -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,7 @@ 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(qstr, inode, dir, &suffix, &value, &len);
 	if (rc) {
 		if (rc == -EOPNOTSUPP)
 			return 0;
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index ff5744e..0fc5362 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -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, &si, &dentry->d_name);
 	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, &si, &dentry->d_name);
 	if (status) {
 		if (status == -EOPNOTSUPP)
 			si.enable = 0;
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index b5f9160..cd3f5b4 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -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);
 	}
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 67cd439..429dca6 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -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, &si, qstr);
 	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,
-			    struct ocfs2_security_xattr_info *si)
+			    struct ocfs2_security_xattr_info *si,
+			    const struct qstr *qstr)
 {
 	/* 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(qstr, inode, dir, &si->name,
+					    &si->value, &si->value_len);
 }
 
 int ocfs2_init_security_set(handle_t *handle,
diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h
index aa64bb3..dbb6c53 100644
--- a/fs/ocfs2/xattr.h
+++ b/fs/ocfs2/xattr.h
@@ -57,7 +57,8 @@ 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 *,
-			    struct ocfs2_security_xattr_info *);
+			    struct ocfs2_security_xattr_info *,
+			    const struct qstr *);
 int ocfs2_init_security_set(handle_t *, struct inode *,
 			    struct buffer_head *,
 			    struct ocfs2_security_xattr_info *,
@@ -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 */
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index ba5f51e..df59f3d 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -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, &security, &dentry->d_name);
 	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, &security, &dentry->d_name);
 	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, &security, &dentry->d_name);
 	if (retval < 0) {
 		drop_new_inode(inode);
 		return retval;
@@ -1032,7 +1032,7 @@ 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, &security, &dentry->d_name);
 	if (retval < 0) {
 		drop_new_inode(inode);
 		return retval;
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index 237c692..e8895d4 100644
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -54,7 +54,8 @@ 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,
-			   struct reiserfs_security_handle *sec)
+			   struct reiserfs_security_handle *sec,
+			   const struct qstr *qstr)
 {
 	int blocks = 0;
 	int error;
@@ -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(qstr, inode, dir, &sec->name,
 					     &sec->value, &sec->length);
 	if (error) {
 		if (error == -EOPNOTSUPP)
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 94d5fd6..6baf95c 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -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(qstr, inode, dir, (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;
 
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 6ce1bca..db9691c 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -874,7 +874,7 @@ 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 *);
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
index b2cf208..876dab7 100644
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -63,7 +63,8 @@ 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,
-			   struct reiserfs_security_handle *sec);
+			   struct reiserfs_security_handle *sec,
+			   const struct qstr *qstr);
 int reiserfs_security_write(struct reiserfs_transaction_handle *th,
 			    struct inode *inode,
 			    struct reiserfs_security_handle *sec);
@@ -130,7 +131,8 @@ 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,
-					 struct reiserfs_security_handle *sec)
+					 struct reiserfs_security_handle *sec,
+					 const struct qstr *qstr)
 {
 	return 0;
 }
diff --git a/include/linux/security.h b/include/linux/security.h
index 4ab684e..d42619e 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1436,8 +1436,9 @@ 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);
+	int (*inode_init_security) (const struct qstr *qstr, struct inode *inode,
+				    struct inode *dir, 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,
@@ -1700,8 +1701,9 @@ 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);
+int security_inode_init_security(const struct qstr *qstr, struct inode *inode,
+				 struct inode *dir, 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);
@@ -2026,7 +2028,8 @@ static inline int security_inode_alloc(struct inode *inode)
 static inline void security_inode_free(struct inode *inode)
 { }
 
-static inline int security_inode_init_security(struct inode *inode,
+static inline int security_inode_init_security(const struct qstr *qstr,
+						struct inode *inode,
 						struct inode *dir,
 						char **name,
 						void **value,
diff --git a/mm/shmem.c b/mm/shmem.c
index 47fdeeb..06aa3cf 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1843,8 +1843,8 @@ 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(&dentry->d_name, inode,
+						     dir, NULL, NULL, NULL);
 		if (error) {
 			if (error != -EOPNOTSUPP) {
 				iput(inode);
@@ -1983,8 +1983,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(&dentry->d_name, inode, dir, NULL,
+					     NULL, NULL);
 	if (error) {
 		if (error != -EOPNOTSUPP) {
 			iput(inode);
diff --git a/security/capability.c b/security/capability.c
index 92a1bff..778a28f 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -117,8 +117,9 @@ 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)
+static int cap_inode_init_security(const struct qstr *qstr, struct inode *inode,
+				   struct inode *dir, char **name, void **value,
+				   size_t *len)
 {
 	return -EOPNOTSUPP;
 }
diff --git a/security/security.c b/security/security.c
index 799239d..639a72a 100644
--- a/security/security.c
+++ b/security/security.c
@@ -335,12 +335,14 @@ void security_inode_free(struct inode *inode)
 	security_ops->inode_free_security(inode);
 }
 
-int security_inode_init_security(struct inode *inode, struct inode *dir,
-				  char **name, void **value, size_t *len)
+int security_inode_init_security(const struct qstr *qstr, struct inode *inode,
+				 struct inode *dir, 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(qstr, inode, dir, name, value,
+						 len);
 }
 EXPORT_SYMBOL(security_inode_init_security);
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b8dcd05..609e8d3 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -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>
@@ -2508,9 +2509,8 @@ static void selinux_inode_free_security(struct inode *inode)
 	inode_free_security(inode);
 }
 
-static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
-				       char **name, void **value,
-				       size_t *len)
+static int selinux_inode_init_security(const struct qstr *qstr, struct inode *inode,
+			struct inode *dir, char **name, void **value, size_t *len)
 {
 	const struct task_security_struct *tsec = current_security();
 	struct inode_security_struct *dsec;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 489a85a..f4794e9 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -31,6 +31,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))
@@ -430,8 +431,9 @@ 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)
+static int smack_inode_init_security(const struct qstr *qstr, struct inode *inode,
+				     struct inode *dir, char **name, void **value,
+				     size_t *len)
 {
 	char *isp = smk_of_inode(inode);
 


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH 2/2] SELinux: Use dentry name in new object labeling
  2010-12-03 21:45 [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation Eric Paris
@ 2010-12-03 21:45 ` Eric Paris
  2010-12-04  4:20 ` [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation Casey Schaufler
  1 sibling, 0 replies; 16+ messages in thread
From: Eric Paris @ 2010-12-03 21:45 UTC (permalink / raw)
  To: selinux; +Cc: eparis, sds, jmorris, linux-security-module, viro, hch

Currently SELinux has rules which label new objects according to 3 criteria.
The label of the process creating the object, the label of the parent
directory, and the type of object (reg, dir, char, block, etc.)  This patch
adds a 4th criteria, the dentry name, thus we can distinguish between
creating a file in an etc_t directory called shadow and one called motd.

There is no file globbing, regex parsing, or anything mystical.  Either the
policy exactly (strcmp) matches the dentry name of the object or it doesn't.
This patch has no changes from today if policy does not implement the new
rules.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 security/selinux/hooks.c            |   15 ++--
 security/selinux/include/security.h |    8 +-
 security/selinux/ss/avtab.h         |   22 +++---
 security/selinux/ss/policydb.c      |  130 +++++++++++++++++++++++++++++++++++
 security/selinux/ss/policydb.h      |   14 ++++
 security/selinux/ss/services.c      |   45 ++++++++----
 6 files changed, 197 insertions(+), 37 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 609e8d3..98e3497 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1301,10 +1301,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
 
 		/* Try to obtain a transition SID. */
 		isec->sclass = inode_mode_to_security_class(inode->i_mode);
-		rc = security_transition_sid(isec->task_sid,
-					     sbsec->sid,
-					     isec->sclass,
-					     &sid);
+		rc = security_transition_sid(isec->task_sid, sbsec->sid,
+					     isec->sclass, NULL, &sid);
 		if (rc)
 			goto out_unlock;
 		isec->sid = sid;
@@ -1579,7 +1577,7 @@ static int may_create(struct inode *dir,
 		return rc;
 
 	if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
-		rc = security_transition_sid(sid, dsec->sid, tclass, &newsid);
+		rc = security_transition_sid(sid, dsec->sid, tclass, NULL, &newsid);
 		if (rc)
 			return rc;
 	}
@@ -2061,7 +2059,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
 	} else {
 		/* Check for a default transition on this program. */
 		rc = security_transition_sid(old_tsec->sid, isec->sid,
-					     SECCLASS_PROCESS, &new_tsec->sid);
+					     SECCLASS_PROCESS, NULL,
+					     &new_tsec->sid);
 		if (rc)
 			return rc;
 	}
@@ -2531,7 +2530,7 @@ static int selinux_inode_init_security(const struct qstr *qstr, struct inode *in
 	else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
 		rc = security_transition_sid(sid, dsec->sid,
 					     inode_mode_to_security_class(inode->i_mode),
-					     &newsid);
+					     qstr, &newsid);
 		if (rc) {
 			printk(KERN_WARNING "%s:  "
 			       "security_transition_sid failed, rc=%d (dev=%s "
@@ -4855,7 +4854,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
 		 * message queue this message will be stored in
 		 */
 		rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG,
-					     &msec->sid);
+					     NULL, &msec->sid);
 		if (rc)
 			return rc;
 	}
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 671273e..348eb00 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -8,6 +8,7 @@
 #ifndef _SELINUX_SECURITY_H_
 #define _SELINUX_SECURITY_H_
 
+#include <linux/dcache.h>
 #include <linux/magic.h>
 #include <linux/types.h>
 #include "flask.h"
@@ -28,13 +29,14 @@
 #define POLICYDB_VERSION_POLCAP		22
 #define POLICYDB_VERSION_PERMISSIVE	23
 #define POLICYDB_VERSION_BOUNDARY	24
+#define POLICYDB_VERSION_FILENAME_TRANS	25
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_BOUNDARY
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_FILENAME_TRANS
 #endif
 
 /* Mask for just the mount related flags */
@@ -106,8 +108,8 @@ void security_compute_av(u32 ssid, u32 tsid,
 void security_compute_av_user(u32 ssid, u32 tsid,
 			     u16 tclass, struct av_decision *avd);
 
-int security_transition_sid(u32 ssid, u32 tsid,
-			    u16 tclass, u32 *out_sid);
+int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
+			    const struct qstr *qstr, u32 *out_sid);
 
 int security_transition_sid_user(u32 ssid, u32 tsid,
 				 u16 tclass, u32 *out_sid);
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index dff0c75..39aae08 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -14,7 +14,7 @@
  *
  * Copyright (C) 2003 Tresys Technology, LLC
  *	This program is free software; you can redistribute it and/or modify
- *  	it under the terms of the GNU General Public License as published by
+ *	it under the terms of the GNU General Public License as published by
  *	the Free Software Foundation, version 2.
  *
  * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp>
@@ -27,16 +27,16 @@ struct avtab_key {
 	u16 source_type;	/* source type */
 	u16 target_type;	/* target type */
 	u16 target_class;	/* target object class */
-#define AVTAB_ALLOWED     1
-#define AVTAB_AUDITALLOW  2
-#define AVTAB_AUDITDENY   4
-#define AVTAB_AV         (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY)
-#define AVTAB_TRANSITION 16
-#define AVTAB_MEMBER     32
-#define AVTAB_CHANGE     64
-#define AVTAB_TYPE       (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
-#define AVTAB_ENABLED_OLD    0x80000000 /* reserved for used in cond_avtab */
-#define AVTAB_ENABLED    0x8000 /* reserved for used in cond_avtab */
+#define AVTAB_ALLOWED		0x0001
+#define AVTAB_AUDITALLOW	0x0002
+#define AVTAB_AUDITDENY		0x0004
+#define AVTAB_AV		(AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY)
+#define AVTAB_TRANSITION	0x0010
+#define AVTAB_MEMBER		0x0020
+#define AVTAB_CHANGE		0x0040
+#define AVTAB_TYPE		(AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
+#define AVTAB_ENABLED_OLD   0x80000000 /* reserved for used in cond_avtab */
+#define AVTAB_ENABLED		0x8000 /* reserved for used in cond_avtab */
 	u16 specified;	/* what field is specified */
 };
 
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index be9de38..159c818 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -123,6 +123,11 @@ static struct policydb_compat_info policydb_compat[] = {
 		.sym_num	= SYM_NUM,
 		.ocon_num	= OCON_NUM,
 	},
+	{
+		.version	= POLICYDB_VERSION_FILENAME_TRANS,
+		.sym_num	= SYM_NUM,
+		.ocon_num	= OCON_NUM,
+	},
 };
 
 static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -704,6 +709,7 @@ void policydb_destroy(struct policydb *p)
 	int i;
 	struct role_allow *ra, *lra = NULL;
 	struct role_trans *tr, *ltr = NULL;
+	struct filename_trans *ft, *nft;
 
 	for (i = 0; i < SYM_NUM; i++) {
 		cond_resched();
@@ -781,6 +787,15 @@ void policydb_destroy(struct policydb *p)
 		}
 		flex_array_free(p->type_attr_map_array);
 	}
+
+	ft = p->filename_trans;
+	while (ft) {
+		nft = ft->next;
+		kfree(ft->name);
+		kfree(ft);
+		ft = nft;
+	}
+
 	ebitmap_destroy(&p->policycaps);
 	ebitmap_destroy(&p->permissive_map);
 
@@ -1788,6 +1803,76 @@ out:
 	return rc;
 }
 
+static int filename_trans_read(struct policydb *p, void *fp)
+{
+	struct filename_trans *ft, *last;
+	u32 nel, len;
+	char *name;
+	__le32 buf[4];
+	int rc, i;
+
+	if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
+		return 0;
+
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc)
+		goto out;
+	nel = le32_to_cpu(buf[0]);
+
+	printk(KERN_ERR "%s: nel=%d\n", __func__, nel);
+
+	last = p->filename_trans;
+	while (last && last->next)
+		last = last->next;
+
+	for (i = 0; i < nel; i++) {
+		rc = -ENOMEM;
+		ft = kzalloc(sizeof(*ft), GFP_KERNEL);
+		if (!ft)
+			goto out;
+
+		/* add it to the tail of the list */
+		if (!last)
+			p->filename_trans = ft;
+		else
+			last->next = ft;
+		last = ft;
+
+		/* length of the path component string */
+		rc = next_entry(buf, fp, sizeof(u32));
+		if (rc)
+			goto out;
+		len = le32_to_cpu(buf[0]);
+
+		rc = -ENOMEM;
+		name = kmalloc(len + 1, GFP_KERNEL);
+		if (!name)
+			goto out;
+
+		ft->name = name;
+
+		/* path component string */
+		rc = next_entry(name, fp, len);
+		if (rc)
+			goto out;
+		name[len] = 0;
+
+		printk(KERN_ERR "%s: ft=%p ft->name=%p ft->name=%s\n", __func__, ft, ft->name, ft->name);
+
+		rc = next_entry(buf, fp, sizeof(u32) * 4);
+		if (rc)
+			goto out;
+
+		ft->stype = le32_to_cpu(buf[0]);
+		ft->ttype = le32_to_cpu(buf[1]);
+		ft->tclass = le32_to_cpu(buf[2]);
+		ft->otype = le32_to_cpu(buf[3]);
+	}
+	rc = 0;
+out:
+	return rc;
+}
+
 static int genfs_read(struct policydb *p, void *fp)
 {
 	int i, j, rc;
@@ -2251,6 +2336,10 @@ int policydb_read(struct policydb *p, void *fp)
 		lra = ra;
 	}
 
+	rc = filename_trans_read(p, fp);
+	if (rc)
+		goto bad;
+
 	rc = policydb_index(p);
 	if (rc)
 		goto bad;
@@ -3025,6 +3114,43 @@ static int range_write(struct policydb *p, void *fp)
 	return 0;
 }
 
+static int filename_trans_write(struct policydb *p, void *fp)
+{
+	struct filename_trans *ft;
+	u32 len, nel = 0;
+	__le32 buf[4];
+	int rc;
+
+	for (ft = p->filename_trans; ft; ft = ft->next)
+		nel++;
+
+	buf[0] = cpu_to_le32(nel);
+	rc = put_entry(buf, sizeof(u32), 1, fp);
+	if (rc)
+		return rc;
+
+	for (ft = p->filename_trans; ft; ft = ft->next) {
+		len = strlen(ft->name);
+		buf[0] = cpu_to_le32(len);
+		rc = put_entry(buf, sizeof(u32), 1, fp);
+		if (rc)
+			return rc;
+
+		rc = put_entry(ft->name, sizeof(char), len, fp);
+		if (rc)
+			return rc;
+
+		buf[0] = ft->stype;
+		buf[1] = ft->ttype;
+		buf[2] = ft->tclass;
+		buf[3] = ft->otype;
+
+		rc = put_entry(buf, sizeof(u32), 4, fp);
+		if (rc)
+			return rc;
+	}
+	return 0;
+}
 /*
  * Write the configuration data in a policy database
  * structure to a policy database binary representation
@@ -3135,6 +3261,10 @@ int policydb_write(struct policydb *p, void *fp)
 	if (rc)
 		return rc;
 
+	rc = filename_trans_write(p, fp);
+	if (rc)
+		return rc;
+
 	rc = ocontext_write(p, info, fp);
 	if (rc)
 		return rc;
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 4e3ab9d..732ea4a 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -77,6 +77,15 @@ struct role_trans {
 	struct role_trans *next;
 };
 
+struct filename_trans {
+	struct filename_trans *next;
+	u32 stype;		/* current process */
+	u32 ttype;		/* parent dir context */
+	u16 tclass;		/* class of new object */
+	const char *name;	/* last path component */
+	u32 otype;		/* expected of new object */
+};
+
 struct role_allow {
 	u32 role;		/* current role */
 	u32 new_role;		/* new role */
@@ -217,6 +226,9 @@ struct policydb {
 	/* role transitions */
 	struct role_trans *role_tr;
 
+	/* file transitions with the last path component */
+	struct filename_trans *filename_trans;
+
 	/* bools indexed by (value - 1) */
 	struct cond_bool_datum **bool_val_to_struct;
 	/* type enforcement conditional access vectors and transitions */
@@ -302,7 +314,7 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
 	return 0;
 }
 
-static inline int put_entry(void *buf, size_t bytes, int num, struct policy_file *fp)
+static inline int put_entry(const void *buf, size_t bytes, int num, struct policy_file *fp)
 {
 	size_t len = bytes * num;
 
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index a03cfaf..2e36e03 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1343,10 +1343,27 @@ out:
 	return -EACCES;
 }
 
+static void filename_compute_type(struct policydb *p, struct context *newcontext,
+				  u32 scon, u32 tcon, u16 tclass,
+				  const struct qstr *qstr)
+{
+	struct filename_trans *ft;
+	for (ft = p->filename_trans; ft; ft = ft->next) {
+		if (ft->stype == scon &&
+		    ft->ttype == tcon &&
+		    ft->tclass == tclass &&
+		    !strcmp(ft->name, qstr->name)) {
+			newcontext->type = ft->otype;
+			return;
+		}
+	}
+}
+
 static int security_compute_sid(u32 ssid,
 				u32 tsid,
 				u16 orig_tclass,
 				u32 specified,
+				const struct qstr *qstr,
 				u32 *out_sid,
 				bool kern)
 {
@@ -1442,6 +1459,11 @@ static int security_compute_sid(u32 ssid,
 		newcontext.type = avdatum->data;
 	}
 
+	/* if we have a qstr this is a file trans check so check those rules */
+	if (qstr)
+		filename_compute_type(&policydb, &newcontext, scontext->type,
+				      tcontext->type, tclass, qstr);
+
 	/* Check for class-specific changes. */
 	if  (tclass == policydb.process_class) {
 		if (specified & AVTAB_TRANSITION) {
@@ -1495,22 +1517,17 @@ out:
  * if insufficient memory is available, or %0 if the new SID was
  * computed successfully.
  */
-int security_transition_sid(u32 ssid,
-			    u32 tsid,
-			    u16 tclass,
-			    u32 *out_sid)
+int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
+			    const struct qstr *qstr, u32 *out_sid)
 {
 	return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
-				    out_sid, true);
+				    qstr, out_sid, true);
 }
 
-int security_transition_sid_user(u32 ssid,
-				 u32 tsid,
-				 u16 tclass,
-				 u32 *out_sid)
+int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
 {
 	return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
-				    out_sid, false);
+				    NULL, out_sid, false);
 }
 
 /**
@@ -1531,8 +1548,8 @@ int security_member_sid(u32 ssid,
 			u16 tclass,
 			u32 *out_sid)
 {
-	return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid,
-				    false);
+	return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, NULL,
+				    out_sid, false);
 }
 
 /**
@@ -1553,8 +1570,8 @@ int security_change_sid(u32 ssid,
 			u16 tclass,
 			u32 *out_sid)
 {
-	return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid,
-				    false);
+	return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL,
+				    out_sid, false);
 }
 
 /* Clone the SID into the new SID table. */


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-03 21:45 [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation Eric Paris
  2010-12-03 21:45 ` [RFC PATCH 2/2] SELinux: Use dentry name in new object labeling Eric Paris
@ 2010-12-04  4:20 ` Casey Schaufler
  2010-12-04 21:34   ` Eric Paris
  1 sibling, 1 reply; 16+ messages in thread
From: Casey Schaufler @ 2010-12-04  4:20 UTC (permalink / raw)
  To: Eric Paris
  Cc: selinux, sds, jmorris, linux-security-module, viro, hch, Casey Schaufler

On 12/3/2010 1:45 PM, Eric Paris wrote:
> 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.

I see. Pathname based controls. In SELinux.

> This is very useful because creating /etc/shadow is different than creating
> /etc/passwd but the kernel hooks are unable to differentiate these
> operations.

If I recall correctly, this has been the Apparmor/TOMOYO argument all along.

> We currently require that userspace realize it is doing some
> difficult operation like that and that userspace jump 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.

Why can't you use the existing pathname hooks?

If you want pathname based behavior there are already two perfectly good
LSMs that do that. Why do we need a third? Especially when the people who
run SELinux have been so adamant that name based access controls have no
place in the kernel?

Sure, you're just talking about the final component, but that's because
you've already done user space labeling of the entire file system and are
counting on standardized directory structures. Let's face it, outside the
context of a specific distribution and an SELinux policy tailored to that
distribution, final component name based controls do not have any kind of
generality.

If you really have seen the light and believe that pathname based access
controls have merit a scheme that is half based on labels and half based
on final components can't possibly seem satisfactory.

Or am I missing something?


> Signed-off-by: Eric Paris <eparis@redhat.com>
> ---
>
>  fs/btrfs/inode.c               |   11 ++++++-----
>  fs/btrfs/xattr.c               |    3 ++-
>  fs/btrfs/xattr.h               |    1 +
>  fs/ext2/ext2.h                 |    2 +-
>  fs/ext2/ialloc.c               |    4 ++--
>  fs/ext2/namei.c                |    8 ++++----
>  fs/ext2/xattr.h                |    4 ++--
>  fs/ext2/xattr_security.c       |    4 ++--
>  fs/ext3/ialloc.c               |    5 +++--
>  fs/ext3/namei.c                |    8 ++++----
>  fs/ext3/xattr.h                |    8 ++++----
>  fs/ext3/xattr_security.c       |    5 +++--
>  fs/ext4/ialloc.c               |    2 +-
>  fs/ext4/migrate.c              |    2 +-
>  fs/ext4/xattr.h                |    8 ++++----
>  fs/ext4/xattr_security.c       |    5 +++--
>  fs/gfs2/inode.c                |    7 ++++---
>  fs/jffs2/dir.c                 |    9 ++++-----
>  fs/jffs2/nodelist.h            |    2 +-
>  fs/jffs2/security.c            |    5 +++--
>  fs/jffs2/write.c               |   16 ++++++++--------
>  fs/jffs2/xattr.h               |    5 +++--
>  fs/jfs/jfs_xattr.h             |    5 +++--
>  fs/jfs/namei.c                 |    8 ++++----
>  fs/jfs/xattr.c                 |    5 +++--
>  fs/ocfs2/namei.c               |    4 ++--
>  fs/ocfs2/refcounttree.c        |    3 ++-
>  fs/ocfs2/xattr.c               |   12 +++++++-----
>  fs/ocfs2/xattr.h               |    6 ++++--
>  fs/reiserfs/namei.c            |    8 ++++----
>  fs/reiserfs/xattr_security.c   |    5 +++--
>  fs/xfs/linux-2.6/xfs_iops.c    |    9 +++++----
>  include/linux/ext3_fs.h        |    2 +-
>  include/linux/reiserfs_xattr.h |    6 ++++--
>  include/linux/security.h       |   13 ++++++++-----
>  mm/shmem.c                     |    8 ++++----
>  security/capability.c          |    5 +++--
>  security/security.c            |    8 +++++---
>  security/selinux/hooks.c       |    6 +++---
>  security/smack/smack_lsm.c     |    6 ++++--
>  40 files changed, 135 insertions(+), 108 deletions(-)
>
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index 8039390..7a993ad 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -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,
> +				     const struct qstr *qstr,
>  				     struct inode *inode,  struct inode *dir)
>  {
>  	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, qstr, inode, dir);
>  	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, &dentry->d_name, inode, dir);
>  	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, &dentry->d_name, inode, dir);
>  	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, &dentry->d_name, inode, dir);
>  	if (err)
>  		goto out_fail;
>  
> @@ -6940,7 +6941,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, &dentry->d_name, inode, dir);
>  	if (err) {
>  		drop_inode = 1;
>  		goto out_unlock;
> diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
> index 698fdd2..7e9dd88 100644
> --- a/fs/btrfs/xattr.c
> +++ b/fs/btrfs/xattr.c
> @@ -352,6 +352,7 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
>  }
>  
>  int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
> +			      const struct qstr *qstr,
>  			      struct inode *inode, struct inode *dir)
>  {
>  	int err;
> @@ -360,7 +361,7 @@ 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(qstr, inode, dir, &suffix, &value, &len);
>  	if (err) {
>  		if (err == -EOPNOTSUPP)
>  			return 0;
> diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h
> index 7a43fd6..1e1d9b0 100644
> --- a/fs/btrfs/xattr.h
> +++ b/fs/btrfs/xattr.h
> @@ -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,
> +				     const struct qstr *qstr,
>  				     struct inode *inode, struct inode *dir);
>  
>  #endif /* __XATTR__ */
> diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
> index 6346a2a..1b48c33 100644
> --- a/fs/ext2/ext2.h
> +++ b/fs/ext2/ext2.h
> @@ -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 *);
> diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
> index ad70479..5be2348 100644
> --- a/fs/ext2/ialloc.c
> +++ b/fs/ext2/ialloc.c
> @@ -429,7 +429,7 @@ 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 +585,7 @@ got:
>  	if (err)
>  		goto fail_free_drop;
>  
> -	err = ext2_init_security(inode,dir);
> +	err = ext2_init_security(qstr, inode, dir);
>  	if (err)
>  		goto fail_free_drop;
>  
> diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
> index f8aecd2..368d704 100644
> --- a/fs/ext2/namei.c
> +++ b/fs/ext2/namei.c
> @@ -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;
> diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h
> index a1a1c21..7460429 100644
> --- a/fs/ext2/xattr.h
> +++ b/fs/ext2/xattr.h
> @@ -116,9 +116,9 @@ 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(const struct qstr *qstr, struct inode *inode, struct inode *dir);
>  #else
> -static inline int ext2_init_security(struct inode *inode, struct inode *dir)
> +static inline int ext2_init_security(const struct qstr *qstr, struct inode *inode, struct inode *dir)
>  {
>  	return 0;
>  }
> diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
> index 3004e15..e06c1c9 100644
> --- a/fs/ext2/xattr_security.c
> +++ b/fs/ext2/xattr_security.c
> @@ -47,14 +47,14 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
>  }
>  
>  int
> -ext2_init_security(struct inode *inode, struct inode *dir)
> +ext2_init_security(const struct qstr *qstr, struct inode *inode, struct inode *dir)
>  {
>  	int err;
>  	size_t len;
>  	void *value;
>  	char *name;
>  
> -	err = security_inode_init_security(inode, dir, &name, &value, &len);
> +	err = security_inode_init_security(qstr, inode, dir, &name, &value, &len);
>  	if (err) {
>  		if (err == -EOPNOTSUPP)
>  			return 0;
> diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
> index 9724aef..7fb0940 100644
> --- a/fs/ext3/ialloc.c
> +++ b/fs/ext3/ialloc.c
> @@ -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, qstr, inode, dir);
>  	if (err)
>  		goto fail_free_drop;
>  
> diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
> index bce9dce..a900033 100644
> --- a/fs/ext3/namei.c
> +++ b/fs/ext3/namei.c
> @@ -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;
> diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
> index 377fe72..7cb86ba 100644
> --- a/fs/ext3/xattr.h
> +++ b/fs/ext3/xattr.h
> @@ -127,11 +127,11 @@ exit_ext3_xattr(void)
>  # endif  /* CONFIG_EXT3_FS_XATTR */
>  
>  #ifdef CONFIG_EXT3_FS_SECURITY
> -extern int ext3_init_security(handle_t *handle, struct inode *inode,
> -				struct inode *dir);
> +extern int ext3_init_security(handle_t *handle, const struct qstr *qstr,
> +				struct inode *inode, struct inode *dir);
>  #else
> -static inline int ext3_init_security(handle_t *handle, struct inode *inode,
> -				struct inode *dir)
> +static inline int ext3_init_security(handle_t *handle, const struct qstr *qstr,
> +				struct inode *inode, struct inode *dir)
>  {
>  	return 0;
>  }
> diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
> index 03a99bf..c0159b3 100644
> --- a/fs/ext3/xattr_security.c
> +++ b/fs/ext3/xattr_security.c
> @@ -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, const struct qstr *qstr, struct inode *inode,
> +		struct inode *dir)
>  {
>  	int err;
>  	size_t len;
>  	void *value;
>  	char *name;
>  
> -	err = security_inode_init_security(inode, dir, &name, &value, &len);
> +	err = security_inode_init_security(qstr, inode, dir, &name, &value, &len);
>  	if (err) {
>  		if (err == -EOPNOTSUPP)
>  			return 0;
> diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
> index 1ce240a..22b7628 100644
> --- a/fs/ext4/ialloc.c
> +++ b/fs/ext4/ialloc.c
> @@ -1042,7 +1042,7 @@ got:
>  	if (err)
>  		goto fail_free_drop;
>  
> -	err = ext4_init_security(handle, inode, dir);
> +	err = ext4_init_security(handle, qstr, inode, dir);
>  	if (err)
>  		goto fail_free_drop;
>  
> diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
> index 25f3a97..b0a126f 100644
> --- a/fs/ext4/migrate.c
> +++ b/fs/ext4/migrate.c
> @@ -496,7 +496,7 @@ int ext4_ext_migrate(struct inode *inode)
>  	goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) *
>  		EXT4_INODES_PER_GROUP(inode->i_sb)) + 1;
>  	tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
> -				   S_IFREG, 0, goal);
> +				   S_IFREG, NULL, goal);
>  	if (IS_ERR(tmp_inode)) {
>  		retval = -ENOMEM;
>  		ext4_journal_stop(handle);
> diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
> index 1ef1652..93051a9 100644
> --- a/fs/ext4/xattr.h
> +++ b/fs/ext4/xattr.h
> @@ -144,11 +144,11 @@ ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
>  # endif  /* CONFIG_EXT4_FS_XATTR */
>  
>  #ifdef CONFIG_EXT4_FS_SECURITY
> -extern int ext4_init_security(handle_t *handle, struct inode *inode,
> -				struct inode *dir);
> +extern int ext4_init_security(handle_t *handle, const struct qstr *qstr,
> +				struct inode *inode, struct inode *dir);
>  #else
> -static inline int ext4_init_security(handle_t *handle, struct inode *inode,
> -				struct inode *dir)
> +static inline int ext4_init_security(handle_t *handle, const struct qstr *qstr,
> +				struct inode *inode, struct inode *dir)
>  {
>  	return 0;
>  }
> diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
> index 9b21268..1390ff3 100644
> --- a/fs/ext4/xattr_security.c
> +++ b/fs/ext4/xattr_security.c
> @@ -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, const struct qstr *qstr, struct inode *inode,
> +		struct inode *dir)
>  {
>  	int err;
>  	size_t len;
>  	void *value;
>  	char *name;
>  
> -	err = security_inode_init_security(inode, dir, &name, &value, &len);
> +	err = security_inode_init_security(qstr, inode, dir, &name, &value, &len);
>  	if (err) {
>  		if (err == -EOPNOTSUPP)
>  			return 0;
> diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
> index e1213f7..7de62cf 100644
> --- a/fs/gfs2/inode.c
> +++ b/fs/gfs2/inode.c
> @@ -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(qstr, &ip->i_inode, &dip->i_inode,
>  					   &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;
>  
> diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
> index 9297865..82faddd 100644
> --- a/fs/jffs2/dir.c
> +++ b/fs/jffs2/dir.c
> @@ -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;
>  
> diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
> index 5a53d9b..e4619b0 100644
> --- a/fs/jffs2/nodelist.h
> +++ b/fs/jffs2/nodelist.h
> @@ -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,
> diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
> index 239f512..ddc389e 100644
> --- a/fs/jffs2/security.c
> +++ b/fs/jffs2/security.c
> @@ -23,14 +23,15 @@
>  #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(qstr, inode, dir, &name, &value, &len);
>  	if (rc) {
>  		if (rc == -EOPNOTSUPP)
>  			return 0;
> diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
> index c819eb0..ef2e592 100644
> --- a/fs/jffs2/write.c
> +++ b/fs/jffs2/write.c
> @@ -424,7 +424,7 @@ 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 +466,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 +493,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);
>  
> diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h
> index cf4f575..7be4beb 100644
> --- a/fs/jffs2/xattr.h
> +++ b/fs/jffs2/xattr.h
> @@ -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_ */
> diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h
> index 88b6cc5..e9e100f 100644
> --- a/fs/jfs/jfs_xattr.h
> +++ b/fs/jfs/jfs_xattr.h
> @@ -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;
>  }
> diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
> index 231ca4a..ff0fda9 100644
> --- a/fs/jfs/namei.c
> +++ b/fs/jfs/namei.c
> @@ -114,7 +114,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;
> @@ -252,7 +252,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;
> @@ -931,7 +931,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;
>  
> @@ -1394,7 +1394,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;
> diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
> index 2d7f165..61fbe00 100644
> --- a/fs/jfs/xattr.c
> +++ b/fs/jfs/xattr.c
> @@ -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,7 @@ 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(qstr, inode, dir, &suffix, &value, &len);
>  	if (rc) {
>  		if (rc == -EOPNOTSUPP)
>  			return 0;
> diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
> index ff5744e..0fc5362 100644
> --- a/fs/ocfs2/namei.c
> +++ b/fs/ocfs2/namei.c
> @@ -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, &si, &dentry->d_name);
>  	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, &si, &dentry->d_name);
>  	if (status) {
>  		if (status == -EOPNOTSUPP)
>  			si.enable = 0;
> diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
> index b5f9160..cd3f5b4 100644
> --- a/fs/ocfs2/refcounttree.c
> +++ b/fs/ocfs2/refcounttree.c
> @@ -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);
>  	}
> diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
> index 67cd439..429dca6 100644
> --- a/fs/ocfs2/xattr.c
> +++ b/fs/ocfs2/xattr.c
> @@ -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, &si, qstr);
>  	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,
> -			    struct ocfs2_security_xattr_info *si)
> +			    struct ocfs2_security_xattr_info *si,
> +			    const struct qstr *qstr)
>  {
>  	/* 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(qstr, inode, dir, &si->name,
> +					    &si->value, &si->value_len);
>  }
>  
>  int ocfs2_init_security_set(handle_t *handle,
> diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h
> index aa64bb3..dbb6c53 100644
> --- a/fs/ocfs2/xattr.h
> +++ b/fs/ocfs2/xattr.h
> @@ -57,7 +57,8 @@ 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 *,
> -			    struct ocfs2_security_xattr_info *);
> +			    struct ocfs2_security_xattr_info *,
> +			    const struct qstr *);
>  int ocfs2_init_security_set(handle_t *, struct inode *,
>  			    struct buffer_head *,
>  			    struct ocfs2_security_xattr_info *,
> @@ -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 */
> diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
> index ba5f51e..df59f3d 100644
> --- a/fs/reiserfs/namei.c
> +++ b/fs/reiserfs/namei.c
> @@ -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, &security, &dentry->d_name);
>  	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, &security, &dentry->d_name);
>  	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, &security, &dentry->d_name);
>  	if (retval < 0) {
>  		drop_new_inode(inode);
>  		return retval;
> @@ -1032,7 +1032,7 @@ 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, &security, &dentry->d_name);
>  	if (retval < 0) {
>  		drop_new_inode(inode);
>  		return retval;
> diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
> index 237c692..e8895d4 100644
> --- a/fs/reiserfs/xattr_security.c
> +++ b/fs/reiserfs/xattr_security.c
> @@ -54,7 +54,8 @@ 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,
> -			   struct reiserfs_security_handle *sec)
> +			   struct reiserfs_security_handle *sec,
> +			   const struct qstr *qstr)
>  {
>  	int blocks = 0;
>  	int error;
> @@ -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(qstr, inode, dir, &sec->name,
>  					     &sec->value, &sec->length);
>  	if (error) {
>  		if (error == -EOPNOTSUPP)
> diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
> index 94d5fd6..6baf95c 100644
> --- a/fs/xfs/linux-2.6/xfs_iops.c
> +++ b/fs/xfs/linux-2.6/xfs_iops.c
> @@ -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(qstr, inode, dir, (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;
>  
> diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
> index 6ce1bca..db9691c 100644
> --- a/include/linux/ext3_fs.h
> +++ b/include/linux/ext3_fs.h
> @@ -874,7 +874,7 @@ 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 *);
> diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
> index b2cf208..876dab7 100644
> --- a/include/linux/reiserfs_xattr.h
> +++ b/include/linux/reiserfs_xattr.h
> @@ -63,7 +63,8 @@ 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,
> -			   struct reiserfs_security_handle *sec);
> +			   struct reiserfs_security_handle *sec,
> +			   const struct qstr *qstr);
>  int reiserfs_security_write(struct reiserfs_transaction_handle *th,
>  			    struct inode *inode,
>  			    struct reiserfs_security_handle *sec);
> @@ -130,7 +131,8 @@ 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,
> -					 struct reiserfs_security_handle *sec)
> +					 struct reiserfs_security_handle *sec,
> +					 const struct qstr *qstr)
>  {
>  	return 0;
>  }
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 4ab684e..d42619e 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -1436,8 +1436,9 @@ 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);
> +	int (*inode_init_security) (const struct qstr *qstr, struct inode *inode,
> +				    struct inode *dir, 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,
> @@ -1700,8 +1701,9 @@ 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);
> +int security_inode_init_security(const struct qstr *qstr, struct inode *inode,
> +				 struct inode *dir, 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);
> @@ -2026,7 +2028,8 @@ static inline int security_inode_alloc(struct inode *inode)
>  static inline void security_inode_free(struct inode *inode)
>  { }
>  
> -static inline int security_inode_init_security(struct inode *inode,
> +static inline int security_inode_init_security(const struct qstr *qstr,
> +						struct inode *inode,
>  						struct inode *dir,
>  						char **name,
>  						void **value,
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 47fdeeb..06aa3cf 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -1843,8 +1843,8 @@ 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(&dentry->d_name, inode,
> +						     dir, NULL, NULL, NULL);
>  		if (error) {
>  			if (error != -EOPNOTSUPP) {
>  				iput(inode);
> @@ -1983,8 +1983,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(&dentry->d_name, inode, dir, NULL,
> +					     NULL, NULL);
>  	if (error) {
>  		if (error != -EOPNOTSUPP) {
>  			iput(inode);
> diff --git a/security/capability.c b/security/capability.c
> index 92a1bff..778a28f 100644
> --- a/security/capability.c
> +++ b/security/capability.c
> @@ -117,8 +117,9 @@ 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)
> +static int cap_inode_init_security(const struct qstr *qstr, struct inode *inode,
> +				   struct inode *dir, char **name, void **value,
> +				   size_t *len)
>  {
>  	return -EOPNOTSUPP;
>  }
> diff --git a/security/security.c b/security/security.c
> index 799239d..639a72a 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -335,12 +335,14 @@ void security_inode_free(struct inode *inode)
>  	security_ops->inode_free_security(inode);
>  }
>  
> -int security_inode_init_security(struct inode *inode, struct inode *dir,
> -				  char **name, void **value, size_t *len)
> +int security_inode_init_security(const struct qstr *qstr, struct inode *inode,
> +				 struct inode *dir, 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(qstr, inode, dir, name, value,
> +						 len);
>  }
>  EXPORT_SYMBOL(security_inode_init_security);
>  
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index b8dcd05..609e8d3 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -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>
> @@ -2508,9 +2509,8 @@ static void selinux_inode_free_security(struct inode *inode)
>  	inode_free_security(inode);
>  }
>  
> -static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
> -				       char **name, void **value,
> -				       size_t *len)
> +static int selinux_inode_init_security(const struct qstr *qstr, struct inode *inode,
> +			struct inode *dir, char **name, void **value, size_t *len)
>  {
>  	const struct task_security_struct *tsec = current_security();
>  	struct inode_security_struct *dsec;
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 489a85a..f4794e9 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -31,6 +31,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))
> @@ -430,8 +431,9 @@ 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)
> +static int smack_inode_init_security(const struct qstr *qstr, struct inode *inode,
> +				     struct inode *dir, char **name, void **value,
> +				     size_t *len)
>  {
>  	char *isp = smk_of_inode(inode);
>  
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-04  4:20 ` [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation Casey Schaufler
@ 2010-12-04 21:34   ` Eric Paris
  2010-12-05  7:38     ` Casey Schaufler
  0 siblings, 1 reply; 16+ messages in thread
From: Eric Paris @ 2010-12-04 21:34 UTC (permalink / raw)
  To: Casey Schaufler, penguin-kernel
  Cc: selinux, sds, jmorris, linux-security-module, viro, hch

On Fri, 2010-12-03 at 20:20 -0800, Casey Schaufler wrote:
> On 12/3/2010 1:45 PM, Eric Paris wrote:
> > 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.
> 
> I see. Pathname based controls. In SELinux.

Actually you of (almost) all people shouldn't make this mistake.  There
is absolutely no pathname based controls being implemented.  This is an
extension of the object labeling model to facilitate and simply some
userspace issues related to the labeling of NEW objects.  SELinux very
much so is and will continue to be based solely on label based controls.
The intention is to remove some particularly gross userspace hacks
related to new object labeling (read udev/restorecond/anything to do
with /var/run, etc).  It simplifies userspace, removes numerous races,
and does so with no reduction in security (and theoretically the
possibility of a more secure system)

> > This is very useful because creating /etc/shadow is different than creating
> > /etc/passwd but the kernel hooks are unable to differentiate these
> > operations.
> 
> If I recall correctly, this has been the Apparmor/TOMOYO argument all along.

They are similar arguments but not at all the same.  Some people may not
understand the distinction between the initial labeling an object and
access controls.  If that distinction is not clear to anyone please let
me know.  They talk about access controls based on the name.  I'm only
talking about new object labeling.

> > We currently require that userspace realize it is doing some
> > difficult operation like that and that userspace jump 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.
> 
> Why can't you use the existing pathname hooks?

Because the pathname hooks are about pathname based access controls,
which I contend for both philosophical and technical reasons are not
appropriate.  Discussed more later.

> If you want pathname based behavior there are already two perfectly good
> LSMs that do that. Why do we need a third? Especially when the people who
> run SELinux have been so adamant that name based access controls have no
> place in the kernel?

Good thing I'm not adding name based access controls   :)

> Sure, you're just talking about the final component, but that's because
> you've already done user space labeling of the entire file system and are
> counting on standardized directory structures. Let's face it, outside the
> context of a specific distribution and an SELinux policy tailored to that
> distribution, final component name based controls do not have any kind of
> generality.

It's true that a relatively standard directory and naming structure is
helpful in getting the refpolicy to work.  But the tweaks to get SELinux
running on a new distro (assuming it uses PAM, sorry slackware) should
not huge.  If anything your argument is against pathname based systems,
not against label based LSMs or the patch in question.  I'm not sure
what point you were trying to make here.

> If you really have seen the light and believe that pathname based access
> controls have merit a scheme that is half based on labels and half based
> on final components can't possibly seem satisfactory.

Sadly I'm both still living in the dark and I agree with that statement
completely.  Pathname based access controls are not the best and a
hybrid model is no better.  

> Or am I missing something?

You are (and I'm guessing rather intentionally :-P)

[next message explains my thoughts]

On Sat, 2010-12-04 at 17:01 +0900, Tetsuo Handa wrote:
> /etc/shadow as an absolute pathname makes special meaning but etc_t + shadow
> does not always make special meaning. Using "struct dentry" instead of
> "struct qstr" is not sufficient, for it would be sufficient for /etc/shadow
> case because /etc/ directory is known to be within / partition but it is not
> sufficient for /etc/foo/etc/shadow case because /etc/foo/ directory is not
> always within / partition. Assigning shadow_t when creating /etc/foo/etc/shadow
> (where the pathname derived from "struct dentry" is /etc/shadow) is wrong.

(I should start by saying that there will likely never be a rule related
to /etc/shadow since it is rarely a newly created object, but I'm
willing to use it as my example, since most people reasonably understand
the security implications of it.)

You actually point out exactly the flaw of pathname based security, not
a problem with my new object labeling extension.  If the program
responsible for creating /etc/shadow is able to be tricked into
creating /etc/foo/shadow instead, that file is still going to contain
passwords and information that should be protected just like /etc/shadow
needs to be protected.  It's irrelevant if the pathname is wrong.  It's
about the data and the integrity/confidentiality of the data.  If that
file contains password data (or at least what something/someone thought
was password data) it should be protected exactly the same as the real
one.  We are at diametrically opposed view points on this and I doubt we
ever come to agree.  This patch makes no changes to SELinux in that
regard and I don't see such a change in the future.

I don't understand some of your logic (why does /etc have to be on the
same partition as /?  How can a useful struct dentry, much less a struct
path [I assume you meant path rather than vfsmount], exist before the
struct inode?) but those parts seem irrelevant.  Pathname based security
is (at least in my view) fundamentally flawed if you want to make real
security claims.  Label based security can make real guarantees (ok
Casey insert you snide comment about how SELinux policy is so large its
hard->impossible to analyze/make claims) but when implemented on
flexible systems (as opposed to to static systems such as those used in
3 letter gov't agencies) labeling is hard to do and this change makes it
easier.

Let me give some examples of where I plan to actually use this new
behavior.

devtmpfs/udev:  currently devtmpfs creates new char and block files
'magically' in /dev.  It does so with the label device_t because it
can't possibly know better.  It then calls up to hotplug, which call
udev, which does a pathname based check in userspace, and resets the
label to something better.  How horrific is that?  With this patch the
kernel can tell that mem != console and can just do the right thing,
race free.  'Really secure' installations don't use devtmpfs/udev and
instead have static premade /dev with proper labeling (yeah MAKEDEV!).
I'm fine if you are crazy enough to do that, but I'd rather live in the
modern world with tools that just work.

/var/run:  Lots of programs used to (and many still do) create files
directly in /var/run/.  We in the fedora land have urged packages to
use /var/run/[package name] because it made labeling easier to get
right.  This is SELinux forcing it's way of life onto userspace.
Something we would rather avoid if it's possible to automate.

~/.ssh:  When a user or even sshd creates the ~/.ssh directory the
kernel doesn't realize that this is different than creating the
directory "Downloads."  How do we solve that today?  We have a program
that puts an inotify watch on ~/.ssh when you log in and which will, as
fast as it can, relabel that directory to the correct label.  How much
crap is that?

SELinux from Red Hat out of the box (I can't speak definitely for not RH
based distros) fails on one of the major tenets of its own security
model.  It fails at label tranquility (aka once an object is labeled
that label never changes).  We have things which automatically and
dynamically relabel existing objects (I just mentioned two of them.)
I'd like to remove both of those exceptions, simplify userspace
applications, and in doing so bring the flexibility of a real usable
dynamic system to the security of one which meets something closer to a
statically labeled system....

Make sense?

-Eric


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-04 21:34   ` Eric Paris
@ 2010-12-05  7:38     ` Casey Schaufler
  2010-12-06 14:32       ` Daniel J Walsh
                         ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Casey Schaufler @ 2010-12-05  7:38 UTC (permalink / raw)
  To: Eric Paris
  Cc: penguin-kernel, selinux, sds, jmorris, linux-security-module,
	viro, hch, Casey Schaufler

On 12/4/2010 1:34 PM, Eric Paris wrote:
> On Fri, 2010-12-03 at 20:20 -0800, Casey Schaufler wrote:
>> On 12/3/2010 1:45 PM, Eric Paris wrote:
>>> 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.
>> I see. Pathname based controls. In SELinux.
> Actually you of (almost) all people shouldn't make this mistake.

Sorry Eric, but if it looks like a duck, quacks like a duck, and
bites like a duck it's a good bet that what you have is a duck.
Better get out the Grand Mariner and start on a sauce.

> There
> is absolutely no pathname based controls being implemented.  This is an
> extension of the object labeling model to facilitate and simply some
> userspace issues related to the labeling of NEW objects.  

The end to which the controls are put does not change the character
of those controls. If the attribute of the file being used is the
name component of the name/inode pair in a directory entry than what
you have is a pathname based control mechanism. It will have all of
the downsides, including mount points and hard links, that any other
name based scheme will suffer from.

> SELinux very
> much so is and will continue to be based solely on label based controls.

I'm not sure that I buy that. The very presence of restorecond, which
sets labels based strictly on pathnames, begs the observer to question
whether an SELinux system (e.g. a RedHat distribution) can be truly
said to be strictly label based. Yes, individual access control decisions
are made based on the combination of the policy and the labels, but
with the suggested changes it becomes very difficult to distinguish the
enforcement of the kernel (e.g. creating "passwd" in a etc_t directory)
where restorecond is assumed to have set "/etc" to etc_t from checking
the same access rights on a file that happens to be named "/etc/passwd".
Yes, the kernel component of SELinux relies strictly on the labels,
but the reality is that SELinux is heavily dependent on the user space
component to maintain the proper labels on files so that the specified
policy is rational.

> The intention is to remove some particularly gross userspace hacks
> related to new object labeling (read udev/restorecond/anything to do
> with /var/run, etc).  It simplifies userspace, removes numerous races,
> and does so with no reduction in security (and theoretically the
> possibility of a more secure system)

These "userspace hacks" are no "worse" than restorecond from a
security perspective. They have the unpleasant characteristic that
they are outside the control of the primary distributor of SELinux.
I will admit that the suggested changes will make SELinux better.
That does not make them any less pathname based.


>>> This is very useful because creating /etc/shadow is different than creating
>>> /etc/passwd but the kernel hooks are unable to differentiate these
>>> operations.
>> If I recall correctly, this has been the Apparmor/TOMOYO argument all along.
> They are similar arguments but not at all the same.  Some people may not
> understand the distinction between the initial labeling an object and
> access controls.  If that distinction is not clear to anyone please let
> me know.  They talk about access controls based on the name.  I'm only
> talking about new object labeling.

Initial labeling of objects is critical. There is no point in
talking about the access control decision if you can't say good
things about how the label gets set initially.

>>> We currently require that userspace realize it is doing some
>>> difficult operation like that and that userspace jump 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.
>> Why can't you use the existing pathname hooks?
> Because the pathname hooks are about pathname based access controls,
> which I contend for both philosophical and technical reasons are not
> appropriate.  Discussed more later.

Sigh. Argued more later.

>> If you want pathname based behavior there are already two perfectly good
>> LSMs that do that. Why do we need a third? Especially when the people who
>> run SELinux have been so adamant that name based access controls have no
>> place in the kernel?
> Good thing I'm not adding name based access controls   :)

I contend that you are, but as always I am willing to learn
why it is I am wrong.

>> Sure, you're just talking about the final component, but that's because
>> you've already done user space labeling of the entire file system and are
>> counting on standardized directory structures. Let's face it, outside the
>> context of a specific distribution and an SELinux policy tailored to that
>> distribution, final component name based controls do not have any kind of
>> generality.
> It's true that a relatively standard directory and naming structure is
> helpful in getting the refpolicy to work.  But the tweaks to get SELinux
> running on a new distro (assuming it uses PAM, sorry slackware) should
> not huge.  If anything your argument is against pathname based systems,
> not against label based LSMs or the patch in question.  I'm not sure
> what point you were trying to make here.

My point is roughly centered around the distinction between a Linux
kernel with SELinux configured and a policy installed and an SELinux
system with the aforementioned and a complete SELinux runtime that
includes goodies like restorecond. The former is strictly label based,
while the latter is definitely not. I really think that you should
leave the name based bits in userspace unless you are willing to
accept their general value in the kernel.

>> If you really have seen the light and believe that pathname based access
>> controls have merit a scheme that is half based on labels and half based
>> on final components can't possibly seem satisfactory.
> Sadly I'm both still living in the dark and I agree with that statement
> completely.  Pathname based access controls are not the best and a
> hybrid model is no better.  

I'm not saying that darkness is inherently wrong, but I am suggesting
that blindness is a condition that ought to be corrected where
possible. If you want to bring some of what is awkward to do in
userspace into the kernel that is fine, but I tend to view things
from a simplistic viewpoint, and if the attribute you're using is the
name of the thing I have to say that the mechanism you're using is
name based.

>> Or am I missing something?
> You are (and I'm guessing rather intentionally :-P)

OK, yes, there is some attempt at irony in my first response.
If you wanted to you could find some bits of Smack (look in
smack_d_instantiate if you're in a hurry) that could be considered
at least as questionable.

I don't see a significant difference from a security standpoint
between creating "shadow" in a etc_t directory and creating
"/etc/shadow", because "everyone knows" that "/etc" gets etc_t,
and the userspace tools enforce it.

> [next message explains my thoughts]
>
> On Sat, 2010-12-04 at 17:01 +0900, Tetsuo Handa wrote:
>> /etc/shadow as an absolute pathname makes special meaning but etc_t + shadow
>> does not always make special meaning. Using "struct dentry" instead of
>> "struct qstr" is not sufficient, for it would be sufficient for /etc/shadow
>> case because /etc/ directory is known to be within / partition but it is not
>> sufficient for /etc/foo/etc/shadow case because /etc/foo/ directory is not
>> always within / partition. Assigning shadow_t when creating /etc/foo/etc/shadow
>> (where the pathname derived from "struct dentry" is /etc/shadow) is wrong.
> (I should start by saying that there will likely never be a rule related
> to /etc/shadow since it is rarely a newly created object, but I'm
> willing to use it as my example, since most people reasonably understand
> the security implications of it.)
>
> You actually point out exactly the flaw of pathname based security, not
> a problem with my new object labeling extension.  If the program
> responsible for creating /etc/shadow is able to be tricked into
> creating /etc/foo/shadow instead, that file is still going to contain
> passwords and information that should be protected just like /etc/shadow
> needs to be protected.  

> It's irrelevant if the pathname is wrong.  

Well, no, that's not true. The data will not be available to its
legitimate consumers if it is created in /etc/foo/shadow, even if
/etc/foo is (somehow) labeled etc_t.

> It's
> about the data and the integrity/confidentiality of the data.  

This is also true, but it is not the only concern. If a /etc/foo
is on removable media the integrity and confidentiality, as defined
by the label of /etc/foo, is not going to mean all that much.

> If that
> file contains password data (or at least what something/someone thought
> was password data) it should be protected exactly the same as the real
> one.  We are at diametrically opposed view points on this and I doubt we
> ever come to agree.  This patch makes no changes to SELinux in that
> regard and I don't see such a change in the future.

No, the bulk of the pathname based controls of an SELinux distribution
are done in userspace. The SELinux kernel does not currently care.
That's fine. I suggest that all the pathname based behavior of SELinux
stay in the userspace components.

> I don't understand some of your logic (why does /etc have to be on the
> same partition as /?  How can a useful struct dentry, much less a struct
> path [I assume you meant path rather than vfsmount], exist before the
> struct inode?) but those parts seem irrelevant.  Pathname based security
> is (at least in my view) fundamentally flawed if you want to make real
> security claims.  Label based security can make real guarantees (ok
> Casey insert you snide comment about how SELinux policy is so large its
> hard->impossible to analyze/make claims) but when implemented on
> flexible systems (as opposed to to static systems such as those used in
> 3 letter gov't agencies) labeling is hard to do and this change makes it
> easier.
>
> Let me give some examples of where I plan to actually use this new
> behavior.
>
> devtmpfs/udev:  currently devtmpfs creates new char and block files
> 'magically' in /dev.  It does so with the label device_t because it
> can't possibly know better.  It then calls up to hotplug, which call
> udev, which does a pathname based check in userspace, and resets the
> label to something better.  How horrific is that?  With this patch the
> kernel can tell that mem != console and can just do the right thing,
> race free.  'Really secure' installations don't use devtmpfs/udev and
> instead have static premade /dev with proper labeling (yeah MAKEDEV!).
> I'm fine if you are crazy enough to do that, but I'd rather live in the
> modern world with tools that just work.
>
> /var/run:  Lots of programs used to (and many still do) create files
> directly in /var/run/.  We in the fedora land have urged packages to
> use /var/run/[package name] because it made labeling easier to get
> right.  This is SELinux forcing it's way of life onto userspace.
> Something we would rather avoid if it's possible to automate.
>
> ~/.ssh:  When a user or even sshd creates the ~/.ssh directory the
> kernel doesn't realize that this is different than creating the
> directory "Downloads."  How do we solve that today?  We have a program
> that puts an inotify watch on ~/.ssh when you log in and which will, as
> fast as it can, relabel that directory to the correct label.  How much
> crap is that?

You could fix these applications. That's the right thing to do.
I didn't say it's easy, just that its right.

> SELinux from Red Hat out of the box (I can't speak definitely for not RH
> based distros) fails on one of the major tenets of its own security
> model.  It fails at label tranquility (aka once an object is labeled
> that label never changes).  We have things which automatically and
> dynamically relabel existing objects (I just mentioned two of them.)
> I'd like to remove both of those exceptions, simplify userspace
> applications, and in doing so bring the flexibility of a real usable
> dynamic system to the security of one which meets something closer to a
> statically labeled system....
>
> Make sense?

Sure, but if it is a duck ...

> -Eric

BTW: I'm not saying your goals are bad, but I do question the
implementation. It really looks like the pathname hooks are your
easiest and most correct approach.

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-05  7:38     ` Casey Schaufler
@ 2010-12-06 14:32       ` Daniel J Walsh
  2010-12-06 23:32       ` Kyle Moffett
  2010-12-07 13:43       ` Stephen Smalley
  2 siblings, 0 replies; 16+ messages in thread
From: Daniel J Walsh @ 2010-12-06 14:32 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Eric Paris, penguin-kernel, selinux, sds, jmorris,
	linux-security-module, viro, hch

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 12/05/2010 02:38 AM, Casey Schaufler wrote:
> On 12/4/2010 1:34 PM, Eric Paris wrote:
>> On Fri, 2010-12-03 at 20:20 -0800, Casey Schaufler wrote:
>>> On 12/3/2010 1:45 PM, Eric Paris wrote:
>>>> 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.
>>> I see. Pathname based controls. In SELinux.
>> Actually you of (almost) all people shouldn't make this mistake.
> 
> Sorry Eric, but if it looks like a duck, quacks like a duck, and
> bites like a duck it's a good bet that what you have is a duck.
> Better get out the Grand Mariner and start on a sauce.
> 
>> There
>> is absolutely no pathname based controls being implemented.  This is an
>> extension of the object labeling model to facilitate and simply some
>> userspace issues related to the labeling of NEW objects.  
> 
> The end to which the controls are put does not change the character
> of those controls. If the attribute of the file being used is the
> name component of the name/inode pair in a directory entry than what
> you have is a pathname based control mechanism. It will have all of
> the downsides, including mount points and hard links, that any other
> name based scheme will suffer from.
> 
>> SELinux very
>> much so is and will continue to be based solely on label based controls.
> 
> I'm not sure that I buy that. The very presence of restorecond, which
> sets labels based strictly on pathnames, begs the observer to question
> whether an SELinux system (e.g. a RedHat distribution) can be truly
> said to be strictly label based. Yes, individual access control decisions
> are made based on the combination of the policy and the labels, but
> with the suggested changes it becomes very difficult to distinguish the
> enforcement of the kernel (e.g. creating "passwd" in a etc_t directory)
> where restorecond is assumed to have set "/etc" to etc_t from checking
> the same access rights on a file that happens to be named "/etc/passwd".
> Yes, the kernel component of SELinux relies strictly on the labels,
> but the reality is that SELinux is heavily dependent on the user space
> component to maintain the proper labels on files so that the specified
> policy is rational.
> 
>> The intention is to remove some particularly gross userspace hacks
>> related to new object labeling (read udev/restorecond/anything to do
>> with /var/run, etc).  It simplifies userspace, removes numerous races,
>> and does so with no reduction in security (and theoretically the
>> possibility of a more secure system)
> 
> These "userspace hacks" are no "worse" than restorecond from a
> security perspective. They have the unpleasant characteristic that
> they are outside the control of the primary distributor of SELinux.
> I will admit that the suggested changes will make SELinux better.
> That does not make them any less pathname based.
> 
> 
>>>> This is very useful because creating /etc/shadow is different than creating
>>>> /etc/passwd but the kernel hooks are unable to differentiate these
>>>> operations.
>>> If I recall correctly, this has been the Apparmor/TOMOYO argument all along.
>> They are similar arguments but not at all the same.  Some people may not
>> understand the distinction between the initial labeling an object and
>> access controls.  If that distinction is not clear to anyone please let
>> me know.  They talk about access controls based on the name.  I'm only
>> talking about new object labeling.
> 
> Initial labeling of objects is critical. There is no point in
> talking about the access control decision if you can't say good
> things about how the label gets set initially.
> 
>>>> We currently require that userspace realize it is doing some
>>>> difficult operation like that and that userspace jump 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.
>>> Why can't you use the existing pathname hooks?
>> Because the pathname hooks are about pathname based access controls,
>> which I contend for both philosophical and technical reasons are not
>> appropriate.  Discussed more later.
> 
> Sigh. Argued more later.
> 
>>> If you want pathname based behavior there are already two perfectly good
>>> LSMs that do that. Why do we need a third? Especially when the people who
>>> run SELinux have been so adamant that name based access controls have no
>>> place in the kernel?
>> Good thing I'm not adding name based access controls   :)
> 
> I contend that you are, but as always I am willing to learn
> why it is I am wrong.
> 
>>> Sure, you're just talking about the final component, but that's because
>>> you've already done user space labeling of the entire file system and are
>>> counting on standardized directory structures. Let's face it, outside the
>>> context of a specific distribution and an SELinux policy tailored to that
>>> distribution, final component name based controls do not have any kind of
>>> generality.
>> It's true that a relatively standard directory and naming structure is
>> helpful in getting the refpolicy to work.  But the tweaks to get SELinux
>> running on a new distro (assuming it uses PAM, sorry slackware) should
>> not huge.  If anything your argument is against pathname based systems,
>> not against label based LSMs or the patch in question.  I'm not sure
>> what point you were trying to make here.
> 
> My point is roughly centered around the distinction between a Linux
> kernel with SELinux configured and a policy installed and an SELinux
> system with the aforementioned and a complete SELinux runtime that
> includes goodies like restorecond. The former is strictly label based,
> while the latter is definitely not. I really think that you should
> leave the name based bits in userspace unless you are willing to
> accept their general value in the kernel.
> 
>>> If you really have seen the light and believe that pathname based access
>>> controls have merit a scheme that is half based on labels and half based
>>> on final components can't possibly seem satisfactory.
>> Sadly I'm both still living in the dark and I agree with that statement
>> completely.  Pathname based access controls are not the best and a
>> hybrid model is no better.  
> 
> I'm not saying that darkness is inherently wrong, but I am suggesting
> that blindness is a condition that ought to be corrected where
> possible. If you want to bring some of what is awkward to do in
> userspace into the kernel that is fine, but I tend to view things
> from a simplistic viewpoint, and if the attribute you're using is the
> name of the thing I have to say that the mechanism you're using is
> name based.
> 
>>> Or am I missing something?
>> You are (and I'm guessing rather intentionally :-P)
> 
> OK, yes, there is some attempt at irony in my first response.
> If you wanted to you could find some bits of Smack (look in
> smack_d_instantiate if you're in a hurry) that could be considered
> at least as questionable.
> 
> I don't see a significant difference from a security standpoint
> between creating "shadow" in a etc_t directory and creating
> "/etc/shadow", because "everyone knows" that "/etc" gets etc_t,
> and the userspace tools enforce it.
> 
>> [next message explains my thoughts]
>>
>> On Sat, 2010-12-04 at 17:01 +0900, Tetsuo Handa wrote:
>>> /etc/shadow as an absolute pathname makes special meaning but etc_t + shadow
>>> does not always make special meaning. Using "struct dentry" instead of
>>> "struct qstr" is not sufficient, for it would be sufficient for /etc/shadow
>>> case because /etc/ directory is known to be within / partition but it is not
>>> sufficient for /etc/foo/etc/shadow case because /etc/foo/ directory is not
>>> always within / partition. Assigning shadow_t when creating /etc/foo/etc/shadow
>>> (where the pathname derived from "struct dentry" is /etc/shadow) is wrong.
>> (I should start by saying that there will likely never be a rule related
>> to /etc/shadow since it is rarely a newly created object, but I'm
>> willing to use it as my example, since most people reasonably understand
>> the security implications of it.)
>>
>> You actually point out exactly the flaw of pathname based security, not
>> a problem with my new object labeling extension.  If the program
>> responsible for creating /etc/shadow is able to be tricked into
>> creating /etc/foo/shadow instead, that file is still going to contain
>> passwords and information that should be protected just like /etc/shadow
>> needs to be protected.  
> 
>> It's irrelevant if the pathname is wrong.  
> 
> Well, no, that's not true. The data will not be available to its
> legitimate consumers if it is created in /etc/foo/shadow, even if
> /etc/foo is (somehow) labeled etc_t.
> 
>> It's
>> about the data and the integrity/confidentiality of the data.  
> 
> This is also true, but it is not the only concern. If a /etc/foo
> is on removable media the integrity and confidentiality, as defined
> by the label of /etc/foo, is not going to mean all that much.
> 
>> If that
>> file contains password data (or at least what something/someone thought
>> was password data) it should be protected exactly the same as the real
>> one.  We are at diametrically opposed view points on this and I doubt we
>> ever come to agree.  This patch makes no changes to SELinux in that
>> regard and I don't see such a change in the future.
> 
> No, the bulk of the pathname based controls of an SELinux distribution
> are done in userspace. The SELinux kernel does not currently care.
> That's fine. I suggest that all the pathname based behavior of SELinux
> stay in the userspace components.
> 
>> I don't understand some of your logic (why does /etc have to be on the
>> same partition as /?  How can a useful struct dentry, much less a struct
>> path [I assume you meant path rather than vfsmount], exist before the
>> struct inode?) but those parts seem irrelevant.  Pathname based security
>> is (at least in my view) fundamentally flawed if you want to make real
>> security claims.  Label based security can make real guarantees (ok
>> Casey insert you snide comment about how SELinux policy is so large its
>> hard->impossible to analyze/make claims) but when implemented on
>> flexible systems (as opposed to to static systems such as those used in
>> 3 letter gov't agencies) labeling is hard to do and this change makes it
>> easier.
>>
>> Let me give some examples of where I plan to actually use this new
>> behavior.
>>
>> devtmpfs/udev:  currently devtmpfs creates new char and block files
>> 'magically' in /dev.  It does so with the label device_t because it
>> can't possibly know better.  It then calls up to hotplug, which call
>> udev, which does a pathname based check in userspace, and resets the
>> label to something better.  How horrific is that?  With this patch the
>> kernel can tell that mem != console and can just do the right thing,
>> race free.  'Really secure' installations don't use devtmpfs/udev and
>> instead have static premade /dev with proper labeling (yeah MAKEDEV!).
>> I'm fine if you are crazy enough to do that, but I'd rather live in the
>> modern world with tools that just work.
>>
>> /var/run:  Lots of programs used to (and many still do) create files
>> directly in /var/run/.  We in the fedora land have urged packages to
>> use /var/run/[package name] because it made labeling easier to get
>> right.  This is SELinux forcing it's way of life onto userspace.
>> Something we would rather avoid if it's possible to automate.
>>
>> ~/.ssh:  When a user or even sshd creates the ~/.ssh directory the
>> kernel doesn't realize that this is different than creating the
>> directory "Downloads."  How do we solve that today?  We have a program
>> that puts an inotify watch on ~/.ssh when you log in and which will, as
>> fast as it can, relabel that directory to the correct label.  How much
>> crap is that?
> 
> You could fix these applications. That's the right thing to do.
> I didn't say it's easy, just that its right.
> 
>> SELinux from Red Hat out of the box (I can't speak definitely for not RH
>> based distros) fails on one of the major tenets of its own security
>> model.  It fails at label tranquility (aka once an object is labeled
>> that label never changes).  We have things which automatically and
>> dynamically relabel existing objects (I just mentioned two of them.)
>> I'd like to remove both of those exceptions, simplify userspace
>> applications, and in doing so bring the flexibility of a real usable
>> dynamic system to the security of one which meets something closer to a
>> statically labeled system....
>>
>> Make sense?
> 
> Sure, but if it is a duck ...
> 
>> -Eric
> 
> BTW: I'm not saying your goals are bad, but I do question the
> implementation. It really looks like the pathname hooks are your
> easiest and most correct approach.
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
> 
> 


I really don't want to get into this that deeply, but I want to end a
couple of misconceptions.  restorecond the init service has not been run
by default in several releases on Fedora, and does not run by default on
RHEL6.  I am not sure if it does on RHEL5.

If you run it, it only watches these files.

/etc/services
/etc/resolv.conf
/etc/samba/secrets.tdb
/etc/mtab
/var/run/utmp
/var/log/wtmp
/root/*
/root/.ssh/*

Most of these were added do to either bugs in rpm post install scripts
(vmware) bugs in policy, or admins constantly screwing up when creating
files.  Most of these are historical and not needed any longer.

I have added a userspace restorecond in Fedora 12-14 and RHEL6 that
watches for the user creating files in his home dir.  Expecting users to
understand SELinux and to set the labels correctly so system services
will work, just does not work.

Lately we have been seeing more and more race condition avcs where the
kernel creates a device in /dev and udev does not fix it quick enough
before an AVC is generated.  Bluetooth seems to get hit by this a lot.

SELinux has always been partially path based.  You need a way to get
initial labels onto the disk, and the enforcement is Inode based.  You
are just adding a new way to get the labels on disk.  Either through
RPM, Udevd, fixfiles, restorecon, restorecond.

Eric is just giving a new tool to the policy writer that he can use to
get initial labels on disk.  The only place I would envision using this
to start would be for /dev and maybe /root and ~/.

We can sit here and argue about what is pragmatic to do.  I have always
cared about usability and what every I can do, to make the system more
usable without lowering security I am looking to do.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAkz89BEACgkQrlYvE4MpobMbigCg6HShTT0SAv+TLTMC22XVxjFE
2ZcAn21EIp6dmn2YmyUh4PJZ2ptg2W+X
=1HpR
-----END PGP SIGNATURE-----

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-05  7:38     ` Casey Schaufler
  2010-12-06 14:32       ` Daniel J Walsh
@ 2010-12-06 23:32       ` Kyle Moffett
  2010-12-07 13:43       ` Stephen Smalley
  2 siblings, 0 replies; 16+ messages in thread
From: Kyle Moffett @ 2010-12-06 23:32 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Eric Paris, penguin-kernel, selinux, sds, jmorris,
	linux-security-module, viro, hch

On Sun, Dec 5, 2010 at 02:38, Casey Schaufler <casey@schaufler-ca.com> wrote:
> On 12/4/2010 1:34 PM, Eric Paris wrote:
>> SELinux very
>> much so is and will continue to be based solely on label based controls.
>
> I'm not sure that I buy that. The very presence of restorecond, which
> sets labels based strictly on pathnames, begs the observer to question
> whether an SELinux system (e.g. a RedHat distribution) can be truly
> said to be strictly label based. Yes, individual access control decisions
> are made based on the combination of the policy and the labels, but
> with the suggested changes it becomes very difficult to distinguish the
> enforcement of the kernel (e.g. creating "passwd" in a etc_t directory)
> where restorecond is assumed to have set "/etc" to etc_t from checking
> the same access rights on a file that happens to be named "/etc/passwd".
> Yes, the kernel component of SELinux relies strictly on the labels,
> but the reality is that SELinux is heavily dependent on the user space
> component to maintain the proper labels on files so that the specified
> policy is rational.

I believe this is a limitation of the current policy structure that
could completely go away with support for last-component matching.

Now, there is *always* a relatively complex set of assumptions that
the policy itself makes about the userspace environment.  For example,
the policy must assume that the "passwd" tool does not allow
unprivileged users to change *other* users passwords.  It must assume
that the "login" tool actually performs proper authentication, etc.
The policy can only assume that programs called "login" or "password"
in the various system binary directories conform to these
requirements.

Userspace itself is very *thoroughly* dependent on specific file
names, "sh", "sed", "awk", "passwd", "mkfs"... the list goes on for
many pages.  In most cases, though it does NOT care *where* in $PATH
the tool is located, and that frequently varies across Linux
distributions.  Any comprehensive least-privilege security policy
truly needs to take this into account.


> I don't see a significant difference from a security standpoint
> between creating "shadow" in a etc_t directory and creating
> "/etc/shadow", because "everyone knows" that "/etc" gets etc_t,
> and the userspace tools enforce it.

The difference is in the complexity of other tasks, such as
".htaccess" files, where they are created not just in a single
directory, but in a whole directory hierarchy.  From a performance
standpoint I would much rather have a rule that says: [create
".htaccess" in an www_t directory as "www_htaccess_t"] plus a few to
prohibit hardlinks to and from ".htaccess" files, as opposed to a
bunch of rules using paths like: "/var/www/**/.htaccess"

The latter case also results in absolutely *ridiculous* duplication of
rules when I suddenly decide to put other web-site files in other
places: "/srv/mirror/ftp.example.com/pub".

>> You actually point out exactly the flaw of pathname based security, not
>> a problem with my new object labeling extension.  If the program
>> responsible for creating /etc/shadow is able to be tricked into
>> creating /etc/foo/shadow instead, that file is still going to contain
>> passwords and information that should be protected just like /etc/shadow
>> needs to be protected.
>
>> It's irrelevant if the pathname is wrong.
>
> Well, no, that's not true. The data will not be available to its
> legitimate consumers if it is created in /etc/foo/shadow, even if
> /etc/foo is (somehow) labeled etc_t.
>
>> It's
>> about the data and the integrity/confidentiality of the data.
>
> This is also true, but it is not the only concern. If a /etc/foo
> is on removable media the integrity and confidentiality, as defined
> by the label of /etc/foo, is not going to mean all that much.

If you're concerned about shadow confidentiality in that way then you
should not have a rule that says "allow shadow_t filesystem:associate
removable_filesystem_t" or similar.  That would prevent you from
creating a shadow_t file on a removable_filesystem_t even if the root
directory of the FS was labelled etc_t.


>> /var/run:  Lots of programs used to (and many still do) create files
>> directly in /var/run/.  We in the fedora land have urged packages to
>> use /var/run/[package name] because it made labeling easier to get
>> right.  This is SELinux forcing it's way of life onto userspace.
>> Something we would rather avoid if it's possible to automate.
>>
>> ~/.ssh:  When a user or even sshd creates the ~/.ssh directory the
>> kernel doesn't realize that this is different than creating the
>> directory "Downloads."  How do we solve that today?  We have a program
>> that puts an inotify watch on ~/.ssh when you log in and which will, as
>> fast as it can, relabel that directory to the correct label.  How much
>> crap is that?
>
> You could fix these applications. That's the right thing to do.
> I didn't say it's easy, just that its right.

No... in general... you *can't* just "fix" those applications.  Did
you even spend a minute to think about the ".ssh" example?  To add a
bit more detail... when I log into a freshly installed system over a
serial console one of the first things I do as root is:
  mkdir .ssh && cat >.ssh/authorized_keys

Then I copy and paste my public key into the terminal, then hit
Ctrl-D.  Any conceivable way of "fixing" that would introduce horrors
into "bash" and "coreutils" that would get you on their developer's
killfiles for life!  The whole point of having plain-text config files
is that they can be easily mucked about with by an administrator using
"cat", "sed", and "vi".


> BTW: I'm not saying your goals are bad, but I do question the
> implementation. It really looks like the pathname hooks are your
> easiest and most correct approach.

If I recall that doesn't work because several of the path-based hooks
are in different places from the inode-based hooks.  Specifically,
current SELinux hooks are always called *after* all of the DAC-based
checks, versus the path-based hooks which need a vfsmount parameter
only available *before* the DAC-based checks; if you changed this you
would cause a whole bunch of new audit false positives.

Cheers,
Kyle Moffett


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-05  7:38     ` Casey Schaufler
  2010-12-06 14:32       ` Daniel J Walsh
  2010-12-06 23:32       ` Kyle Moffett
@ 2010-12-07 13:43       ` Stephen Smalley
  2010-12-07 14:58         ` Casey Schaufler
  2 siblings, 1 reply; 16+ messages in thread
From: Stephen Smalley @ 2010-12-07 13:43 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Eric Paris, penguin-kernel, selinux, sds, jmorris,
	linux-security-module, viro, hch

On Sun, Dec 5, 2010 at 2:38 AM, Casey Schaufler <casey@schaufler-ca.com> wrote:
> The end to which the controls are put does not change the character
> of those controls. If the attribute of the file being used is the
> name component of the name/inode pair in a directory entry than what
> you have is a pathname based control mechanism. It will have all of
> the downsides, including mount points and hard links, that any other
> name based scheme will suffer from.

I think this is a misunderstanding.
The mechanism that Eric is proposing (which btw is something that has
long since been discussed among the SELinux developers and agreed to
in principle, so this is not a point of contention among SELinux
developers) is to allow the last component name of a newly created
file to be used as an optional additional input into the decision
logic for computing the new label of that inode.  You can already use
the security contexts of the creating process and the parent directory
along with the type of file (security class) as inputs into that
logic, so this merely adds one additional factor that can be leveraged
by policy writers.  It is only used as an input when the file is
created (file access is still based solely on its previously
determined security context) and namespace manipulation has no effect
on it (creating a hard link to the file does not involve this logic,
nor does renaming it nor mounting the containing filesystem
elsewhere).

> These "userspace hacks" are no "worse" than restorecond from a
> security perspective. They have the unpleasant characteristic that
> they are outside the control of the primary distributor of SELinux.
> I will admit that the suggested changes will make SELinux better.
> That does not make them any less pathname based.

I don't follow this logic.  restorecond and udev relabeling of
kernel-created dev nodes are inherently racy - the file is not created
in the desired security context initially, and must be relabeled by
some userspace component that notices that the file has been created.
Kernel support for incorporating the last component name as an
additional input enables us to label certain files correctly upon
creation and thus avoids that problem entirely.  And as for being
outside the control of a given distributor, I think that is both a
fallacy (it is no harder to replace or extend userspace than it is to
replace/extend policy) and irrelevant.

> Initial labeling of objects is critical. There is no point in
> talking about the access control decision if you can't say good
> things about how the label gets set initially.

That's true, and precisely why this is beneficial - it gives us an
additional input to use when labeling objects initially that improves
our accuracy of labeling at file creation time.  BTW, this isn't as
novel to SELinux as you seem to think.  That fact that we are already
using the parent directory context as an input in computing the
security context of a new files means that our file labeling logic is
already "path-based" in a certain sense.  It isn't solely path-based
(either before or after this change), but it is already taking into
account the placement of the file when it is created.  This just
refines the granularity at which we can make such decisions.

> My point is roughly centered around the distinction between a Linux
> kernel with SELinux configured and a policy installed and an SELinux
> system with the aforementioned and a complete SELinux runtime that
> includes goodies like restorecond. The former is strictly label based,
> while the latter is definitely not. I really think that you should
> leave the name based bits in userspace unless you are willing to
> accept their general value in the kernel.

SELinux remains label-based in its access control enforcement
mechanism in the kernel even after this change.  In any event, you are
free to configure your policy to not use this extension just as you
are free to not ship/run restorecond - there is no real difference
there.

With regard to the pathname hooks, they aren't suitable because they
don't have anything to do with assigning labels to new inodes - they
are about enforcing access control upon file accesses based on the
pathname used to reach the file.  That doesn't support what we want.

The only real question for this particular patch IMHO is whether the
changes being made here are sensible from a vfs and fs point of view.
Most of your comments seem more directed at whether or not SELinux
should be extended in this manner (i.e. the 2nd patch), and that's a
question for the SELinux developers, who have already come to
consensus on the matter.

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-07 13:43       ` Stephen Smalley
@ 2010-12-07 14:58         ` Casey Schaufler
  2010-12-07 16:11           ` Stephen Smalley
  0 siblings, 1 reply; 16+ messages in thread
From: Casey Schaufler @ 2010-12-07 14:58 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: Eric Paris, penguin-kernel, selinux, sds, jmorris,
	linux-security-module, viro, hch, Casey Schaufler

On 12/7/2010 5:43 AM, Stephen Smalley wrote:
> ...
> The only real question for this particular patch IMHO is whether the
> changes being made here are sensible from a vfs and fs point of view.
> Most of your comments seem more directed at whether or not SELinux
> should be extended in this manner (i.e. the 2nd patch), and that's a
> question for the SELinux developers, who have already come to
> consensus on the matter.

I will accept that the changes are acceptable to the SELinux
community and that the proposed behavior is perceived as
beneficial within that community.

One of the concerns that has traditionally been raised when new
LSM hooks or changes to existing hooks are proposed is that of
generality. I can think of a number of ways in which the final
component of a pathname could be used to make access control
decisions, but I would not expect to be using them myself. Who
else might you expect to make use of this LSM "enhancement", or
is this something that only SELinux is ever going to want? Is
the component something the LSM should be providing in general,
or is this the only case in which it makes sense?

I think that the LSM interfaces are awfully inconsistent and
quite arbitrary, and that a little bit of consideration about
the possibility of avoiding taking it even further in that
direction is in order, especially when a change is in a fuzzy
area that has been contentious in the past. I remember the
issues that were raised when the AppArmor folks proposed
LSM interface changes, and while the changes proposed today
lack the problems those changes did the same issues need to
be raised and addressed.

In the end, I don't mind an additional parameter I'll not be
using in Smack if it is generally useful.


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-07 14:58         ` Casey Schaufler
@ 2010-12-07 16:11           ` Stephen Smalley
  2010-12-07 16:56             ` Casey Schaufler
  0 siblings, 1 reply; 16+ messages in thread
From: Stephen Smalley @ 2010-12-07 16:11 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Eric Paris, penguin-kernel, selinux, sds, jmorris,
	linux-security-module, viro, hch

On Tue, Dec 7, 2010 at 9:58 AM, Casey Schaufler <casey@schaufler-ca.com> wrote:
> One of the concerns that has traditionally been raised when new
> LSM hooks or changes to existing hooks are proposed is that of
> generality. I can think of a number of ways in which the final
> component of a pathname could be used to make access control
> decisions, but I would not expect to be using them myself. Who
> else might you expect to make use of this LSM "enhancement", or
> is this something that only SELinux is ever going to want? Is
> the component something the LSM should be providing in general,
> or is this the only case in which it makes sense?

The existing inode_init_security hook is useful for any security
module that maintains security attributes on inodes (although when it
was added, it was only first used by SELinux as that was the only such
security module), and adding the last component name as a further
input argument is a general change that could benefit any such
security module that wants to use that information in determining the
correct attribute value for the new inode.  The fact that there are
only two such modules that implement the hook today (SELinux and
Smack), and that you chose to not use the argument for Smack doesn't
lessen its generality.   If you have an alternative parameter that
would be more general that you would like to pass to the hook that
would enable SELinux to do what it wants and provide benefit to Smack,
then feel free to suggest it.

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-07 16:11           ` Stephen Smalley
@ 2010-12-07 16:56             ` Casey Schaufler
  2010-12-07 17:34               ` Stephen Smalley
  0 siblings, 1 reply; 16+ messages in thread
From: Casey Schaufler @ 2010-12-07 16:56 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: Eric Paris, penguin-kernel, selinux, sds, jmorris,
	linux-security-module, viro, hch, Casey Schaufler

On 12/7/2010 8:11 AM, Stephen Smalley wrote:
> On Tue, Dec 7, 2010 at 9:58 AM, Casey Schaufler <casey@schaufler-ca.com> wrote:
>> One of the concerns that has traditionally been raised when new
>> LSM hooks or changes to existing hooks are proposed is that of
>> generality. I can think of a number of ways in which the final
>> component of a pathname could be used to make access control
>> decisions, but I would not expect to be using them myself. Who
>> else might you expect to make use of this LSM "enhancement", or
>> is this something that only SELinux is ever going to want? Is
>> the component something the LSM should be providing in general,
>> or is this the only case in which it makes sense?
> The existing inode_init_security hook is useful for any security
> module that maintains security attributes on inodes (although when it
> was added, it was only first used by SELinux as that was the only such
> security module), and adding the last component name as a further
> input argument is a general change that could benefit any such
> security module that wants to use that information in determining the
> correct attribute value for the new inode.  The fact that there are
> only two such modules that implement the hook today (SELinux and
> Smack), and that you chose to not use the argument for Smack doesn't
> lessen its generality.   If you have an alternative parameter that
> would be more general that you would like to pass to the hook that
> would enable SELinux to do what it wants and provide benefit to Smack,
> then feel free to suggest it.

Let's assume for the moment that no one has a significant objection
to adding the component name to inode_init_security. I am not
suggesting that what gets passed to inode_init_security is
insufficiently general. I am asking if there are other hooks that
also ought to have the component name as one of their parameters.
Yes, I understand the concept of "if it ain't broke ...", and that
may suffice at this point, and if not the fact that no one would be
using the component name in those other hooks definitely would. I
expect that when someone comes along with a new LSM that does access
controls based on the final component* they aren't going to suffer
unnecessary resistance from the SELinux community as they add the
component name as a parameter to other hooks.

----
* For example, only files suffixed with ".exe" can be executed and
  only files suffixed with ".so" can be mmapped.


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-07 16:56             ` Casey Schaufler
@ 2010-12-07 17:34               ` Stephen Smalley
  2010-12-07 18:00                 ` Casey Schaufler
  2010-12-08 14:25                 ` Kyle Moffett
  0 siblings, 2 replies; 16+ messages in thread
From: Stephen Smalley @ 2010-12-07 17:34 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Eric Paris, penguin-kernel, selinux, sds, jmorris,
	linux-security-module, viro, hch

On Tue, Dec 7, 2010 at 11:56 AM, Casey Schaufler <casey@schaufler-ca.com> wrote:
> Let's assume for the moment that no one has a significant objection
> to adding the component name to inode_init_security. I am not
> suggesting that what gets passed to inode_init_security is
> insufficiently general. I am asking if there are other hooks that
> also ought to have the component name as one of their parameters.
> Yes, I understand the concept of "if it ain't broke ...", and that
> may suffice at this point, and if not the fact that no one would be
> using the component name in those other hooks definitely would. I
> expect that when someone comes along with a new LSM that does access
> controls based on the final component* they aren't going to suffer
> unnecessary resistance from the SELinux community as they add the
> component name as a parameter to other hooks.
>
> ----
> * For example, only files suffixed with ".exe" can be executed and
>  only files suffixed with ".so" can be mmapped.

I think you can already achieve that via the pathname hooks, but if
not and you want it, go for it.


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-07 17:34               ` Stephen Smalley
@ 2010-12-07 18:00                 ` Casey Schaufler
  2010-12-08 14:25                 ` Kyle Moffett
  1 sibling, 0 replies; 16+ messages in thread
From: Casey Schaufler @ 2010-12-07 18:00 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: Eric Paris, penguin-kernel, selinux, sds, jmorris,
	linux-security-module, viro, hch, Casey Schaufler

On 12/7/2010 9:34 AM, Stephen Smalley wrote:
> On Tue, Dec 7, 2010 at 11:56 AM, Casey Schaufler <casey@schaufler-ca.com> wrote:
>> Let's assume for the moment that no one has a significant objection
>> to adding the component name to inode_init_security. I am not
>> suggesting that what gets passed to inode_init_security is
>> insufficiently general. I am asking if there are other hooks that
>> also ought to have the component name as one of their parameters.
>> Yes, I understand the concept of "if it ain't broke ...", and that
>> may suffice at this point, and if not the fact that no one would be
>> using the component name in those other hooks definitely would. I
>> expect that when someone comes along with a new LSM that does access
>> controls based on the final component* they aren't going to suffer
>> unnecessary resistance from the SELinux community as they add the
>> component name as a parameter to other hooks.
>>
>> ----
>> * For example, only files suffixed with ".exe" can be executed and
>>  only files suffixed with ".so" can be mmapped.
> I think you can already achieve that via the pathname hooks, but if
> not and you want it, go for it.

Well there it is then. Sure, add the component to inode_init_security
if no one on the filesystem end has an issue with it.



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-07 17:34               ` Stephen Smalley
  2010-12-07 18:00                 ` Casey Schaufler
@ 2010-12-08 14:25                 ` Kyle Moffett
  2010-12-08 14:49                   ` Casey Schaufler
  2010-12-08 19:04                   ` Daniel J Walsh
  1 sibling, 2 replies; 16+ messages in thread
From: Kyle Moffett @ 2010-12-08 14:25 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: Casey Schaufler, Eric Paris, penguin-kernel, selinux, sds,
	jmorris, linux-security-module, viro, hch

On Tue, Dec 7, 2010 at 12:34, Stephen Smalley <stephen.smalley@gmail.com> wrote:
> On Tue, Dec 7, 2010 at 11:56 AM, Casey Schaufler <casey@schaufler-ca.com> wrote:
>> Let's assume for the moment that no one has a significant objection
>> to adding the component name to inode_init_security. I am not
>> suggesting that what gets passed to inode_init_security is
>> insufficiently general. I am asking if there are other hooks that
>> also ought to have the component name as one of their parameters.
>> Yes, I understand the concept of "if it ain't broke ...", and that
>> may suffice at this point, and if not the fact that no one would be
>> using the component name in those other hooks definitely would. I
>> expect that when someone comes along with a new LSM that does access
>> controls based on the final component* they aren't going to suffer
>> unnecessary resistance from the SELinux community as they add the
>> component name as a parameter to other hooks.
>>
>> ----
>> * For example, only files suffixed with ".exe" can be executed and
>>  only files suffixed with ".so" can be mmapped.
>
> I think you can already achieve that via the pathname hooks, but if
> not and you want it, go for it.

Actually, there are still a few remaining hooks which might actually
be useful to add the last path component to even in SELinux.  While
you of course cannot (and should not) *change* the label of a file in
a link() or rename() operation, it would potentially be useful to deny
an operation based on the old label and the new name that is being
passed in.  It would also make sense if the file create() action was
able to match on the same requirements as the file "type_transition".

EG: To prevent a compromised web application from messing with
otherwise writable .htaccess files in its data folders, you ought to
be able to do something like this (although this does imply
introducing some sort of matching order, where a "deny_name" with a
matching name is applied instead of a more-generic "allow"):

deny_name my_web_app_t my_web_app_data_t file:rename ".htaccess";
allow my_web_app_t my_web_app_data_t file:rename;

deny_name my_web_app_t my_web_app_data_t file:link ".htaccess";
allow my_web_app_t my_web_app_data_t file:link;

Cheers,
Kyle Moffett


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-08 14:25                 ` Kyle Moffett
@ 2010-12-08 14:49                   ` Casey Schaufler
  2010-12-08 19:04                   ` Daniel J Walsh
  1 sibling, 0 replies; 16+ messages in thread
From: Casey Schaufler @ 2010-12-08 14:49 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: Stephen Smalley, Eric Paris, penguin-kernel, selinux, sds,
	jmorris, linux-security-module, viro, hch, Casey Schaufler

On 12/8/2010 6:25 AM, Kyle Moffett wrote:
> On Tue, Dec 7, 2010 at 12:34, Stephen Smalley <stephen.smalley@gmail.com> wrote:
>> On Tue, Dec 7, 2010 at 11:56 AM, Casey Schaufler <casey@schaufler-ca.com> wrote:
>>> Let's assume for the moment that no one has a significant objection
>>> to adding the component name to inode_init_security. I am not
>>> suggesting that what gets passed to inode_init_security is
>>> insufficiently general. I am asking if there are other hooks that
>>> also ought to have the component name as one of their parameters.
>>> Yes, I understand the concept of "if it ain't broke ...", and that
>>> may suffice at this point, and if not the fact that no one would be
>>> using the component name in those other hooks definitely would. I
>>> expect that when someone comes along with a new LSM that does access
>>> controls based on the final component* they aren't going to suffer
>>> unnecessary resistance from the SELinux community as they add the
>>> component name as a parameter to other hooks.
>>>
>>> ----
>>> * For example, only files suffixed with ".exe" can be executed and
>>>  only files suffixed with ".so" can be mmapped.
>> I think you can already achieve that via the pathname hooks, but if
>> not and you want it, go for it.
> Actually, there are still a few remaining hooks which might actually
> be useful to add the last path component to even in SELinux.  While
> you of course cannot (and should not) *change* the label of a file in
> a link() or rename() operation, it would potentially be useful to deny
> an operation based on the old label and the new name that is being
> passed in.  It would also make sense if the file create() action was
> able to match on the same requirements as the file "type_transition".
>
> EG: To prevent a compromised web application from messing with
> otherwise writable .htaccess files in its data folders, you ought to
> be able to do something like this (although this does imply
> introducing some sort of matching order, where a "deny_name" with a
> matching name is applied instead of a more-generic "allow"):
>
> deny_name my_web_app_t my_web_app_data_t file:rename ".htaccess";
> allow my_web_app_t my_web_app_data_t file:rename;
>
> deny_name my_web_app_t my_web_app_data_t file:link ".htaccess";
> allow my_web_app_t my_web_app_data_t file:link;
>
> Cheers,
> Kyle Moffett
>

Thank you Kyle. I was hoping someone would follow up on that. I owe you (another?) beer.


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation
  2010-12-08 14:25                 ` Kyle Moffett
  2010-12-08 14:49                   ` Casey Schaufler
@ 2010-12-08 19:04                   ` Daniel J Walsh
  1 sibling, 0 replies; 16+ messages in thread
From: Daniel J Walsh @ 2010-12-08 19:04 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: Stephen Smalley, Casey Schaufler, Eric Paris, penguin-kernel,
	selinux, sds, jmorris, linux-security-module, viro, hch

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 12/08/2010 09:25 AM, Kyle Moffett wrote:
> On Tue, Dec 7, 2010 at 12:34, Stephen Smalley <stephen.smalley@gmail.com> wrote:
>> On Tue, Dec 7, 2010 at 11:56 AM, Casey Schaufler <casey@schaufler-ca.com> wrote:
>>> Let's assume for the moment that no one has a significant objection
>>> to adding the component name to inode_init_security. I am not
>>> suggesting that what gets passed to inode_init_security is
>>> insufficiently general. I am asking if there are other hooks that
>>> also ought to have the component name as one of their parameters.
>>> Yes, I understand the concept of "if it ain't broke ...", and that
>>> may suffice at this point, and if not the fact that no one would be
>>> using the component name in those other hooks definitely would. I
>>> expect that when someone comes along with a new LSM that does access
>>> controls based on the final component* they aren't going to suffer
>>> unnecessary resistance from the SELinux community as they add the
>>> component name as a parameter to other hooks.
>>>
>>> ----
>>> * For example, only files suffixed with ".exe" can be executed and
>>>  only files suffixed with ".so" can be mmapped.
>>
>> I think you can already achieve that via the pathname hooks, but if
>> not and you want it, go for it.
> 
> Actually, there are still a few remaining hooks which might actually
> be useful to add the last path component to even in SELinux.  While
> you of course cannot (and should not) *change* the label of a file in
> a link() or rename() operation, it would potentially be useful to deny
> an operation based on the old label and the new name that is being
> passed in.  It would also make sense if the file create() action was
> able to match on the same requirements as the file "type_transition".
> 
> EG: To prevent a compromised web application from messing with
> otherwise writable .htaccess files in its data folders, you ought to
> be able to do something like this (although this does imply
> introducing some sort of matching order, where a "deny_name" with a
> matching name is applied instead of a more-generic "allow"):
> 
> deny_name my_web_app_t my_web_app_data_t file:rename ".htaccess";
> allow my_web_app_t my_web_app_data_t file:rename;
> 
> deny_name my_web_app_t my_web_app_data_t file:link ".htaccess";
> allow my_web_app_t my_web_app_data_t file:link;
> 
> Cheers,
> Kyle Moffett
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.



I just saw a use case where this might be handy.  If you have two
machines sharing an a homedir.  Say I have two desktop machines.  If I
setup NFS shared from one machine to the other via NFS.  When I log into
the client machine, xdm_t creates the .xsession-errors file,  On the
server there is a rule that says kernel_t creating files in
user_home_dir_t creates them as user_home_t.  Now when I login to the
server machine, I get an AVC saying that xdm_t can not write
.xsession-errors labeled user_home_t.  It should have been labeled
xdm_home_t.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAkz/1qYACgkQrlYvE4MpobNbHwCg0ndO2X/MuRUnp4ASMXvi/eBD
sJAAniWrS/csZKQlmOsbkChXYGYVfQTq
=UPLG
-----END PGP SIGNATURE-----

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2010-12-08 19:04 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-03 21:45 [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation Eric Paris
2010-12-03 21:45 ` [RFC PATCH 2/2] SELinux: Use dentry name in new object labeling Eric Paris
2010-12-04  4:20 ` [RFC PATCH 1/2] fs/vfs/security: pass last path component to LSM on inode creation Casey Schaufler
2010-12-04 21:34   ` Eric Paris
2010-12-05  7:38     ` Casey Schaufler
2010-12-06 14:32       ` Daniel J Walsh
2010-12-06 23:32       ` Kyle Moffett
2010-12-07 13:43       ` Stephen Smalley
2010-12-07 14:58         ` Casey Schaufler
2010-12-07 16:11           ` Stephen Smalley
2010-12-07 16:56             ` Casey Schaufler
2010-12-07 17:34               ` Stephen Smalley
2010-12-07 18:00                 ` Casey Schaufler
2010-12-08 14:25                 ` Kyle Moffett
2010-12-08 14:49                   ` Casey Schaufler
2010-12-08 19:04                   ` Daniel J Walsh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.