Merge branch 'master' of git://git.infradead.org/users/eparis/selinux into next
authorJames Morris <jmorris@namei.org>
Tue, 8 Mar 2011 00:38:10 +0000 (11:38 +1100)
committerJames Morris <jmorris@namei.org>
Tue, 8 Mar 2011 00:38:10 +0000 (11:38 +1100)
52 files changed:
fs/btrfs/inode.c
fs/btrfs/xattr.c
fs/btrfs/xattr.h
fs/ext2/ext2.h
fs/ext2/ialloc.c
fs/ext2/namei.c
fs/ext2/xattr.h
fs/ext2/xattr_security.c
fs/ext3/ialloc.c
fs/ext3/namei.c
fs/ext3/xattr.h
fs/ext3/xattr_security.c
fs/ext4/ialloc.c
fs/ext4/xattr.h
fs/ext4/xattr_security.c
fs/gfs2/inode.c
fs/jffs2/dir.c
fs/jffs2/nodelist.h
fs/jffs2/security.c
fs/jffs2/write.c
fs/jffs2/xattr.h
fs/jfs/jfs_xattr.h
fs/jfs/namei.c
fs/jfs/xattr.c
fs/namespace.c
fs/ocfs2/namei.c
fs/ocfs2/refcounttree.c
fs/ocfs2/xattr.c
fs/ocfs2/xattr.h
fs/proc/proc_sysctl.c
fs/reiserfs/namei.c
fs/reiserfs/xattr_security.c
fs/xfs/linux-2.6/xfs_iops.c
include/linux/ext3_fs.h
include/linux/reiserfs_xattr.h
include/linux/security.h
kernel/sysctl.c
mm/shmem.c
scripts/selinux/genheaders/genheaders.c
security/capability.c
security/security.c
security/selinux/hooks.c
security/selinux/include/classmap.h
security/selinux/include/security.h
security/selinux/ss/avtab.h
security/selinux/ss/mls.c
security/selinux/ss/mls.h
security/selinux/ss/policydb.c
security/selinux/ss/policydb.h
security/selinux/ss/services.c
security/selinux/xfrm.c
security/smack/smack_lsm.c

index 0efdb65953c577cc27fb7d190dc4f66cd7a933a2..a45785ab197b1a935a7994834df97105283d9208 100644 (file)
@@ -90,13 +90,14 @@ static noinline int cow_file_range(struct inode *inode,
                                   unsigned long *nr_written, int unlock);
 
 static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
-                                    struct inode *inode,  struct inode *dir)
+                                    struct inode *inode,  struct inode *dir,
+                                    const struct qstr *qstr)
 {
        int err;
 
        err = btrfs_init_acl(trans, inode, dir);
        if (!err)
-               err = btrfs_xattr_security_init(trans, inode, dir);
+               err = btrfs_xattr_security_init(trans, inode, dir, qstr);
        return err;
 }
 
@@ -4704,7 +4705,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_inode_security(trans, inode, dir);
+       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
@@ -4765,7 +4766,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_inode_security(trans, inode, dir);
+       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
@@ -4893,7 +4894,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
        drop_on_err = 1;
 
-       err = btrfs_init_inode_security(trans, inode, dir);
+       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
        if (err)
                goto out_fail;
 
@@ -7104,7 +7105,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_inode_security(trans, inode, dir);
+       err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
index a5776531dc2bacdbbc9ab2dc22d9e5361a1bf2f9..d779cefcfd7ddaace6928ae007d906293c5b24bf 100644 (file)
@@ -370,7 +370,8 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
 }
 
 int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
-                             struct inode *inode, struct inode *dir)
+                             struct inode *inode, struct inode *dir,
+                             const struct qstr *qstr)
 {
        int err;
        size_t len;
@@ -378,7 +379,8 @@ int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
        char *suffix;
        char *name;
 
-       err = security_inode_init_security(inode, dir, &suffix, &value, &len);
+       err = security_inode_init_security(inode, dir, qstr, &suffix, &value,
+                                          &len);
        if (err) {
                if (err == -EOPNOTSUPP)
                        return 0;
index 7a43fd640bbb54b97c63fe37ab2dbea9e28c00e0..b3cc8039134bc4ed59420f51b48ab72c04f2eedc 100644 (file)
@@ -37,6 +37,7 @@ extern int btrfs_setxattr(struct dentry *dentry, const char *name,
 extern int btrfs_removexattr(struct dentry *dentry, const char *name);
 
 extern int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
-                                    struct inode *inode, struct inode *dir);
+                                    struct inode *inode, struct inode *dir,
+                                    const struct qstr *qstr);
 
 #endif /* __XATTR__ */
index 6346a2acf326075b2e23739a2ba9b55ce6d56c33..1b48c337087293bfb95733d52def539f68ff219d 100644 (file)
@@ -110,7 +110,7 @@ extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
 extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *, int);
 
 /* ialloc.c */
-extern struct inode * ext2_new_inode (struct inode *, int);
+extern struct inode * ext2_new_inode (struct inode *, int, const struct qstr *);
 extern void ext2_free_inode (struct inode *);
 extern unsigned long ext2_count_free_inodes (struct super_block *);
 extern void ext2_check_inodes_bitmap (struct super_block *);
index ad70479aabff30d08d1b322846e7e3f49ecbe3d5..ee9ed31948e1229d123cbea2fcea5e45ff42aa3f 100644 (file)
@@ -429,7 +429,8 @@ found:
        return group;
 }
 
-struct inode *ext2_new_inode(struct inode *dir, int mode)
+struct inode *ext2_new_inode(struct inode *dir, int mode,
+                            const struct qstr *qstr)
 {
        struct super_block *sb;
        struct buffer_head *bitmap_bh = NULL;
@@ -585,7 +586,7 @@ got:
        if (err)
                goto fail_free_drop;
 
-       err = ext2_init_security(inode,dir);
+       err = ext2_init_security(inode, dir, qstr);
        if (err)
                goto fail_free_drop;
 
index adb91855ccd092c86f220161c922873bee7fce0c..ed5c5d496ee914aacd5e0d3ea6c7dcd98d319794 100644 (file)
@@ -104,7 +104,7 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, st
 
        dquot_initialize(dir);
 
-       inode = ext2_new_inode(dir, mode);
+       inode = ext2_new_inode(dir, mode, &dentry->d_name);
        if (IS_ERR(inode))
                return PTR_ERR(inode);
 
@@ -133,7 +133,7 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_
 
        dquot_initialize(dir);
 
-       inode = ext2_new_inode (dir, mode);
+       inode = ext2_new_inode (dir, mode, &dentry->d_name);
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                init_special_inode(inode, inode->i_mode, rdev);
@@ -159,7 +159,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry,
 
        dquot_initialize(dir);
 
-       inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
+       inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO, &dentry->d_name);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out;
@@ -230,7 +230,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 
        inode_inc_link_count(dir);
 
-       inode = ext2_new_inode (dir, S_IFDIR | mode);
+       inode = ext2_new_inode(dir, S_IFDIR | mode, &dentry->d_name);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_dir;
index a1a1c2184616594c240151b115460856b53cfccf..5e41cccff7622a212fec0a8f2a43fe7e38d8b2d9 100644 (file)
@@ -116,9 +116,11 @@ exit_ext2_xattr(void)
 # endif  /* CONFIG_EXT2_FS_XATTR */
 
 #ifdef CONFIG_EXT2_FS_SECURITY
-extern int ext2_init_security(struct inode *inode, struct inode *dir);
+extern int ext2_init_security(struct inode *inode, struct inode *dir,
+                             const struct qstr *qstr);
 #else
-static inline int ext2_init_security(struct inode *inode, struct inode *dir)
+static inline int ext2_init_security(struct inode *inode, struct inode *dir,
+                                    const struct qstr *qstr)
 {
        return 0;
 }
index 3004e15d5da53a711e064981aeaab3cba7334e8c..5d979b4347b03c3b3820f6cb14c8566cdeb9497a 100644 (file)
@@ -47,14 +47,15 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
 }
 
 int
-ext2_init_security(struct inode *inode, struct inode *dir)
+ext2_init_security(struct inode *inode, struct inode *dir,
+                  const struct qstr *qstr)
 {
        int err;
        size_t len;
        void *value;
        char *name;
 
-       err = security_inode_init_security(inode, dir, &name, &value, &len);
+       err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
        if (err) {
                if (err == -EOPNOTSUPP)
                        return 0;
index 9724aef224600c17faf288464d43cb7c5766ad3e..bfc2dc43681d41c6b54fe405174cc480de1663e9 100644 (file)
@@ -404,7 +404,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
  * For other inodes, search forward from the parent directory's block
  * group to find a free inode.
  */
-struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
+struct inode *ext3_new_inode(handle_t *handle, struct inode * dir,
+                            const struct qstr *qstr, int mode)
 {
        struct super_block *sb;
        struct buffer_head *bitmap_bh = NULL;
@@ -589,7 +590,7 @@ got:
        if (err)
                goto fail_free_drop;
 
-       err = ext3_init_security(handle,inode, dir);
+       err = ext3_init_security(handle, inode, dir, qstr);
        if (err)
                goto fail_free_drop;
 
index b27ba71810ecdb57efbf7739559eb7bb76b1126e..9dba3bd69d9a7009a74031f818a91f2529fadb67 100644 (file)
@@ -1710,7 +1710,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;
@@ -1746,7 +1746,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);
@@ -1784,7 +1784,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;
@@ -2206,7 +2206,7 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
 
-       inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
+       inode = ext3_new_inode (handle, dir, &dentry->d_name, S_IFLNK|S_IRWXUGO);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_stop;
index 377fe720116995caa90f94821bfe808e2c0e4b9b..2be4f69bfa64b301d437e5130868f433a01d5f50 100644 (file)
@@ -128,10 +128,10 @@ exit_ext3_xattr(void)
 
 #ifdef CONFIG_EXT3_FS_SECURITY
 extern int ext3_init_security(handle_t *handle, struct inode *inode,
-                               struct inode *dir);
+                             struct inode *dir, const struct qstr *qstr);
 #else
 static inline int ext3_init_security(handle_t *handle, struct inode *inode,
-                               struct inode *dir)
+                                    struct inode *dir, const struct qstr *qstr)
 {
        return 0;
 }
index 03a99bfc59f90f1f7331251e70e71ce9f94253af..b8d9f83aa5c545f23b48f14530b6ee0578204a66 100644 (file)
@@ -49,14 +49,15 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
 }
 
 int
-ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir)
+ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
+                  const struct qstr *qstr)
 {
        int err;
        size_t len;
        void *value;
        char *name;
 
-       err = security_inode_init_security(inode, dir, &name, &value, &len);
+       err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
        if (err) {
                if (err == -EOPNOTSUPP)
                        return 0;
index eb9097aec6f091a788b876840e53d26727d538ee..78b79e1bd7ed2214af4399bd628fd4158d36410e 100644 (file)
@@ -1042,7 +1042,7 @@ got:
        if (err)
                goto fail_free_drop;
 
-       err = ext4_init_security(handle, inode, dir);
+       err = ext4_init_security(handle, inode, dir, qstr);
        if (err)
                goto fail_free_drop;
 
index 1ef16520b950c8a4c0c5385ee24f620b147065e2..25b7387ff183f880cdb9ccaf2529ca8c0f218a7b 100644 (file)
@@ -145,10 +145,10 @@ ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
 
 #ifdef CONFIG_EXT4_FS_SECURITY
 extern int ext4_init_security(handle_t *handle, struct inode *inode,
-                               struct inode *dir);
+                             struct inode *dir, const struct qstr *qstr);
 #else
 static inline int ext4_init_security(handle_t *handle, struct inode *inode,
-                               struct inode *dir)
+                                    struct inode *dir, const struct qstr *qstr)
 {
        return 0;
 }
index 9b21268e121c1a90f83465fa7a54292c2d8a56f0..007c3bfbf094221988855d9eb754bfdf430d569e 100644 (file)
@@ -49,14 +49,15 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
 }
 
 int
-ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir)
+ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
+                  const struct qstr *qstr)
 {
        int err;
        size_t len;
        void *value;
        char *name;
 
-       err = security_inode_init_security(inode, dir, &name, &value, &len);
+       err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
        if (err) {
                if (err == -EOPNOTSUPP)
                        return 0;
index 7aa7d4f8984aa3271eac65e268cd4e5e0db05564..97d54a28776a1851a004b62a7b7ecc41a84d0e04 100644 (file)
@@ -763,14 +763,15 @@ fail:
        return error;
 }
 
-static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip)
+static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
+                             const struct qstr *qstr)
 {
        int err;
        size_t len;
        void *value;
        char *name;
 
-       err = security_inode_init_security(&ip->i_inode, &dip->i_inode,
+       err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
                                           &name, &value, &len);
 
        if (err) {
@@ -854,7 +855,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        if (error)
                goto fail_gunlock2;
 
-       error = gfs2_security_init(dip, GFS2_I(inode));
+       error = gfs2_security_init(dip, GFS2_I(inode), name);
        if (error)
                goto fail_gunlock2;
 
index 92978658ed1803bc289840500e8a220cbf032ffa..82faddd1f321b74e8efd4f11fe07449e409d7bbc 100644 (file)
@@ -215,8 +215,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
           no chance of AB-BA deadlock involving its f->sem). */
        mutex_unlock(&f->sem);
 
-       ret = jffs2_do_create(c, dir_f, f, ri,
-                             dentry->d_name.name, dentry->d_name.len);
+       ret = jffs2_do_create(c, dir_f, f, ri, &dentry->d_name);
        if (ret)
                goto fail;
 
@@ -386,7 +385,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
 
        jffs2_complete_reservation(c);
 
-       ret = jffs2_init_security(inode, dir_i);
+       ret = jffs2_init_security(inode, dir_i, &dentry->d_name);
        if (ret)
                goto fail;
 
@@ -530,7 +529,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
 
        jffs2_complete_reservation(c);
 
-       ret = jffs2_init_security(inode, dir_i);
+       ret = jffs2_init_security(inode, dir_i, &dentry->d_name);
        if (ret)
                goto fail;
 
@@ -703,7 +702,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
 
        jffs2_complete_reservation(c);
 
-       ret = jffs2_init_security(inode, dir_i);
+       ret = jffs2_init_security(inode, dir_i, &dentry->d_name);
        if (ret)
                goto fail;
 
index 5a53d9bdb2b584a3e1cb737ed028183d99f527e2..e4619b00f7c5dec65669f0b1dd9acdf135392185 100644 (file)
@@ -401,7 +401,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
                            struct jffs2_raw_inode *ri, unsigned char *buf,
                            uint32_t offset, uint32_t writelen, uint32_t *retlen);
 int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f,
-                   struct jffs2_raw_inode *ri, const char *name, int namelen);
+                   struct jffs2_raw_inode *ri, const struct qstr *qstr);
 int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name,
                    int namelen, struct jffs2_inode_info *dead_f, uint32_t time);
 int jffs2_do_link(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino,
index 239f51216a68ee6e9ec1f4dc156ff513b686bc85..cfeb7164b0853a0d163cf7552f89577743067575 100644 (file)
 #include "nodelist.h"
 
 /* ---- Initial Security Label Attachment -------------- */
-int jffs2_init_security(struct inode *inode, struct inode *dir)
+int jffs2_init_security(struct inode *inode, struct inode *dir,
+                       const struct qstr *qstr)
 {
        int rc;
        size_t len;
        void *value;
        char *name;
 
-       rc = security_inode_init_security(inode, dir, &name, &value, &len);
+       rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
        if (rc) {
                if (rc == -EOPNOTSUPP)
                        return 0;
index c819eb0e982d8b95a216a09ab9398c9bd7e3ea58..30d175b6d290698fad6a38f6bbafba755eee90b4 100644 (file)
@@ -424,7 +424,9 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
        return ret;
 }
 
-int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen)
+int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
+                   struct jffs2_inode_info *f, struct jffs2_raw_inode *ri,
+                   const struct qstr *qstr)
 {
        struct jffs2_raw_dirent *rd;
        struct jffs2_full_dnode *fn;
@@ -466,15 +468,15 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
        mutex_unlock(&f->sem);
        jffs2_complete_reservation(c);
 
-       ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode);
+       ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode, qstr);
        if (ret)
                return ret;
        ret = jffs2_init_acl_post(&f->vfs_inode);
        if (ret)
                return ret;
 
-       ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
-                               ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
+       ret = jffs2_reserve_space(c, sizeof(*rd)+qstr->len, &alloclen,
+                               ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(qstr->len));
 
        if (ret) {
                /* Eep. */
@@ -493,19 +495,19 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
 
        rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
        rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-       rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
+       rd->totlen = cpu_to_je32(sizeof(*rd) + qstr->len);
        rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
 
        rd->pino = cpu_to_je32(dir_f->inocache->ino);
        rd->version = cpu_to_je32(++dir_f->highest_version);
        rd->ino = ri->ino;
        rd->mctime = ri->ctime;
-       rd->nsize = namelen;
+       rd->nsize = qstr->len;
        rd->type = DT_REG;
        rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-       rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
+       rd->name_crc = cpu_to_je32(crc32(0, qstr->name, qstr->len));
 
-       fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL);
+       fd = jffs2_write_dirent(c, dir_f, rd, qstr->name, qstr->len, ALLOC_NORMAL);
 
        jffs2_free_raw_dirent(rd);
 
index cf4f5759b42b407ba614d1c40fd67b9db511e01a..7be4beb306f3ff06eb6df2a8427ca31cb2027e6f 100644 (file)
@@ -121,10 +121,11 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
 #endif /* CONFIG_JFFS2_FS_XATTR */
 
 #ifdef CONFIG_JFFS2_FS_SECURITY
-extern int jffs2_init_security(struct inode *inode, struct inode *dir);
+extern int jffs2_init_security(struct inode *inode, struct inode *dir,
+                              const struct qstr *qstr);
 extern const struct xattr_handler jffs2_security_xattr_handler;
 #else
-#define jffs2_init_security(inode,dir) (0)
+#define jffs2_init_security(inode,dir,qstr)    (0)
 #endif /* CONFIG_JFFS2_FS_SECURITY */
 
 #endif /* _JFFS2_FS_XATTR_H_ */
index 88b6cc535bf246cee2dc33487993fcd488b48dc2..e9e100fd7c09a90a7ba603e7f1282ae9ba15e164 100644 (file)
@@ -62,10 +62,11 @@ extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
 extern int jfs_removexattr(struct dentry *, const char *);
 
 #ifdef CONFIG_JFS_SECURITY
-extern int jfs_init_security(tid_t, struct inode *, struct inode *);
+extern int jfs_init_security(tid_t, struct inode *, struct inode *,
+                            const struct qstr *);
 #else
 static inline int jfs_init_security(tid_t tid, struct inode *inode,
-                                   struct inode *dir)
+                                   struct inode *dir, const struct qstr *qstr)
 {
        return 0;
 }
index 81ead850ddb65c722fbd5d1fa8a3f7844428e033..2a37d2fdd7075f0f7b4b0287f6834a1ae0de5e63 100644 (file)
@@ -115,7 +115,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
        if (rc)
                goto out3;
 
-       rc = jfs_init_security(tid, ip, dip);
+       rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
        if (rc) {
                txAbort(tid, 0);
                goto out3;
@@ -253,7 +253,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
        if (rc)
                goto out3;
 
-       rc = jfs_init_security(tid, ip, dip);
+       rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
        if (rc) {
                txAbort(tid, 0);
                goto out3;
@@ -932,7 +932,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
        mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
 
-       rc = jfs_init_security(tid, ip, dip);
+       rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
        if (rc)
                goto out3;
 
@@ -1395,7 +1395,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
        if (rc)
                goto out3;
 
-       rc = jfs_init_security(tid, ip, dir);
+       rc = jfs_init_security(tid, ip, dir, &dentry->d_name);
        if (rc) {
                txAbort(tid, 0);
                goto out3;
index 2d7f165d0f1d0b6be01c2003f57fbd64182465ac..3fa4c32272dfa16453f4fbe6995354d219cf4d91 100644 (file)
@@ -1091,7 +1091,8 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
 }
 
 #ifdef CONFIG_JFS_SECURITY
-int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir)
+int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
+                     const struct qstr *qstr)
 {
        int rc;
        size_t len;
@@ -1099,7 +1100,8 @@ int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir)
        char *suffix;
        char *name;
 
-       rc = security_inode_init_security(inode, dir, &suffix, &value, &len);
+       rc = security_inode_init_security(inode, dir, qstr, &suffix, &value,
+                                         &len);
        if (rc) {
                if (rc == -EOPNOTSUPP)
                        return 0;
index d1edf26025dcb018ec434309aacc839f9dbf2cfb..a66feed7311d90aa566706b9c13235db08ae9157 100644 (file)
@@ -1767,6 +1767,10 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
        if (path->dentry != path->mnt->mnt_root)
                return -EINVAL;
 
+       err = security_sb_remount(sb, data);
+       if (err)
+               return err;
+
        down_write(&sb->s_umount);
        if (flags & MS_BIND)
                err = change_mount_flags(path->mnt, flags);
index 849fb4a2e814a9a640e90e410e435b2a3209d598..d6c25d76b537df58a92796b4258ccb2d83c523e2 100644 (file)
@@ -293,7 +293,7 @@ static int ocfs2_mknod(struct inode *dir,
        }
 
        /* get security xattr */
-       status = ocfs2_init_security_get(inode, dir, &si);
+       status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);
        if (status) {
                if (status == -EOPNOTSUPP)
                        si.enable = 0;
@@ -1665,7 +1665,7 @@ static int ocfs2_symlink(struct inode *dir,
        }
 
        /* get security xattr */
-       status = ocfs2_init_security_get(inode, dir, &si);
+       status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);
        if (status) {
                if (status == -EOPNOTSUPP)
                        si.enable = 0;
index 19ebc5aad391f73d58b22b0583114bf7d0517eb8..35798b88042d8bebe72d39afa5aa75a2dd57471c 100644 (file)
@@ -4328,7 +4328,8 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir,
 
        /* If the security isn't preserved, we need to re-initialize them. */
        if (!preserve) {
-               error = ocfs2_init_security_and_acl(dir, new_orphan_inode);
+               error = ocfs2_init_security_and_acl(dir, new_orphan_inode,
+                                                   &new_dentry->d_name);
                if (error)
                        mlog_errno(error);
        }
index 67cd43914641f5d3d522c098763437e21b7c7f46..6bb602486c6bdf92a635855d120d8c724b34aef5 100644 (file)
@@ -7185,7 +7185,8 @@ out:
  * must not hold any lock expect i_mutex.
  */
 int ocfs2_init_security_and_acl(struct inode *dir,
-                               struct inode *inode)
+                               struct inode *inode,
+                               const struct qstr *qstr)
 {
        int ret = 0;
        struct buffer_head *dir_bh = NULL;
@@ -7193,7 +7194,7 @@ int ocfs2_init_security_and_acl(struct inode *dir,
                .enable = 1,
        };
 
-       ret = ocfs2_init_security_get(inode, dir, &si);
+       ret = ocfs2_init_security_get(inode, dir, qstr, &si);
        if (!ret) {
                ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
                                      si.name, si.value, si.value_len,
@@ -7261,13 +7262,14 @@ static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name,
 
 int ocfs2_init_security_get(struct inode *inode,
                            struct inode *dir,
+                           const struct qstr *qstr,
                            struct ocfs2_security_xattr_info *si)
 {
        /* check whether ocfs2 support feature xattr */
        if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
                return -EOPNOTSUPP;
-       return security_inode_init_security(inode, dir, &si->name, &si->value,
-                                           &si->value_len);
+       return security_inode_init_security(inode, dir, qstr, &si->name,
+                                           &si->value, &si->value_len);
 }
 
 int ocfs2_init_security_set(handle_t *handle,
index aa64bb37a65bd73a61d8f61e6ba6fd970f67686e..d63cfb72316b451c59bb15193461137f941109d5 100644 (file)
@@ -57,6 +57,7 @@ int ocfs2_has_inline_xattr_value_outside(struct inode *inode,
                                         struct ocfs2_dinode *di);
 int ocfs2_xattr_remove(struct inode *, struct buffer_head *);
 int ocfs2_init_security_get(struct inode *, struct inode *,
+                           const struct qstr *,
                            struct ocfs2_security_xattr_info *);
 int ocfs2_init_security_set(handle_t *, struct inode *,
                            struct buffer_head *,
@@ -94,5 +95,6 @@ int ocfs2_reflink_xattrs(struct inode *old_inode,
                         struct buffer_head *new_bh,
                         bool preserve_security);
 int ocfs2_init_security_and_acl(struct inode *dir,
-                               struct inode *inode);
+                               struct inode *inode,
+                               const struct qstr *qstr);
 #endif /* OCFS2_XATTR_H */
index 09a1f92a34ef2fce52b07cf394d040708e86a22b..fb707e018a816685529f75f54d9d30eb88cb5054 100644 (file)
@@ -32,7 +32,6 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
        ei->sysctl_entry = table;
 
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-       inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */
        inode->i_mode = table->mode;
        if (!table->child) {
                inode->i_mode |= S_IFREG;
index 68fdf45cc6c923325d80d7abff701211519eb43b..82f45542dcfc7e841a172bb21563f91441d8e1f7 100644 (file)
@@ -593,7 +593,7 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode,
        new_inode_init(inode, dir, mode);
 
        jbegin_count += reiserfs_cache_default_acl(dir);
-       retval = reiserfs_security_init(dir, inode, &security);
+       retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security);
        if (retval < 0) {
                drop_new_inode(inode);
                return retval;
@@ -667,7 +667,7 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
        new_inode_init(inode, dir, mode);
 
        jbegin_count += reiserfs_cache_default_acl(dir);
-       retval = reiserfs_security_init(dir, inode, &security);
+       retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security);
        if (retval < 0) {
                drop_new_inode(inode);
                return retval;
@@ -747,7 +747,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        new_inode_init(inode, dir, mode);
 
        jbegin_count += reiserfs_cache_default_acl(dir);
-       retval = reiserfs_security_init(dir, inode, &security);
+       retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security);
        if (retval < 0) {
                drop_new_inode(inode);
                return retval;
@@ -1032,7 +1032,8 @@ static int reiserfs_symlink(struct inode *parent_dir,
        }
        new_inode_init(inode, parent_dir, mode);
 
-       retval = reiserfs_security_init(parent_dir, inode, &security);
+       retval = reiserfs_security_init(parent_dir, inode, &dentry->d_name,
+                                       &security);
        if (retval < 0) {
                drop_new_inode(inode);
                return retval;
index 237c6928d3c69fe6901ea7abf74e4e6b1a220800..ef66c18a933266e9c658fde311f7a1d0e2d6d023 100644 (file)
@@ -54,6 +54,7 @@ static size_t security_list(struct dentry *dentry, char *list, size_t list_len,
  * of blocks needed for the transaction. If successful, reiserfs_security
  * must be released using reiserfs_security_free when the caller is done. */
 int reiserfs_security_init(struct inode *dir, struct inode *inode,
+                          const struct qstr *qstr,
                           struct reiserfs_security_handle *sec)
 {
        int blocks = 0;
@@ -65,7 +66,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
        if (IS_PRIVATE(dir))
                return 0;
 
-       error = security_inode_init_security(inode, dir, &sec->name,
+       error = security_inode_init_security(inode, dir, qstr, &sec->name,
                                             &sec->value, &sec->length);
        if (error) {
                if (error == -EOPNOTSUPP)
index bd5727852fd6306e692984af2b2830a3dfdddb34..9ff7fc603d2f4325c550303d2f6295c731b65e82 100644 (file)
@@ -102,7 +102,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;
@@ -110,7 +111,7 @@ xfs_init_security(
        unsigned char   *name;
        int             error;
 
-       error = security_inode_init_security(inode, dir, (char **)&name,
+       error = security_inode_init_security(inode, dir, qstr, (char **)&name,
                                             &value, &length);
        if (error) {
                if (error == -EOPNOTSUPP)
@@ -194,7 +195,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;
 
@@ -367,7 +368,7 @@ xfs_vn_symlink(
 
        inode = VFS_I(cip);
 
-       error = xfs_init_security(inode, dir);
+       error = xfs_init_security(inode, dir, &dentry->d_name);
        if (unlikely(error))
                goto out_cleanup_inode;
 
index 65990ef612f526dbad10e326072d89289985f8d5..6043c64c207afa170c3de5a0551bd68451314263 100644 (file)
@@ -884,7 +884,8 @@ extern int ext3fs_dirhash(const char *name, int len, struct
                          dx_hash_info *hinfo);
 
 /* ialloc.c */
-extern struct inode * ext3_new_inode (handle_t *, struct inode *, int);
+extern struct inode * ext3_new_inode (handle_t *, struct inode *,
+                                     const struct qstr *, int);
 extern void ext3_free_inode (handle_t *, struct inode *);
 extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
 extern unsigned long ext3_count_free_inodes (struct super_block *);
index 3b94c91f20a6dfa6dc6c4553c44350042a560f23..6deef5dc95fb033493bde8e775fba572c47ee1ef 100644 (file)
@@ -63,6 +63,7 @@ extern const struct xattr_handler reiserfs_xattr_trusted_handler;
 extern const struct xattr_handler reiserfs_xattr_security_handler;
 #ifdef CONFIG_REISERFS_FS_SECURITY
 int reiserfs_security_init(struct inode *dir, struct inode *inode,
+                          const struct qstr *qstr,
                           struct reiserfs_security_handle *sec);
 int reiserfs_security_write(struct reiserfs_transaction_handle *th,
                            struct inode *inode,
@@ -130,6 +131,7 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
 #ifndef CONFIG_REISERFS_FS_SECURITY
 static inline int reiserfs_security_init(struct inode *dir,
                                         struct inode *inode,
+                                        const struct qstr *qstr,
                                         struct reiserfs_security_handle *sec)
 {
        return 0;
index b2b7f9749f5eb2da633264afd7453fe0a6263561..84a202ac3de9bb5f23edd686f7efdae9b7a67edf 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/fs.h>
 #include <linux/fsnotify.h>
 #include <linux/binfmts.h>
+#include <linux/dcache.h>
 #include <linux/signal.h>
 #include <linux/resource.h>
 #include <linux/sem.h>
@@ -267,6 +268,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     @orig the original mount data copied from userspace.
  *     @copy copied data which will be passed to the security module.
  *     Returns 0 if the copy was successful.
+ * @sb_remount:
+ *     Extracts security system specifc mount options and verifys no changes
+ *     are being made to those options.
+ *     @sb superblock being remounted
+ *     @data contains the filesystem-specific data.
+ *     Return 0 if permission is granted.
  * @sb_umount:
  *     Check permission before the @mnt file system is unmounted.
  *     @mnt contains the mounted file system.
@@ -315,6 +322,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     then it should return -EOPNOTSUPP to skip this processing.
  *     @inode contains the inode structure of the newly created inode.
  *     @dir contains the inode structure of the parent directory.
+ *     @qstr contains the last path component of the new object
  *     @name will be set to the allocated name suffix (e.g. selinux).
  *     @value will be set to the allocated attribute value.
  *     @len will be set to the length of the value.
@@ -1257,12 +1265,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     @cap contains the capability <include/linux/capability.h>.
  *     @audit: Whether to write an audit message or not
  *     Return 0 if the capability is granted for @tsk.
- * @sysctl:
- *     Check permission before accessing the @table sysctl variable in the
- *     manner specified by @op.
- *     @table contains the ctl_table structure for the sysctl variable.
- *     @op contains the operation (001 = search, 002 = write, 004 = read).
- *     Return 0 if permission is granted.
  * @syslog:
  *     Check permission before accessing the kernel message ring or changing
  *     logging to the console.
@@ -1383,7 +1385,6 @@ struct security_operations {
                       const kernel_cap_t *permitted);
        int (*capable) (struct task_struct *tsk, const struct cred *cred,
                        int cap, int audit);
-       int (*sysctl) (struct ctl_table *table, int op);
        int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
        int (*quota_on) (struct dentry *dentry);
        int (*syslog) (int type);
@@ -1399,6 +1400,7 @@ struct security_operations {
        int (*sb_alloc_security) (struct super_block *sb);
        void (*sb_free_security) (struct super_block *sb);
        int (*sb_copy_data) (char *orig, char *copy);
+       int (*sb_remount) (struct super_block *sb, void *data);
        int (*sb_kern_mount) (struct super_block *sb, int flags, void *data);
        int (*sb_show_options) (struct seq_file *m, struct super_block *sb);
        int (*sb_statfs) (struct dentry *dentry);
@@ -1435,7 +1437,8 @@ struct security_operations {
        int (*inode_alloc_security) (struct inode *inode);
        void (*inode_free_security) (struct inode *inode);
        int (*inode_init_security) (struct inode *inode, struct inode *dir,
-                                   char **name, void **value, size_t *len);
+                                   const struct qstr *qstr, char **name,
+                                   void **value, size_t *len);
        int (*inode_create) (struct inode *dir,
                             struct dentry *dentry, int mode);
        int (*inode_link) (struct dentry *old_dentry,
@@ -1665,7 +1668,6 @@ int security_capset(struct cred *new, const struct cred *old,
 int security_capable(const struct cred *cred, int cap);
 int security_real_capable(struct task_struct *tsk, int cap);
 int security_real_capable_noaudit(struct task_struct *tsk, int cap);
-int security_sysctl(struct ctl_table *table, int op);
 int security_quotactl(int cmds, int type, int id, struct super_block *sb);
 int security_quota_on(struct dentry *dentry);
 int security_syslog(int type);
@@ -1681,6 +1683,7 @@ int security_bprm_secureexec(struct linux_binprm *bprm);
 int security_sb_alloc(struct super_block *sb);
 void security_sb_free(struct super_block *sb);
 int security_sb_copy_data(char *orig, char *copy);
+int security_sb_remount(struct super_block *sb, void *data);
 int security_sb_kern_mount(struct super_block *sb, int flags, void *data);
 int security_sb_show_options(struct seq_file *m, struct super_block *sb);
 int security_sb_statfs(struct dentry *dentry);
@@ -1696,7 +1699,8 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
 int security_inode_alloc(struct inode *inode);
 void security_inode_free(struct inode *inode);
 int security_inode_init_security(struct inode *inode, struct inode *dir,
-                                 char **name, void **value, size_t *len);
+                                const struct qstr *qstr, char **name,
+                                void **value, size_t *len);
 int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
 int security_inode_link(struct dentry *old_dentry, struct inode *dir,
                         struct dentry *new_dentry);
@@ -1883,11 +1887,6 @@ int security_real_capable_noaudit(struct task_struct *tsk, int cap)
        return ret;
 }
 
-static inline int security_sysctl(struct ctl_table *table, int op)
-{
-       return 0;
-}
-
 static inline int security_quotactl(int cmds, int type, int id,
                                     struct super_block *sb)
 {
@@ -1964,6 +1963,11 @@ static inline int security_sb_copy_data(char *orig, char *copy)
        return 0;
 }
 
+static inline int security_sb_remount(struct super_block *sb, void *data)
+{
+       return 0;
+}
+
 static inline int security_sb_kern_mount(struct super_block *sb, int flags, void *data)
 {
        return 0;
@@ -2023,6 +2027,7 @@ static inline void security_inode_free(struct inode *inode)
 
 static inline int security_inode_init_security(struct inode *inode,
                                                struct inode *dir,
+                                               const struct qstr *qstr,
                                                char **name,
                                                void **value,
                                                size_t *len)
index 0f1bd83db98523333b9fabde37d200512b20b77e..56f6fc1178ae29b2207c73649a69e11f97aac378 100644 (file)
@@ -1685,13 +1685,8 @@ static int test_perm(int mode, int op)
 
 int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
 {
-       int error;
        int mode;
 
-       error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
-       if (error)
-               return error;
-
        if (root->permissions)
                mode = root->permissions(root, current->nsproxy, table);
        else
index 5ee67c9906022a15b566711da17b8c78e65fa16d..7c9cdc6fe137f24c2453181a2169976fb979df7d 100644 (file)
@@ -1843,8 +1843,9 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
 
        inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
        if (inode) {
-               error = security_inode_init_security(inode, dir, NULL, NULL,
-                                                    NULL);
+               error = security_inode_init_security(inode, dir,
+                                                    &dentry->d_name, NULL,
+                                                    NULL, NULL);
                if (error) {
                        if (error != -EOPNOTSUPP) {
                                iput(inode);
@@ -1983,8 +1984,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
        if (!inode)
                return -ENOSPC;
 
-       error = security_inode_init_security(inode, dir, NULL, NULL,
-                                            NULL);
+       error = security_inode_init_security(inode, dir, &dentry->d_name, NULL,
+                                            NULL, NULL);
        if (error) {
                if (error != -EOPNOTSUPP) {
                        iput(inode);
index 58a12c27870638d522cca54bef07e5f176b38748..539855ff31f977f32a1afbc16b35c9bfc2df6387 100644 (file)
@@ -43,6 +43,8 @@ int main(int argc, char *argv[])
        int i, j, k;
        int isids_len;
        FILE *fout;
+       const char *needle = "SOCKET";
+       char *substr;
 
        progname = argv[0];
 
@@ -88,6 +90,24 @@ int main(int argc, char *argv[])
                fprintf(fout, "%2d\n", i);
        }
        fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1);
+       fprintf(fout, "\nstatic inline bool security_is_socket_class(u16 kern_tclass)\n");
+       fprintf(fout, "{\n");
+       fprintf(fout, "\tbool sock = false;\n\n");
+       fprintf(fout, "\tswitch (kern_tclass) {\n");
+       for (i = 0; secclass_map[i].name; i++) {
+               struct security_class_mapping *map = &secclass_map[i];
+               substr = strstr(map->name, needle);
+               if (substr && strcmp(substr, needle) == 0)
+                       fprintf(fout, "\tcase SECCLASS_%s:\n", map->name);
+       }
+       fprintf(fout, "\t\tsock = true;\n");
+       fprintf(fout, "\t\tbreak;\n");
+       fprintf(fout, "\tdefault:\n");
+       fprintf(fout, "\t\tbreak;\n");
+       fprintf(fout, "\t}\n\n");
+       fprintf(fout, "\treturn sock;\n");
+       fprintf(fout, "}\n");
+
        fprintf(fout, "\n#endif\n");
        fclose(fout);
 
index 2a5df2b7da83be0c3d69d9bcd33dd3bd4d935a15..ab3d807accc3b43ccd26b13e881d1e6ce51a8290 100644 (file)
 
 #include <linux/security.h>
 
-static int cap_sysctl(ctl_table *table, int op)
-{
-       return 0;
-}
-
 static int cap_syslog(int type)
 {
        return 0;
@@ -59,6 +54,11 @@ static int cap_sb_copy_data(char *orig, char *copy)
        return 0;
 }
 
+static int cap_sb_remount(struct super_block *sb, void *data)
+{
+       return 0;
+}
+
 static int cap_sb_kern_mount(struct super_block *sb, int flags, void *data)
 {
        return 0;
@@ -118,7 +118,8 @@ static void cap_inode_free_security(struct inode *inode)
 }
 
 static int cap_inode_init_security(struct inode *inode, struct inode *dir,
-                                  char **name, void **value, size_t *len)
+                                  const struct qstr *qstr, char **name,
+                                  void **value, size_t *len)
 {
        return -EOPNOTSUPP;
 }
@@ -880,7 +881,6 @@ void __init security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, capable);
        set_to_cap_if_null(ops, quotactl);
        set_to_cap_if_null(ops, quota_on);
-       set_to_cap_if_null(ops, sysctl);
        set_to_cap_if_null(ops, syslog);
        set_to_cap_if_null(ops, settime);
        set_to_cap_if_null(ops, vm_enough_memory);
@@ -892,6 +892,7 @@ void __init security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, sb_alloc_security);
        set_to_cap_if_null(ops, sb_free_security);
        set_to_cap_if_null(ops, sb_copy_data);
+       set_to_cap_if_null(ops, sb_remount);
        set_to_cap_if_null(ops, sb_kern_mount);
        set_to_cap_if_null(ops, sb_show_options);
        set_to_cap_if_null(ops, sb_statfs);
index 1a4993b11446710c21a558225f5b29525630d5cd..47b8a447118fa81c19e9604014f98a9d605ae11c 100644 (file)
@@ -181,11 +181,6 @@ int security_real_capable_noaudit(struct task_struct *tsk, int cap)
        return ret;
 }
 
-int security_sysctl(struct ctl_table *table, int op)
-{
-       return security_ops->sysctl(table, op);
-}
-
 int security_quotactl(int cmds, int type, int id, struct super_block *sb)
 {
        return security_ops->quotactl(cmds, type, id, sb);
@@ -271,6 +266,11 @@ int security_sb_copy_data(char *orig, char *copy)
 }
 EXPORT_SYMBOL(security_sb_copy_data);
 
+int security_sb_remount(struct super_block *sb, void *data)
+{
+       return security_ops->sb_remount(sb, data);
+}
+
 int security_sb_kern_mount(struct super_block *sb, int flags, void *data)
 {
        return security_ops->sb_kern_mount(sb, flags, data);
@@ -335,11 +335,13 @@ void security_inode_free(struct inode *inode)
 }
 
 int security_inode_init_security(struct inode *inode, struct inode *dir,
-                                 char **name, void **value, size_t *len)
+                                const struct qstr *qstr, char **name,
+                                void **value, size_t *len)
 {
        if (unlikely(IS_PRIVATE(inode)))
                return -EOPNOTSUPP;
-       return security_ops->inode_init_security(inode, dir, name, value, len);
+       return security_ops->inode_init_security(inode, dir, qstr, name, value,
+                                                len);
 }
 EXPORT_SYMBOL(security_inode_init_security);
 
index c8d699270687e2447976af4b63b51d73749531a6..d52a9250741231fc1cd7d446681d5309654d0ce1 100644 (file)
  */
 
 #include <linux/init.h>
+#include <linux/kd.h>
 #include <linux/kernel.h>
 #include <linux/tracehook.h>
 #include <linux/errno.h>
+#include <linux/ext2_fs.h>
 #include <linux/sched.h>
 #include <linux/security.h>
 #include <linux/xattr.h>
 #include <linux/mman.h>
 #include <linux/slab.h>
 #include <linux/pagemap.h>
+#include <linux/proc_fs.h>
 #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>
 #include <linux/mount.h>
-#include <linux/proc_fs.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/tty.h>
@@ -70,7 +73,6 @@
 #include <net/ipv6.h>
 #include <linux/hugetlb.h>
 #include <linux/personality.h>
-#include <linux/sysctl.h>
 #include <linux/audit.h>
 #include <linux/string.h>
 #include <linux/selinux.h>
@@ -1120,39 +1122,35 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
 }
 
 #ifdef CONFIG_PROC_FS
-static int selinux_proc_get_sid(struct proc_dir_entry *de,
+static int selinux_proc_get_sid(struct dentry *dentry,
                                u16 tclass,
                                u32 *sid)
 {
-       int buflen, rc;
-       char *buffer, *path, *end;
+       int rc;
+       char *buffer, *path;
 
        buffer = (char *)__get_free_page(GFP_KERNEL);
        if (!buffer)
                return -ENOMEM;
 
-       buflen = PAGE_SIZE;
-       end = buffer+buflen;
-       *--end = '\0';
-       buflen--;
-       path = end-1;
-       *path = '/';
-       while (de && de != de->parent) {
-               buflen -= de->namelen + 1;
-               if (buflen < 0)
-                       break;
-               end -= de->namelen;
-               memcpy(end, de->name, de->namelen);
-               *--end = '/';
-               path = end;
-               de = de->parent;
+       path = dentry_path_raw(dentry, buffer, PAGE_SIZE);
+       if (IS_ERR(path))
+               rc = PTR_ERR(path);
+       else {
+               /* each process gets a /proc/PID/ entry. Strip off the
+                * PID part to get a valid selinux labeling.
+                * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
+               while (path[1] >= '0' && path[1] <= '9') {
+                       path[1] = '/';
+                       path++;
+               }
+               rc = security_genfs_sid("proc", path, tclass, sid);
        }
-       rc = security_genfs_sid("proc", path, tclass, sid);
        free_page((unsigned long)buffer);
        return rc;
 }
 #else
-static int selinux_proc_get_sid(struct proc_dir_entry *de,
+static int selinux_proc_get_sid(struct dentry *dentry,
                                u16 tclass,
                                u32 *sid)
 {
@@ -1300,10 +1298,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;
@@ -1316,10 +1312,9 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                isec->sid = sbsec->sid;
 
                if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
-                       struct proc_inode *proci = PROC_I(inode);
-                       if (proci->pde) {
+                       if (opt_dentry) {
                                isec->sclass = inode_mode_to_security_class(inode->i_mode);
-                               rc = selinux_proc_get_sid(proci->pde,
+                               rc = selinux_proc_get_sid(opt_dentry,
                                                          isec->sclass,
                                                          &sid);
                                if (rc)
@@ -1578,7 +1573,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;
        }
@@ -1862,82 +1857,6 @@ static int selinux_capable(struct task_struct *tsk, const struct cred *cred,
        return task_has_capability(tsk, cred, cap, audit);
 }
 
-static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
-{
-       int buflen, rc;
-       char *buffer, *path, *end;
-
-       rc = -ENOMEM;
-       buffer = (char *)__get_free_page(GFP_KERNEL);
-       if (!buffer)
-               goto out;
-
-       buflen = PAGE_SIZE;
-       end = buffer+buflen;
-       *--end = '\0';
-       buflen--;
-       path = end-1;
-       *path = '/';
-       while (table) {
-               const char *name = table->procname;
-               size_t namelen = strlen(name);
-               buflen -= namelen + 1;
-               if (buflen < 0)
-                       goto out_free;
-               end -= namelen;
-               memcpy(end, name, namelen);
-               *--end = '/';
-               path = end;
-               table = table->parent;
-       }
-       buflen -= 4;
-       if (buflen < 0)
-               goto out_free;
-       end -= 4;
-       memcpy(end, "/sys", 4);
-       path = end;
-       rc = security_genfs_sid("proc", path, tclass, sid);
-out_free:
-       free_page((unsigned long)buffer);
-out:
-       return rc;
-}
-
-static int selinux_sysctl(ctl_table *table, int op)
-{
-       int error = 0;
-       u32 av;
-       u32 tsid, sid;
-       int rc;
-
-       sid = current_sid();
-
-       rc = selinux_sysctl_get_sid(table, (op == 0001) ?
-                                   SECCLASS_DIR : SECCLASS_FILE, &tsid);
-       if (rc) {
-               /* Default to the well-defined sysctl SID. */
-               tsid = SECINITSID_SYSCTL;
-       }
-
-       /* The op values are "defined" in sysctl.c, thereby creating
-        * a bad coupling between this module and sysctl.c */
-       if (op == 001) {
-               error = avc_has_perm(sid, tsid,
-                                    SECCLASS_DIR, DIR__SEARCH, NULL);
-       } else {
-               av = 0;
-               if (op & 004)
-                       av |= FILE__READ;
-               if (op & 002)
-                       av |= FILE__WRITE;
-               if (av)
-                       error = avc_has_perm(sid, tsid,
-                                            SECCLASS_FILE, av, NULL);
-       }
-
-       return error;
-}
-
 static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
 {
        const struct cred *cred = current_cred();
@@ -2060,7 +1979,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;
        }
@@ -2443,6 +2363,91 @@ out:
        return rc;
 }
 
+static int selinux_sb_remount(struct super_block *sb, void *data)
+{
+       int rc, i, *flags;
+       struct security_mnt_opts opts;
+       char *secdata, **mount_options;
+       struct superblock_security_struct *sbsec = sb->s_security;
+
+       if (!(sbsec->flags & SE_SBINITIALIZED))
+               return 0;
+
+       if (!data)
+               return 0;
+
+       if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
+               return 0;
+
+       security_init_mnt_opts(&opts);
+       secdata = alloc_secdata();
+       if (!secdata)
+               return -ENOMEM;
+       rc = selinux_sb_copy_data(data, secdata);
+       if (rc)
+               goto out_free_secdata;
+
+       rc = selinux_parse_opts_str(secdata, &opts);
+       if (rc)
+               goto out_free_secdata;
+
+       mount_options = opts.mnt_opts;
+       flags = opts.mnt_opts_flags;
+
+       for (i = 0; i < opts.num_mnt_opts; i++) {
+               u32 sid;
+               size_t len;
+
+               if (flags[i] == SE_SBLABELSUPP)
+                       continue;
+               len = strlen(mount_options[i]);
+               rc = security_context_to_sid(mount_options[i], len, &sid);
+               if (rc) {
+                       printk(KERN_WARNING "SELinux: security_context_to_sid"
+                              "(%s) failed for (dev %s, type %s) errno=%d\n",
+                              mount_options[i], sb->s_id, sb->s_type->name, rc);
+                       goto out_free_opts;
+               }
+               rc = -EINVAL;
+               switch (flags[i]) {
+               case FSCONTEXT_MNT:
+                       if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
+                               goto out_bad_option;
+                       break;
+               case CONTEXT_MNT:
+                       if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
+                               goto out_bad_option;
+                       break;
+               case ROOTCONTEXT_MNT: {
+                       struct inode_security_struct *root_isec;
+                       root_isec = sb->s_root->d_inode->i_security;
+
+                       if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
+                               goto out_bad_option;
+                       break;
+               }
+               case DEFCONTEXT_MNT:
+                       if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
+                               goto out_bad_option;
+                       break;
+               default:
+                       goto out_free_opts;
+               }
+       }
+
+       rc = 0;
+out_free_opts:
+       security_free_mnt_opts(&opts);
+out_free_secdata:
+       free_secdata(secdata);
+       return rc;
+out_bad_option:
+       printk(KERN_WARNING "SELinux: unable to change security options "
+              "during remount (dev %s, type=%s)\n", sb->s_id,
+              sb->s_type->name);
+       goto out_free_opts;
+}
+
 static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
 {
        const struct cred *cred = current_cred();
@@ -2509,8 +2514,8 @@ static void selinux_inode_free_security(struct inode *inode)
 }
 
 static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
-                                      char **name, void **value,
-                                      size_t *len)
+                                      const struct qstr *qstr, char **name,
+                                      void **value, size_t *len)
 {
        const struct task_security_struct *tsec = current_security();
        struct inode_security_struct *dsec;
@@ -2531,7 +2536,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
        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 "
@@ -2932,16 +2937,47 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
                              unsigned long arg)
 {
        const struct cred *cred = current_cred();
-       u32 av = 0;
+       int error = 0;
 
-       if (_IOC_DIR(cmd) & _IOC_WRITE)
-               av |= FILE__WRITE;
-       if (_IOC_DIR(cmd) & _IOC_READ)
-               av |= FILE__READ;
-       if (!av)
-               av = FILE__IOCTL;
+       switch (cmd) {
+       case FIONREAD:
+       /* fall through */
+       case FIBMAP:
+       /* fall through */
+       case FIGETBSZ:
+       /* fall through */
+       case EXT2_IOC_GETFLAGS:
+       /* fall through */
+       case EXT2_IOC_GETVERSION:
+               error = file_has_perm(cred, file, FILE__GETATTR);
+               break;
+
+       case EXT2_IOC_SETFLAGS:
+       /* fall through */
+       case EXT2_IOC_SETVERSION:
+               error = file_has_perm(cred, file, FILE__SETATTR);
+               break;
+
+       /* sys_ioctl() checks */
+       case FIONBIO:
+       /* fall through */
+       case FIOASYNC:
+               error = file_has_perm(cred, file, 0);
+               break;
 
-       return file_has_perm(cred, file, av);
+       case KDSKBENT:
+       case KDSKBSENT:
+               error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG,
+                                           SECURITY_CAP_AUDIT);
+               break;
+
+       /* default case assumes that the command will go
+        * to the file's ioctl() function.
+        */
+       default:
+               error = file_has_perm(cred, file, FILE__IOCTL);
+       }
+       return error;
 }
 
 static int default_noexec;
@@ -3644,9 +3680,16 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
 
 /* socket security operations */
 
-static u32 socket_sockcreate_sid(const struct task_security_struct *tsec)
+static int socket_sockcreate_sid(const struct task_security_struct *tsec,
+                                u16 secclass, u32 *socksid)
 {
-       return tsec->sockcreate_sid ? : tsec->sid;
+       if (tsec->sockcreate_sid > SECSID_NULL) {
+               *socksid = tsec->sockcreate_sid;
+               return 0;
+       }
+
+       return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL,
+                                      socksid);
 }
 
 static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
@@ -3670,12 +3713,16 @@ static int selinux_socket_create(int family, int type,
        const struct task_security_struct *tsec = current_security();
        u32 newsid;
        u16 secclass;
+       int rc;
 
        if (kern)
                return 0;
 
-       newsid = socket_sockcreate_sid(tsec);
        secclass = socket_type_to_security_class(family, type, protocol);
+       rc = socket_sockcreate_sid(tsec, secclass, &newsid);
+       if (rc)
+               return rc;
+
        return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
 }
 
@@ -3687,12 +3734,16 @@ static int selinux_socket_post_create(struct socket *sock, int family,
        struct sk_security_struct *sksec;
        int err = 0;
 
+       isec->sclass = socket_type_to_security_class(family, type, protocol);
+
        if (kern)
                isec->sid = SECINITSID_KERNEL;
-       else
-               isec->sid = socket_sockcreate_sid(tsec);
+       else {
+               err = socket_sockcreate_sid(tsec, isec->sclass, &(isec->sid));
+               if (err)
+                       return err;
+       }
 
-       isec->sclass = socket_type_to_security_class(family, type, protocol);
        isec->initialized = 1;
 
        if (sock->sk) {
@@ -4002,7 +4053,6 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
 {
        int err = 0;
        struct sk_security_struct *sksec = sk->sk_security;
-       u32 peer_sid;
        u32 sk_sid = sksec->sid;
        struct common_audit_data ad;
        char *addrp;
@@ -4021,20 +4071,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
                        return err;
        }
 
-       if (selinux_policycap_netpeer) {
-               err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
-               if (err)
-                       return err;
-               err = avc_has_perm(sk_sid, peer_sid,
-                                  SECCLASS_PEER, PEER__RECV, &ad);
-               if (err)
-                       selinux_netlbl_err(skb, err, 0);
-       } else {
-               err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
-               if (err)
-                       return err;
-               err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
-       }
+       err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
+       if (err)
+               return err;
+       err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
 
        return err;
 }
@@ -4529,9 +4569,8 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
                                 SECCLASS_PACKET, PACKET__SEND, &ad))
                        return NF_DROP_ERR(-ECONNREFUSED);
 
-       if (selinux_policycap_netpeer)
-               if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
-                       return NF_DROP_ERR(-ECONNREFUSED);
+       if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
+               return NF_DROP_ERR(-ECONNREFUSED);
 
        return NF_ACCEPT;
 }
@@ -4574,27 +4613,14 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
         * from the sending socket, otherwise use the kernel's sid */
        sk = skb->sk;
        if (sk == NULL) {
-               switch (family) {
-               case PF_INET:
-                       if (IPCB(skb)->flags & IPSKB_FORWARDED)
-                               secmark_perm = PACKET__FORWARD_OUT;
-                       else
-                               secmark_perm = PACKET__SEND;
-                       break;
-               case PF_INET6:
-                       if (IP6CB(skb)->flags & IP6SKB_FORWARDED)
-                               secmark_perm = PACKET__FORWARD_OUT;
-                       else
-                               secmark_perm = PACKET__SEND;
-                       break;
-               default:
-                       return NF_DROP_ERR(-ECONNREFUSED);
-               }
-               if (secmark_perm == PACKET__FORWARD_OUT) {
+               if (skb->skb_iif) {
+                       secmark_perm = PACKET__FORWARD_OUT;
                        if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
                                return NF_DROP;
-               } else
+               } else {
+                       secmark_perm = PACKET__SEND;
                        peer_sid = SECINITSID_KERNEL;
+               }
        } else {
                struct sk_security_struct *sksec = sk->sk_security;
                peer_sid = sksec->sid;
@@ -4848,7 +4874,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;
        }
@@ -5402,7 +5428,6 @@ static struct security_operations selinux_ops = {
        .ptrace_traceme =               selinux_ptrace_traceme,
        .capget =                       selinux_capget,
        .capset =                       selinux_capset,
-       .sysctl =                       selinux_sysctl,
        .capable =                      selinux_capable,
        .quotactl =                     selinux_quotactl,
        .quota_on =                     selinux_quota_on,
@@ -5420,6 +5445,7 @@ static struct security_operations selinux_ops = {
        .sb_alloc_security =            selinux_sb_alloc_security,
        .sb_free_security =             selinux_sb_free_security,
        .sb_copy_data =                 selinux_sb_copy_data,
+       .sb_remount =                   selinux_sb_remount,
        .sb_kern_mount =                selinux_sb_kern_mount,
        .sb_show_options =              selinux_sb_show_options,
        .sb_statfs =                    selinux_sb_statfs,
index 7ed3663332ecf16a9f8c237e00b2963fe561cfa7..b8c53723e09bfe7d6c211bc05df35793ae9ac8b2 100644 (file)
 #define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \
            "write", "associate", "unix_read", "unix_write"
 
+/*
+ * Note: The name for any socket class should be suffixed by "socket",
+ *      and doesn't contain more than one substr of "socket".
+ */
 struct security_class_mapping secclass_map[] = {
        { "security",
          { "compute_av", "compute_create", "compute_member",
@@ -132,8 +136,7 @@ struct security_class_mapping secclass_map[] = {
        { "appletalk_socket",
          { COMMON_SOCK_PERMS, NULL } },
        { "packet",
-         { "send", "recv", "relabelto", "flow_in", "flow_out",
-           "forward_in", "forward_out", NULL } },
+         { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } },
        { "key",
          { "view", "read", "write", "search", "link", "setattr", "create",
            NULL } },
index 671273eb1115c4e7f05983af071069aea7535650..348eb00cb6685fadfef59c5864157f909b092274 100644 (file)
@@ -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"
 #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);
index 3417f9cc1cbd2d547a24abcb7db061c0391ab508..63ce2f9e441da5ed929c3341228bde3a8652f1e4 100644 (file)
@@ -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 */
 };
 
index 1ef8e4e8988019881e880d7212f35398039acca0..e96174216bc9ddb03313eb2dfca363fcdced207a 100644 (file)
@@ -512,7 +512,8 @@ int mls_compute_sid(struct context *scontext,
                    struct context *tcontext,
                    u16 tclass,
                    u32 specified,
-                   struct context *newcontext)
+                   struct context *newcontext,
+                   bool sock)
 {
        struct range_trans rtr;
        struct mls_range *r;
@@ -531,7 +532,7 @@ int mls_compute_sid(struct context *scontext,
                        return mls_range_set(newcontext, r);
                /* Fallthrough */
        case AVTAB_CHANGE:
-               if (tclass == policydb.process_class)
+               if ((tclass == policydb.process_class) || (sock == true))
                        /* Use the process MLS attributes. */
                        return mls_context_cpy(newcontext, scontext);
                else
index cd9152632e54f09ef424862540ece0b404a78c4d..037bf9d82d41d9c67c32d3d602751aa626e508b5 100644 (file)
@@ -49,7 +49,8 @@ int mls_compute_sid(struct context *scontext,
                    struct context *tcontext,
                    u16 tclass,
                    u32 specified,
-                   struct context *newcontext);
+                   struct context *newcontext,
+                   bool sock);
 
 int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
                         struct context *usercon);
index 57363562f0f886a455e900fdf59a56417b379127..e7b850ad57ee1547018ff37c4c3bb496d6bccb21 100644 (file)
@@ -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;
index 4e3ab9d0b315032a6e267072424c476aa5cd2048..732ea4a686821d048e7b09442b3f7f747c016732 100644 (file)
@@ -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;
 
index a03cfaf0ee078d03771a90f6e2e50d46b9d55db7..3e7544d2a07bb617e4d7a4eaee6cf6dcb0dd6c63 100644 (file)
@@ -201,6 +201,21 @@ static u16 unmap_class(u16 tclass)
        return tclass;
 }
 
+/*
+ * Get kernel value for class from its policy value
+ */
+static u16 map_class(u16 pol_value)
+{
+       u16 i;
+
+       for (i = 1; i < current_mapping_size; i++) {
+               if (current_mapping[i].value == pol_value)
+                       return i;
+       }
+
+       return pol_value;
+}
+
 static void map_decision(u16 tclass, struct av_decision *avd,
                         int allow_unknown)
 {
@@ -1343,10 +1358,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)
 {
@@ -1357,6 +1389,7 @@ static int security_compute_sid(u32 ssid,
        struct avtab_node *node;
        u16 tclass;
        int rc = 0;
+       bool sock;
 
        if (!ss_initialized) {
                switch (orig_tclass) {
@@ -1374,10 +1407,13 @@ static int security_compute_sid(u32 ssid,
 
        read_lock(&policy_rwlock);
 
-       if (kern)
+       if (kern) {
                tclass = unmap_class(orig_tclass);
-       else
+               sock = security_is_socket_class(orig_tclass);
+       } else {
                tclass = orig_tclass;
+               sock = security_is_socket_class(map_class(tclass));
+       }
 
        scontext = sidtab_search(&sidtab, ssid);
        if (!scontext) {
@@ -1408,7 +1444,7 @@ static int security_compute_sid(u32 ssid,
        }
 
        /* Set the role and type to default values. */
-       if (tclass == policydb.process_class) {
+       if ((tclass == policydb.process_class) || (sock == true)) {
                /* Use the current role and type of process. */
                newcontext.role = scontext->role;
                newcontext.type = scontext->type;
@@ -1442,6 +1478,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) {
@@ -1460,7 +1501,8 @@ static int security_compute_sid(u32 ssid,
 
        /* Set the MLS attributes.
           This is done last because it may allocate memory. */
-       rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);
+       rc = mls_compute_sid(scontext, tcontext, tclass, specified,
+                            &newcontext, sock);
        if (rc)
                goto out_unlock;
 
@@ -1495,22 +1537,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 +1568,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 +1590,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. */
index fff78d3b51a2ecddd1f18dd959ad99c80c090742..728c57e3d65d0bd5b47edff46367f804d35974e7 100644 (file)
@@ -208,7 +208,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
        if (!uctx)
                goto not_from_user;
 
-       if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX)
+       if (uctx->ctx_alg != XFRM_SC_ALG_SELINUX)
                return -EINVAL;
 
        str_len = uctx->ctx_len;
index 5ab3f39442f2bc4d4b5bf55656997f06450ca69d..23c7a6d0c80c5d33d2a9605e4c8ae92ed1e04739 100644 (file)
@@ -33,6 +33,7 @@
 #include <net/cipso_ipv4.h>
 #include <linux/audit.h>
 #include <linux/magic.h>
+#include <linux/dcache.h>
 #include "smack.h"
 
 #define task_security(task)    (task_cred_xxx((task), security))
@@ -501,6 +502,7 @@ static void smack_inode_free_security(struct inode *inode)
  * smack_inode_init_security - copy out the smack from an inode
  * @inode: the inode
  * @dir: unused
+ * @qstr: unused
  * @name: where to put the attribute name
  * @value: where to put the attribute value
  * @len: where to put the length of the attribute
@@ -508,7 +510,8 @@ static void smack_inode_free_security(struct inode *inode)
  * Returns 0 if it all works out, -ENOMEM if there's no memory
  */
 static int smack_inode_init_security(struct inode *inode, struct inode *dir,
-                                    char **name, void **value, size_t *len)
+                                    const struct qstr *qstr, char **name,
+                                    void **value, size_t *len)
 {
        char *isp = smk_of_inode(inode);
        char *dsp = smk_of_inode(dir);