diff options
52 files changed, 594 insertions, 323 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 0efdb65953c..a45785ab197 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -90,13 +90,14 @@ static noinline int cow_file_range(struct inode *inode, | |||
| 90 | unsigned long *nr_written, int unlock); | 90 | unsigned long *nr_written, int unlock); |
| 91 | 91 | ||
| 92 | static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, | 92 | static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, |
| 93 | struct inode *inode, struct inode *dir) | 93 | struct inode *inode, struct inode *dir, |
| 94 | const struct qstr *qstr) | ||
| 94 | { | 95 | { |
| 95 | int err; | 96 | int err; |
| 96 | 97 | ||
| 97 | err = btrfs_init_acl(trans, inode, dir); | 98 | err = btrfs_init_acl(trans, inode, dir); |
| 98 | if (!err) | 99 | if (!err) |
| 99 | err = btrfs_xattr_security_init(trans, inode, dir); | 100 | err = btrfs_xattr_security_init(trans, inode, dir, qstr); |
| 100 | return err; | 101 | return err; |
| 101 | } | 102 | } |
| 102 | 103 | ||
| @@ -4704,7 +4705,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 4704 | if (IS_ERR(inode)) | 4705 | if (IS_ERR(inode)) |
| 4705 | goto out_unlock; | 4706 | goto out_unlock; |
| 4706 | 4707 | ||
| 4707 | err = btrfs_init_inode_security(trans, inode, dir); | 4708 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
| 4708 | if (err) { | 4709 | if (err) { |
| 4709 | drop_inode = 1; | 4710 | drop_inode = 1; |
| 4710 | goto out_unlock; | 4711 | goto out_unlock; |
| @@ -4765,7 +4766,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 4765 | if (IS_ERR(inode)) | 4766 | if (IS_ERR(inode)) |
| 4766 | goto out_unlock; | 4767 | goto out_unlock; |
| 4767 | 4768 | ||
| 4768 | err = btrfs_init_inode_security(trans, inode, dir); | 4769 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
| 4769 | if (err) { | 4770 | if (err) { |
| 4770 | drop_inode = 1; | 4771 | drop_inode = 1; |
| 4771 | goto out_unlock; | 4772 | goto out_unlock; |
| @@ -4893,7 +4894,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 4893 | 4894 | ||
| 4894 | drop_on_err = 1; | 4895 | drop_on_err = 1; |
| 4895 | 4896 | ||
| 4896 | err = btrfs_init_inode_security(trans, inode, dir); | 4897 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
| 4897 | if (err) | 4898 | if (err) |
| 4898 | goto out_fail; | 4899 | goto out_fail; |
| 4899 | 4900 | ||
| @@ -7104,7 +7105,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 7104 | if (IS_ERR(inode)) | 7105 | if (IS_ERR(inode)) |
| 7105 | goto out_unlock; | 7106 | goto out_unlock; |
| 7106 | 7107 | ||
| 7107 | err = btrfs_init_inode_security(trans, inode, dir); | 7108 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
| 7108 | if (err) { | 7109 | if (err) { |
| 7109 | drop_inode = 1; | 7110 | drop_inode = 1; |
| 7110 | goto out_unlock; | 7111 | goto out_unlock; |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index a5776531dc2..d779cefcfd7 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
| @@ -370,7 +370,8 @@ int btrfs_removexattr(struct dentry *dentry, const char *name) | |||
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, | 372 | int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, |
| 373 | struct inode *inode, struct inode *dir) | 373 | struct inode *inode, struct inode *dir, |
| 374 | const struct qstr *qstr) | ||
| 374 | { | 375 | { |
| 375 | int err; | 376 | int err; |
| 376 | size_t len; | 377 | size_t len; |
| @@ -378,7 +379,8 @@ int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, | |||
| 378 | char *suffix; | 379 | char *suffix; |
| 379 | char *name; | 380 | char *name; |
| 380 | 381 | ||
| 381 | err = security_inode_init_security(inode, dir, &suffix, &value, &len); | 382 | err = security_inode_init_security(inode, dir, qstr, &suffix, &value, |
| 383 | &len); | ||
| 382 | if (err) { | 384 | if (err) { |
| 383 | if (err == -EOPNOTSUPP) | 385 | if (err == -EOPNOTSUPP) |
| 384 | return 0; | 386 | return 0; |
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h index 7a43fd640bb..b3cc8039134 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, | |||
| 37 | extern int btrfs_removexattr(struct dentry *dentry, const char *name); | 37 | extern int btrfs_removexattr(struct dentry *dentry, const char *name); |
| 38 | 38 | ||
| 39 | extern int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, | 39 | extern int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, |
| 40 | struct inode *inode, struct inode *dir); | 40 | struct inode *inode, struct inode *dir, |
| 41 | const struct qstr *qstr); | ||
| 41 | 42 | ||
| 42 | #endif /* __XATTR__ */ | 43 | #endif /* __XATTR__ */ |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 6346a2acf32..1b48c337087 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 **); | |||
| 110 | extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *, int); | 110 | extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *, int); |
| 111 | 111 | ||
| 112 | /* ialloc.c */ | 112 | /* ialloc.c */ |
| 113 | extern struct inode * ext2_new_inode (struct inode *, int); | 113 | extern struct inode * ext2_new_inode (struct inode *, int, const struct qstr *); |
| 114 | extern void ext2_free_inode (struct inode *); | 114 | extern void ext2_free_inode (struct inode *); |
| 115 | extern unsigned long ext2_count_free_inodes (struct super_block *); | 115 | extern unsigned long ext2_count_free_inodes (struct super_block *); |
| 116 | extern void ext2_check_inodes_bitmap (struct super_block *); | 116 | extern void ext2_check_inodes_bitmap (struct super_block *); |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index ad70479aabf..ee9ed31948e 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
| @@ -429,7 +429,8 @@ found: | |||
| 429 | return group; | 429 | return group; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | struct inode *ext2_new_inode(struct inode *dir, int mode) | 432 | struct inode *ext2_new_inode(struct inode *dir, int mode, |
| 433 | const struct qstr *qstr) | ||
| 433 | { | 434 | { |
| 434 | struct super_block *sb; | 435 | struct super_block *sb; |
| 435 | struct buffer_head *bitmap_bh = NULL; | 436 | struct buffer_head *bitmap_bh = NULL; |
| @@ -585,7 +586,7 @@ got: | |||
| 585 | if (err) | 586 | if (err) |
| 586 | goto fail_free_drop; | 587 | goto fail_free_drop; |
| 587 | 588 | ||
| 588 | err = ext2_init_security(inode,dir); | 589 | err = ext2_init_security(inode, dir, qstr); |
| 589 | if (err) | 590 | if (err) |
| 590 | goto fail_free_drop; | 591 | goto fail_free_drop; |
| 591 | 592 | ||
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index adb91855ccd..ed5c5d496ee 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 | |||
| 104 | 104 | ||
| 105 | dquot_initialize(dir); | 105 | dquot_initialize(dir); |
| 106 | 106 | ||
| 107 | inode = ext2_new_inode(dir, mode); | 107 | inode = ext2_new_inode(dir, mode, &dentry->d_name); |
| 108 | if (IS_ERR(inode)) | 108 | if (IS_ERR(inode)) |
| 109 | return PTR_ERR(inode); | 109 | return PTR_ERR(inode); |
| 110 | 110 | ||
| @@ -133,7 +133,7 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_ | |||
| 133 | 133 | ||
| 134 | dquot_initialize(dir); | 134 | dquot_initialize(dir); |
| 135 | 135 | ||
| 136 | inode = ext2_new_inode (dir, mode); | 136 | inode = ext2_new_inode (dir, mode, &dentry->d_name); |
| 137 | err = PTR_ERR(inode); | 137 | err = PTR_ERR(inode); |
| 138 | if (!IS_ERR(inode)) { | 138 | if (!IS_ERR(inode)) { |
| 139 | init_special_inode(inode, inode->i_mode, rdev); | 139 | init_special_inode(inode, inode->i_mode, rdev); |
| @@ -159,7 +159,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry, | |||
| 159 | 159 | ||
| 160 | dquot_initialize(dir); | 160 | dquot_initialize(dir); |
| 161 | 161 | ||
| 162 | inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO); | 162 | inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO, &dentry->d_name); |
| 163 | err = PTR_ERR(inode); | 163 | err = PTR_ERR(inode); |
| 164 | if (IS_ERR(inode)) | 164 | if (IS_ERR(inode)) |
| 165 | goto out; | 165 | goto out; |
| @@ -230,7 +230,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
| 230 | 230 | ||
| 231 | inode_inc_link_count(dir); | 231 | inode_inc_link_count(dir); |
| 232 | 232 | ||
| 233 | inode = ext2_new_inode (dir, S_IFDIR | mode); | 233 | inode = ext2_new_inode(dir, S_IFDIR | mode, &dentry->d_name); |
| 234 | err = PTR_ERR(inode); | 234 | err = PTR_ERR(inode); |
| 235 | if (IS_ERR(inode)) | 235 | if (IS_ERR(inode)) |
| 236 | goto out_dir; | 236 | goto out_dir; |
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h index a1a1c218461..5e41cccff76 100644 --- a/fs/ext2/xattr.h +++ b/fs/ext2/xattr.h | |||
| @@ -116,9 +116,11 @@ exit_ext2_xattr(void) | |||
| 116 | # endif /* CONFIG_EXT2_FS_XATTR */ | 116 | # endif /* CONFIG_EXT2_FS_XATTR */ |
| 117 | 117 | ||
| 118 | #ifdef CONFIG_EXT2_FS_SECURITY | 118 | #ifdef CONFIG_EXT2_FS_SECURITY |
| 119 | extern int ext2_init_security(struct inode *inode, struct inode *dir); | 119 | extern int ext2_init_security(struct inode *inode, struct inode *dir, |
| 120 | const struct qstr *qstr); | ||
| 120 | #else | 121 | #else |
| 121 | static inline int ext2_init_security(struct inode *inode, struct inode *dir) | 122 | static inline int ext2_init_security(struct inode *inode, struct inode *dir, |
| 123 | const struct qstr *qstr) | ||
| 122 | { | 124 | { |
| 123 | return 0; | 125 | return 0; |
| 124 | } | 126 | } |
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index 3004e15d5da..5d979b4347b 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c | |||
| @@ -47,14 +47,15 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name, | |||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | int | 49 | int |
| 50 | ext2_init_security(struct inode *inode, struct inode *dir) | 50 | ext2_init_security(struct inode *inode, struct inode *dir, |
| 51 | const struct qstr *qstr) | ||
| 51 | { | 52 | { |
| 52 | int err; | 53 | int err; |
| 53 | size_t len; | 54 | size_t len; |
| 54 | void *value; | 55 | void *value; |
| 55 | char *name; | 56 | char *name; |
| 56 | 57 | ||
| 57 | err = security_inode_init_security(inode, dir, &name, &value, &len); | 58 | err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); |
| 58 | if (err) { | 59 | if (err) { |
| 59 | if (err == -EOPNOTSUPP) | 60 | if (err == -EOPNOTSUPP) |
| 60 | return 0; | 61 | return 0; |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 9724aef2246..bfc2dc43681 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) | |||
| 404 | * For other inodes, search forward from the parent directory's block | 404 | * For other inodes, search forward from the parent directory's block |
| 405 | * group to find a free inode. | 405 | * group to find a free inode. |
| 406 | */ | 406 | */ |
| 407 | struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode) | 407 | struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, |
| 408 | const struct qstr *qstr, int mode) | ||
| 408 | { | 409 | { |
| 409 | struct super_block *sb; | 410 | struct super_block *sb; |
| 410 | struct buffer_head *bitmap_bh = NULL; | 411 | struct buffer_head *bitmap_bh = NULL; |
| @@ -589,7 +590,7 @@ got: | |||
| 589 | if (err) | 590 | if (err) |
| 590 | goto fail_free_drop; | 591 | goto fail_free_drop; |
| 591 | 592 | ||
| 592 | err = ext3_init_security(handle,inode, dir); | 593 | err = ext3_init_security(handle, inode, dir, qstr); |
| 593 | if (err) | 594 | if (err) |
| 594 | goto fail_free_drop; | 595 | goto fail_free_drop; |
| 595 | 596 | ||
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index b27ba71810e..9dba3bd69d9 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
| @@ -1710,7 +1710,7 @@ retry: | |||
| 1710 | if (IS_DIRSYNC(dir)) | 1710 | if (IS_DIRSYNC(dir)) |
| 1711 | handle->h_sync = 1; | 1711 | handle->h_sync = 1; |
| 1712 | 1712 | ||
| 1713 | inode = ext3_new_inode (handle, dir, mode); | 1713 | inode = ext3_new_inode (handle, dir, &dentry->d_name, mode); |
| 1714 | err = PTR_ERR(inode); | 1714 | err = PTR_ERR(inode); |
| 1715 | if (!IS_ERR(inode)) { | 1715 | if (!IS_ERR(inode)) { |
| 1716 | inode->i_op = &ext3_file_inode_operations; | 1716 | inode->i_op = &ext3_file_inode_operations; |
| @@ -1746,7 +1746,7 @@ retry: | |||
| 1746 | if (IS_DIRSYNC(dir)) | 1746 | if (IS_DIRSYNC(dir)) |
| 1747 | handle->h_sync = 1; | 1747 | handle->h_sync = 1; |
| 1748 | 1748 | ||
| 1749 | inode = ext3_new_inode (handle, dir, mode); | 1749 | inode = ext3_new_inode (handle, dir, &dentry->d_name, mode); |
| 1750 | err = PTR_ERR(inode); | 1750 | err = PTR_ERR(inode); |
| 1751 | if (!IS_ERR(inode)) { | 1751 | if (!IS_ERR(inode)) { |
| 1752 | init_special_inode(inode, inode->i_mode, rdev); | 1752 | init_special_inode(inode, inode->i_mode, rdev); |
| @@ -1784,7 +1784,7 @@ retry: | |||
| 1784 | if (IS_DIRSYNC(dir)) | 1784 | if (IS_DIRSYNC(dir)) |
| 1785 | handle->h_sync = 1; | 1785 | handle->h_sync = 1; |
| 1786 | 1786 | ||
| 1787 | inode = ext3_new_inode (handle, dir, S_IFDIR | mode); | 1787 | inode = ext3_new_inode (handle, dir, &dentry->d_name, S_IFDIR | mode); |
| 1788 | err = PTR_ERR(inode); | 1788 | err = PTR_ERR(inode); |
| 1789 | if (IS_ERR(inode)) | 1789 | if (IS_ERR(inode)) |
| 1790 | goto out_stop; | 1790 | goto out_stop; |
| @@ -2206,7 +2206,7 @@ retry: | |||
| 2206 | if (IS_DIRSYNC(dir)) | 2206 | if (IS_DIRSYNC(dir)) |
| 2207 | handle->h_sync = 1; | 2207 | handle->h_sync = 1; |
| 2208 | 2208 | ||
| 2209 | inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO); | 2209 | inode = ext3_new_inode (handle, dir, &dentry->d_name, S_IFLNK|S_IRWXUGO); |
| 2210 | err = PTR_ERR(inode); | 2210 | err = PTR_ERR(inode); |
| 2211 | if (IS_ERR(inode)) | 2211 | if (IS_ERR(inode)) |
| 2212 | goto out_stop; | 2212 | goto out_stop; |
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h index 377fe720116..2be4f69bfa6 100644 --- a/fs/ext3/xattr.h +++ b/fs/ext3/xattr.h | |||
| @@ -128,10 +128,10 @@ exit_ext3_xattr(void) | |||
| 128 | 128 | ||
| 129 | #ifdef CONFIG_EXT3_FS_SECURITY | 129 | #ifdef CONFIG_EXT3_FS_SECURITY |
| 130 | extern int ext3_init_security(handle_t *handle, struct inode *inode, | 130 | extern int ext3_init_security(handle_t *handle, struct inode *inode, |
| 131 | struct inode *dir); | 131 | struct inode *dir, const struct qstr *qstr); |
| 132 | #else | 132 | #else |
| 133 | static inline int ext3_init_security(handle_t *handle, struct inode *inode, | 133 | static inline int ext3_init_security(handle_t *handle, struct inode *inode, |
| 134 | struct inode *dir) | 134 | struct inode *dir, const struct qstr *qstr) |
| 135 | { | 135 | { |
| 136 | return 0; | 136 | return 0; |
| 137 | } | 137 | } |
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c index 03a99bfc59f..b8d9f83aa5c 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, | |||
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | int | 51 | int |
| 52 | ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir) | 52 | ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir, |
| 53 | const struct qstr *qstr) | ||
| 53 | { | 54 | { |
| 54 | int err; | 55 | int err; |
| 55 | size_t len; | 56 | size_t len; |
| 56 | void *value; | 57 | void *value; |
| 57 | char *name; | 58 | char *name; |
| 58 | 59 | ||
| 59 | err = security_inode_init_security(inode, dir, &name, &value, &len); | 60 | err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); |
| 60 | if (err) { | 61 | if (err) { |
| 61 | if (err == -EOPNOTSUPP) | 62 | if (err == -EOPNOTSUPP) |
| 62 | return 0; | 63 | return 0; |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index eb9097aec6f..78b79e1bd7e 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -1042,7 +1042,7 @@ got: | |||
| 1042 | if (err) | 1042 | if (err) |
| 1043 | goto fail_free_drop; | 1043 | goto fail_free_drop; |
| 1044 | 1044 | ||
| 1045 | err = ext4_init_security(handle, inode, dir); | 1045 | err = ext4_init_security(handle, inode, dir, qstr); |
| 1046 | if (err) | 1046 | if (err) |
| 1047 | goto fail_free_drop; | 1047 | goto fail_free_drop; |
| 1048 | 1048 | ||
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 1ef16520b95..25b7387ff18 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h | |||
| @@ -145,10 +145,10 @@ ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, | |||
| 145 | 145 | ||
| 146 | #ifdef CONFIG_EXT4_FS_SECURITY | 146 | #ifdef CONFIG_EXT4_FS_SECURITY |
| 147 | extern int ext4_init_security(handle_t *handle, struct inode *inode, | 147 | extern int ext4_init_security(handle_t *handle, struct inode *inode, |
| 148 | struct inode *dir); | 148 | struct inode *dir, const struct qstr *qstr); |
| 149 | #else | 149 | #else |
| 150 | static inline int ext4_init_security(handle_t *handle, struct inode *inode, | 150 | static inline int ext4_init_security(handle_t *handle, struct inode *inode, |
| 151 | struct inode *dir) | 151 | struct inode *dir, const struct qstr *qstr) |
| 152 | { | 152 | { |
| 153 | return 0; | 153 | return 0; |
| 154 | } | 154 | } |
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c index 9b21268e121..007c3bfbf09 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, | |||
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | int | 51 | int |
| 52 | ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir) | 52 | ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir, |
| 53 | const struct qstr *qstr) | ||
| 53 | { | 54 | { |
| 54 | int err; | 55 | int err; |
| 55 | size_t len; | 56 | size_t len; |
| 56 | void *value; | 57 | void *value; |
| 57 | char *name; | 58 | char *name; |
| 58 | 59 | ||
| 59 | err = security_inode_init_security(inode, dir, &name, &value, &len); | 60 | err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); |
| 60 | if (err) { | 61 | if (err) { |
| 61 | if (err == -EOPNOTSUPP) | 62 | if (err == -EOPNOTSUPP) |
| 62 | return 0; | 63 | return 0; |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 7aa7d4f8984..97d54a28776 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
| @@ -763,14 +763,15 @@ fail: | |||
| 763 | return error; | 763 | return error; |
| 764 | } | 764 | } |
| 765 | 765 | ||
| 766 | static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) | 766 | static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip, |
| 767 | const struct qstr *qstr) | ||
| 767 | { | 768 | { |
| 768 | int err; | 769 | int err; |
| 769 | size_t len; | 770 | size_t len; |
| 770 | void *value; | 771 | void *value; |
| 771 | char *name; | 772 | char *name; |
| 772 | 773 | ||
| 773 | err = security_inode_init_security(&ip->i_inode, &dip->i_inode, | 774 | err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr, |
| 774 | &name, &value, &len); | 775 | &name, &value, &len); |
| 775 | 776 | ||
| 776 | if (err) { | 777 | if (err) { |
| @@ -854,7 +855,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
| 854 | if (error) | 855 | if (error) |
| 855 | goto fail_gunlock2; | 856 | goto fail_gunlock2; |
| 856 | 857 | ||
| 857 | error = gfs2_security_init(dip, GFS2_I(inode)); | 858 | error = gfs2_security_init(dip, GFS2_I(inode), name); |
| 858 | if (error) | 859 | if (error) |
| 859 | goto fail_gunlock2; | 860 | goto fail_gunlock2; |
| 860 | 861 | ||
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 92978658ed1..82faddd1f32 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, | |||
| 215 | no chance of AB-BA deadlock involving its f->sem). */ | 215 | no chance of AB-BA deadlock involving its f->sem). */ |
| 216 | mutex_unlock(&f->sem); | 216 | mutex_unlock(&f->sem); |
| 217 | 217 | ||
| 218 | ret = jffs2_do_create(c, dir_f, f, ri, | 218 | ret = jffs2_do_create(c, dir_f, f, ri, &dentry->d_name); |
| 219 | dentry->d_name.name, dentry->d_name.len); | ||
| 220 | if (ret) | 219 | if (ret) |
| 221 | goto fail; | 220 | goto fail; |
| 222 | 221 | ||
| @@ -386,7 +385,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
| 386 | 385 | ||
| 387 | jffs2_complete_reservation(c); | 386 | jffs2_complete_reservation(c); |
| 388 | 387 | ||
| 389 | ret = jffs2_init_security(inode, dir_i); | 388 | ret = jffs2_init_security(inode, dir_i, &dentry->d_name); |
| 390 | if (ret) | 389 | if (ret) |
| 391 | goto fail; | 390 | goto fail; |
| 392 | 391 | ||
| @@ -530,7 +529,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
| 530 | 529 | ||
| 531 | jffs2_complete_reservation(c); | 530 | jffs2_complete_reservation(c); |
| 532 | 531 | ||
| 533 | ret = jffs2_init_security(inode, dir_i); | 532 | ret = jffs2_init_security(inode, dir_i, &dentry->d_name); |
| 534 | if (ret) | 533 | if (ret) |
| 535 | goto fail; | 534 | goto fail; |
| 536 | 535 | ||
| @@ -703,7 +702,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
| 703 | 702 | ||
| 704 | jffs2_complete_reservation(c); | 703 | jffs2_complete_reservation(c); |
| 705 | 704 | ||
| 706 | ret = jffs2_init_security(inode, dir_i); | 705 | ret = jffs2_init_security(inode, dir_i, &dentry->d_name); |
| 707 | if (ret) | 706 | if (ret) |
| 708 | goto fail; | 707 | goto fail; |
| 709 | 708 | ||
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h index 5a53d9bdb2b..e4619b00f7c 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, | |||
| 401 | struct jffs2_raw_inode *ri, unsigned char *buf, | 401 | struct jffs2_raw_inode *ri, unsigned char *buf, |
| 402 | uint32_t offset, uint32_t writelen, uint32_t *retlen); | 402 | uint32_t offset, uint32_t writelen, uint32_t *retlen); |
| 403 | int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, | 403 | int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, |
| 404 | struct jffs2_raw_inode *ri, const char *name, int namelen); | 404 | struct jffs2_raw_inode *ri, const struct qstr *qstr); |
| 405 | int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, | 405 | int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, |
| 406 | int namelen, struct jffs2_inode_info *dead_f, uint32_t time); | 406 | int namelen, struct jffs2_inode_info *dead_f, uint32_t time); |
| 407 | int jffs2_do_link(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, | 407 | 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 239f51216a6..cfeb7164b08 100644 --- a/fs/jffs2/security.c +++ b/fs/jffs2/security.c | |||
| @@ -23,14 +23,15 @@ | |||
| 23 | #include "nodelist.h" | 23 | #include "nodelist.h" |
| 24 | 24 | ||
| 25 | /* ---- Initial Security Label Attachment -------------- */ | 25 | /* ---- Initial Security Label Attachment -------------- */ |
| 26 | int jffs2_init_security(struct inode *inode, struct inode *dir) | 26 | int jffs2_init_security(struct inode *inode, struct inode *dir, |
| 27 | const struct qstr *qstr) | ||
| 27 | { | 28 | { |
| 28 | int rc; | 29 | int rc; |
| 29 | size_t len; | 30 | size_t len; |
| 30 | void *value; | 31 | void *value; |
| 31 | char *name; | 32 | char *name; |
| 32 | 33 | ||
| 33 | rc = security_inode_init_security(inode, dir, &name, &value, &len); | 34 | rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len); |
| 34 | if (rc) { | 35 | if (rc) { |
| 35 | if (rc == -EOPNOTSUPP) | 36 | if (rc == -EOPNOTSUPP) |
| 36 | return 0; | 37 | return 0; |
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index c819eb0e982..30d175b6d29 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c | |||
| @@ -424,7 +424,9 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
| 424 | return ret; | 424 | return ret; |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | 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) | 427 | int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, |
| 428 | struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, | ||
| 429 | const struct qstr *qstr) | ||
| 428 | { | 430 | { |
| 429 | struct jffs2_raw_dirent *rd; | 431 | struct jffs2_raw_dirent *rd; |
| 430 | struct jffs2_full_dnode *fn; | 432 | 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 | |||
| 466 | mutex_unlock(&f->sem); | 468 | mutex_unlock(&f->sem); |
| 467 | jffs2_complete_reservation(c); | 469 | jffs2_complete_reservation(c); |
| 468 | 470 | ||
| 469 | ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode); | 471 | ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode, qstr); |
| 470 | if (ret) | 472 | if (ret) |
| 471 | return ret; | 473 | return ret; |
| 472 | ret = jffs2_init_acl_post(&f->vfs_inode); | 474 | ret = jffs2_init_acl_post(&f->vfs_inode); |
| 473 | if (ret) | 475 | if (ret) |
| 474 | return ret; | 476 | return ret; |
| 475 | 477 | ||
| 476 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, | 478 | ret = jffs2_reserve_space(c, sizeof(*rd)+qstr->len, &alloclen, |
| 477 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | 479 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(qstr->len)); |
| 478 | 480 | ||
| 479 | if (ret) { | 481 | if (ret) { |
| 480 | /* Eep. */ | 482 | /* Eep. */ |
| @@ -493,19 +495,19 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str | |||
| 493 | 495 | ||
| 494 | rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); | 496 | rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); |
| 495 | rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); | 497 | rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); |
| 496 | rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); | 498 | rd->totlen = cpu_to_je32(sizeof(*rd) + qstr->len); |
| 497 | rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); | 499 | rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); |
| 498 | 500 | ||
| 499 | rd->pino = cpu_to_je32(dir_f->inocache->ino); | 501 | rd->pino = cpu_to_je32(dir_f->inocache->ino); |
| 500 | rd->version = cpu_to_je32(++dir_f->highest_version); | 502 | rd->version = cpu_to_je32(++dir_f->highest_version); |
| 501 | rd->ino = ri->ino; | 503 | rd->ino = ri->ino; |
| 502 | rd->mctime = ri->ctime; | 504 | rd->mctime = ri->ctime; |
| 503 | rd->nsize = namelen; | 505 | rd->nsize = qstr->len; |
| 504 | rd->type = DT_REG; | 506 | rd->type = DT_REG; |
| 505 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); | 507 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); |
| 506 | rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); | 508 | rd->name_crc = cpu_to_je32(crc32(0, qstr->name, qstr->len)); |
| 507 | 509 | ||
| 508 | fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL); | 510 | fd = jffs2_write_dirent(c, dir_f, rd, qstr->name, qstr->len, ALLOC_NORMAL); |
| 509 | 511 | ||
| 510 | jffs2_free_raw_dirent(rd); | 512 | jffs2_free_raw_dirent(rd); |
| 511 | 513 | ||
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index cf4f5759b42..7be4beb306f 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); | |||
| 121 | #endif /* CONFIG_JFFS2_FS_XATTR */ | 121 | #endif /* CONFIG_JFFS2_FS_XATTR */ |
| 122 | 122 | ||
| 123 | #ifdef CONFIG_JFFS2_FS_SECURITY | 123 | #ifdef CONFIG_JFFS2_FS_SECURITY |
| 124 | extern int jffs2_init_security(struct inode *inode, struct inode *dir); | 124 | extern int jffs2_init_security(struct inode *inode, struct inode *dir, |
| 125 | const struct qstr *qstr); | ||
| 125 | extern const struct xattr_handler jffs2_security_xattr_handler; | 126 | extern const struct xattr_handler jffs2_security_xattr_handler; |
| 126 | #else | 127 | #else |
| 127 | #define jffs2_init_security(inode,dir) (0) | 128 | #define jffs2_init_security(inode,dir,qstr) (0) |
| 128 | #endif /* CONFIG_JFFS2_FS_SECURITY */ | 129 | #endif /* CONFIG_JFFS2_FS_SECURITY */ |
| 129 | 130 | ||
| 130 | #endif /* _JFFS2_FS_XATTR_H_ */ | 131 | #endif /* _JFFS2_FS_XATTR_H_ */ |
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h index 88b6cc535bf..e9e100fd7c0 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); | |||
| 62 | extern int jfs_removexattr(struct dentry *, const char *); | 62 | extern int jfs_removexattr(struct dentry *, const char *); |
| 63 | 63 | ||
| 64 | #ifdef CONFIG_JFS_SECURITY | 64 | #ifdef CONFIG_JFS_SECURITY |
| 65 | extern int jfs_init_security(tid_t, struct inode *, struct inode *); | 65 | extern int jfs_init_security(tid_t, struct inode *, struct inode *, |
| 66 | const struct qstr *); | ||
| 66 | #else | 67 | #else |
| 67 | static inline int jfs_init_security(tid_t tid, struct inode *inode, | 68 | static inline int jfs_init_security(tid_t tid, struct inode *inode, |
| 68 | struct inode *dir) | 69 | struct inode *dir, const struct qstr *qstr) |
| 69 | { | 70 | { |
| 70 | return 0; | 71 | return 0; |
| 71 | } | 72 | } |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 81ead850ddb..2a37d2fdd70 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
| @@ -115,7 +115,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
| 115 | if (rc) | 115 | if (rc) |
| 116 | goto out3; | 116 | goto out3; |
| 117 | 117 | ||
| 118 | rc = jfs_init_security(tid, ip, dip); | 118 | rc = jfs_init_security(tid, ip, dip, &dentry->d_name); |
| 119 | if (rc) { | 119 | if (rc) { |
| 120 | txAbort(tid, 0); | 120 | txAbort(tid, 0); |
| 121 | goto out3; | 121 | goto out3; |
| @@ -253,7 +253,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
| 253 | if (rc) | 253 | if (rc) |
| 254 | goto out3; | 254 | goto out3; |
| 255 | 255 | ||
| 256 | rc = jfs_init_security(tid, ip, dip); | 256 | rc = jfs_init_security(tid, ip, dip, &dentry->d_name); |
| 257 | if (rc) { | 257 | if (rc) { |
| 258 | txAbort(tid, 0); | 258 | txAbort(tid, 0); |
| 259 | goto out3; | 259 | goto out3; |
| @@ -932,7 +932,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
| 932 | mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT); | 932 | mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT); |
| 933 | mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); | 933 | mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); |
| 934 | 934 | ||
| 935 | rc = jfs_init_security(tid, ip, dip); | 935 | rc = jfs_init_security(tid, ip, dip, &dentry->d_name); |
| 936 | if (rc) | 936 | if (rc) |
| 937 | goto out3; | 937 | goto out3; |
| 938 | 938 | ||
| @@ -1395,7 +1395,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 1395 | if (rc) | 1395 | if (rc) |
| 1396 | goto out3; | 1396 | goto out3; |
| 1397 | 1397 | ||
| 1398 | rc = jfs_init_security(tid, ip, dir); | 1398 | rc = jfs_init_security(tid, ip, dir, &dentry->d_name); |
| 1399 | if (rc) { | 1399 | if (rc) { |
| 1400 | txAbort(tid, 0); | 1400 | txAbort(tid, 0); |
| 1401 | goto out3; | 1401 | goto out3; |
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 2d7f165d0f1..3fa4c32272d 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
| @@ -1091,7 +1091,8 @@ int jfs_removexattr(struct dentry *dentry, const char *name) | |||
| 1091 | } | 1091 | } |
| 1092 | 1092 | ||
| 1093 | #ifdef CONFIG_JFS_SECURITY | 1093 | #ifdef CONFIG_JFS_SECURITY |
| 1094 | int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir) | 1094 | int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir, |
| 1095 | const struct qstr *qstr) | ||
| 1095 | { | 1096 | { |
| 1096 | int rc; | 1097 | int rc; |
| 1097 | size_t len; | 1098 | size_t len; |
| @@ -1099,7 +1100,8 @@ int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir) | |||
| 1099 | char *suffix; | 1100 | char *suffix; |
| 1100 | char *name; | 1101 | char *name; |
| 1101 | 1102 | ||
| 1102 | rc = security_inode_init_security(inode, dir, &suffix, &value, &len); | 1103 | rc = security_inode_init_security(inode, dir, qstr, &suffix, &value, |
| 1104 | &len); | ||
| 1103 | if (rc) { | 1105 | if (rc) { |
| 1104 | if (rc == -EOPNOTSUPP) | 1106 | if (rc == -EOPNOTSUPP) |
| 1105 | return 0; | 1107 | return 0; |
diff --git a/fs/namespace.c b/fs/namespace.c index d1edf26025d..a66feed7311 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -1767,6 +1767,10 @@ static int do_remount(struct path *path, int flags, int mnt_flags, | |||
| 1767 | if (path->dentry != path->mnt->mnt_root) | 1767 | if (path->dentry != path->mnt->mnt_root) |
| 1768 | return -EINVAL; | 1768 | return -EINVAL; |
| 1769 | 1769 | ||
| 1770 | err = security_sb_remount(sb, data); | ||
| 1771 | if (err) | ||
| 1772 | return err; | ||
| 1773 | |||
| 1770 | down_write(&sb->s_umount); | 1774 | down_write(&sb->s_umount); |
| 1771 | if (flags & MS_BIND) | 1775 | if (flags & MS_BIND) |
| 1772 | err = change_mount_flags(path->mnt, flags); | 1776 | err = change_mount_flags(path->mnt, flags); |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 849fb4a2e81..d6c25d76b53 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -293,7 +293,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | /* get security xattr */ | 295 | /* get security xattr */ |
| 296 | status = ocfs2_init_security_get(inode, dir, &si); | 296 | status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si); |
| 297 | if (status) { | 297 | if (status) { |
| 298 | if (status == -EOPNOTSUPP) | 298 | if (status == -EOPNOTSUPP) |
| 299 | si.enable = 0; | 299 | si.enable = 0; |
| @@ -1665,7 +1665,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
| 1665 | } | 1665 | } |
| 1666 | 1666 | ||
| 1667 | /* get security xattr */ | 1667 | /* get security xattr */ |
| 1668 | status = ocfs2_init_security_get(inode, dir, &si); | 1668 | status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si); |
| 1669 | if (status) { | 1669 | if (status) { |
| 1670 | if (status == -EOPNOTSUPP) | 1670 | if (status == -EOPNOTSUPP) |
| 1671 | si.enable = 0; | 1671 | si.enable = 0; |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 19ebc5aad39..35798b88042 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -4328,7 +4328,8 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir, | |||
| 4328 | 4328 | ||
| 4329 | /* If the security isn't preserved, we need to re-initialize them. */ | 4329 | /* If the security isn't preserved, we need to re-initialize them. */ |
| 4330 | if (!preserve) { | 4330 | if (!preserve) { |
| 4331 | error = ocfs2_init_security_and_acl(dir, new_orphan_inode); | 4331 | error = ocfs2_init_security_and_acl(dir, new_orphan_inode, |
| 4332 | &new_dentry->d_name); | ||
| 4332 | if (error) | 4333 | if (error) |
| 4333 | mlog_errno(error); | 4334 | mlog_errno(error); |
| 4334 | } | 4335 | } |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 67cd4391464..6bb602486c6 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -7185,7 +7185,8 @@ out: | |||
| 7185 | * must not hold any lock expect i_mutex. | 7185 | * must not hold any lock expect i_mutex. |
| 7186 | */ | 7186 | */ |
| 7187 | int ocfs2_init_security_and_acl(struct inode *dir, | 7187 | int ocfs2_init_security_and_acl(struct inode *dir, |
| 7188 | struct inode *inode) | 7188 | struct inode *inode, |
| 7189 | const struct qstr *qstr) | ||
| 7189 | { | 7190 | { |
| 7190 | int ret = 0; | 7191 | int ret = 0; |
| 7191 | struct buffer_head *dir_bh = NULL; | 7192 | struct buffer_head *dir_bh = NULL; |
| @@ -7193,7 +7194,7 @@ int ocfs2_init_security_and_acl(struct inode *dir, | |||
| 7193 | .enable = 1, | 7194 | .enable = 1, |
| 7194 | }; | 7195 | }; |
| 7195 | 7196 | ||
| 7196 | ret = ocfs2_init_security_get(inode, dir, &si); | 7197 | ret = ocfs2_init_security_get(inode, dir, qstr, &si); |
| 7197 | if (!ret) { | 7198 | if (!ret) { |
| 7198 | ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY, | 7199 | ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY, |
| 7199 | si.name, si.value, si.value_len, | 7200 | si.name, si.value, si.value_len, |
| @@ -7261,13 +7262,14 @@ static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name, | |||
| 7261 | 7262 | ||
| 7262 | int ocfs2_init_security_get(struct inode *inode, | 7263 | int ocfs2_init_security_get(struct inode *inode, |
| 7263 | struct inode *dir, | 7264 | struct inode *dir, |
| 7265 | const struct qstr *qstr, | ||
| 7264 | struct ocfs2_security_xattr_info *si) | 7266 | struct ocfs2_security_xattr_info *si) |
| 7265 | { | 7267 | { |
| 7266 | /* check whether ocfs2 support feature xattr */ | 7268 | /* check whether ocfs2 support feature xattr */ |
| 7267 | if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb))) | 7269 | if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb))) |
| 7268 | return -EOPNOTSUPP; | 7270 | return -EOPNOTSUPP; |
| 7269 | return security_inode_init_security(inode, dir, &si->name, &si->value, | 7271 | return security_inode_init_security(inode, dir, qstr, &si->name, |
| 7270 | &si->value_len); | 7272 | &si->value, &si->value_len); |
| 7271 | } | 7273 | } |
| 7272 | 7274 | ||
| 7273 | int ocfs2_init_security_set(handle_t *handle, | 7275 | int ocfs2_init_security_set(handle_t *handle, |
diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h index aa64bb37a65..d63cfb72316 100644 --- a/fs/ocfs2/xattr.h +++ b/fs/ocfs2/xattr.h | |||
| @@ -57,6 +57,7 @@ int ocfs2_has_inline_xattr_value_outside(struct inode *inode, | |||
| 57 | struct ocfs2_dinode *di); | 57 | struct ocfs2_dinode *di); |
| 58 | int ocfs2_xattr_remove(struct inode *, struct buffer_head *); | 58 | int ocfs2_xattr_remove(struct inode *, struct buffer_head *); |
| 59 | int ocfs2_init_security_get(struct inode *, struct inode *, | 59 | int ocfs2_init_security_get(struct inode *, struct inode *, |
| 60 | const struct qstr *, | ||
| 60 | struct ocfs2_security_xattr_info *); | 61 | struct ocfs2_security_xattr_info *); |
| 61 | int ocfs2_init_security_set(handle_t *, struct inode *, | 62 | int ocfs2_init_security_set(handle_t *, struct inode *, |
| 62 | struct buffer_head *, | 63 | struct buffer_head *, |
| @@ -94,5 +95,6 @@ int ocfs2_reflink_xattrs(struct inode *old_inode, | |||
| 94 | struct buffer_head *new_bh, | 95 | struct buffer_head *new_bh, |
| 95 | bool preserve_security); | 96 | bool preserve_security); |
| 96 | int ocfs2_init_security_and_acl(struct inode *dir, | 97 | int ocfs2_init_security_and_acl(struct inode *dir, |
| 97 | struct inode *inode); | 98 | struct inode *inode, |
| 99 | const struct qstr *qstr); | ||
| 98 | #endif /* OCFS2_XATTR_H */ | 100 | #endif /* OCFS2_XATTR_H */ |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 09a1f92a34e..fb707e018a8 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
| @@ -32,7 +32,6 @@ static struct inode *proc_sys_make_inode(struct super_block *sb, | |||
| 32 | ei->sysctl_entry = table; | 32 | ei->sysctl_entry = table; |
| 33 | 33 | ||
| 34 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 34 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
| 35 | inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */ | ||
| 36 | inode->i_mode = table->mode; | 35 | inode->i_mode = table->mode; |
| 37 | if (!table->child) { | 36 | if (!table->child) { |
| 38 | inode->i_mode |= S_IFREG; | 37 | inode->i_mode |= S_IFREG; |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 68fdf45cc6c..82f45542dcf 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, | |||
| 593 | new_inode_init(inode, dir, mode); | 593 | new_inode_init(inode, dir, mode); |
| 594 | 594 | ||
| 595 | jbegin_count += reiserfs_cache_default_acl(dir); | 595 | jbegin_count += reiserfs_cache_default_acl(dir); |
| 596 | retval = reiserfs_security_init(dir, inode, &security); | 596 | retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security); |
| 597 | if (retval < 0) { | 597 | if (retval < 0) { |
| 598 | drop_new_inode(inode); | 598 | drop_new_inode(inode); |
| 599 | return retval; | 599 | return retval; |
| @@ -667,7 +667,7 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
| 667 | new_inode_init(inode, dir, mode); | 667 | new_inode_init(inode, dir, mode); |
| 668 | 668 | ||
| 669 | jbegin_count += reiserfs_cache_default_acl(dir); | 669 | jbegin_count += reiserfs_cache_default_acl(dir); |
| 670 | retval = reiserfs_security_init(dir, inode, &security); | 670 | retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security); |
| 671 | if (retval < 0) { | 671 | if (retval < 0) { |
| 672 | drop_new_inode(inode); | 672 | drop_new_inode(inode); |
| 673 | return retval; | 673 | return retval; |
| @@ -747,7 +747,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 747 | new_inode_init(inode, dir, mode); | 747 | new_inode_init(inode, dir, mode); |
| 748 | 748 | ||
| 749 | jbegin_count += reiserfs_cache_default_acl(dir); | 749 | jbegin_count += reiserfs_cache_default_acl(dir); |
| 750 | retval = reiserfs_security_init(dir, inode, &security); | 750 | retval = reiserfs_security_init(dir, inode, &dentry->d_name, &security); |
| 751 | if (retval < 0) { | 751 | if (retval < 0) { |
| 752 | drop_new_inode(inode); | 752 | drop_new_inode(inode); |
| 753 | return retval; | 753 | return retval; |
| @@ -1032,7 +1032,8 @@ static int reiserfs_symlink(struct inode *parent_dir, | |||
| 1032 | } | 1032 | } |
| 1033 | new_inode_init(inode, parent_dir, mode); | 1033 | new_inode_init(inode, parent_dir, mode); |
| 1034 | 1034 | ||
| 1035 | retval = reiserfs_security_init(parent_dir, inode, &security); | 1035 | retval = reiserfs_security_init(parent_dir, inode, &dentry->d_name, |
| 1036 | &security); | ||
| 1036 | if (retval < 0) { | 1037 | if (retval < 0) { |
| 1037 | drop_new_inode(inode); | 1038 | drop_new_inode(inode); |
| 1038 | return retval; | 1039 | return retval; |
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index 237c6928d3c..ef66c18a933 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c | |||
| @@ -54,6 +54,7 @@ static size_t security_list(struct dentry *dentry, char *list, size_t list_len, | |||
| 54 | * of blocks needed for the transaction. If successful, reiserfs_security | 54 | * of blocks needed for the transaction. If successful, reiserfs_security |
| 55 | * must be released using reiserfs_security_free when the caller is done. */ | 55 | * must be released using reiserfs_security_free when the caller is done. */ |
| 56 | int reiserfs_security_init(struct inode *dir, struct inode *inode, | 56 | int reiserfs_security_init(struct inode *dir, struct inode *inode, |
| 57 | const struct qstr *qstr, | ||
| 57 | struct reiserfs_security_handle *sec) | 58 | struct reiserfs_security_handle *sec) |
| 58 | { | 59 | { |
| 59 | int blocks = 0; | 60 | int blocks = 0; |
| @@ -65,7 +66,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode, | |||
| 65 | if (IS_PRIVATE(dir)) | 66 | if (IS_PRIVATE(dir)) |
| 66 | return 0; | 67 | return 0; |
| 67 | 68 | ||
| 68 | error = security_inode_init_security(inode, dir, &sec->name, | 69 | error = security_inode_init_security(inode, dir, qstr, &sec->name, |
| 69 | &sec->value, &sec->length); | 70 | &sec->value, &sec->length); |
| 70 | if (error) { | 71 | if (error) { |
| 71 | if (error == -EOPNOTSUPP) | 72 | if (error == -EOPNOTSUPP) |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index bd5727852fd..9ff7fc603d2 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -102,7 +102,8 @@ xfs_mark_inode_dirty( | |||
| 102 | STATIC int | 102 | STATIC int |
| 103 | xfs_init_security( | 103 | xfs_init_security( |
| 104 | struct inode *inode, | 104 | struct inode *inode, |
| 105 | struct inode *dir) | 105 | struct inode *dir, |
| 106 | const struct qstr *qstr) | ||
| 106 | { | 107 | { |
| 107 | struct xfs_inode *ip = XFS_I(inode); | 108 | struct xfs_inode *ip = XFS_I(inode); |
| 108 | size_t length; | 109 | size_t length; |
| @@ -110,7 +111,7 @@ xfs_init_security( | |||
| 110 | unsigned char *name; | 111 | unsigned char *name; |
| 111 | int error; | 112 | int error; |
| 112 | 113 | ||
| 113 | error = security_inode_init_security(inode, dir, (char **)&name, | 114 | error = security_inode_init_security(inode, dir, qstr, (char **)&name, |
| 114 | &value, &length); | 115 | &value, &length); |
| 115 | if (error) { | 116 | if (error) { |
| 116 | if (error == -EOPNOTSUPP) | 117 | if (error == -EOPNOTSUPP) |
| @@ -194,7 +195,7 @@ xfs_vn_mknod( | |||
| 194 | 195 | ||
| 195 | inode = VFS_I(ip); | 196 | inode = VFS_I(ip); |
| 196 | 197 | ||
| 197 | error = xfs_init_security(inode, dir); | 198 | error = xfs_init_security(inode, dir, &dentry->d_name); |
| 198 | if (unlikely(error)) | 199 | if (unlikely(error)) |
| 199 | goto out_cleanup_inode; | 200 | goto out_cleanup_inode; |
| 200 | 201 | ||
| @@ -367,7 +368,7 @@ xfs_vn_symlink( | |||
| 367 | 368 | ||
| 368 | inode = VFS_I(cip); | 369 | inode = VFS_I(cip); |
| 369 | 370 | ||
| 370 | error = xfs_init_security(inode, dir); | 371 | error = xfs_init_security(inode, dir, &dentry->d_name); |
| 371 | if (unlikely(error)) | 372 | if (unlikely(error)) |
| 372 | goto out_cleanup_inode; | 373 | goto out_cleanup_inode; |
| 373 | 374 | ||
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 65990ef612f..6043c64c207 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h | |||
| @@ -884,7 +884,8 @@ extern int ext3fs_dirhash(const char *name, int len, struct | |||
| 884 | dx_hash_info *hinfo); | 884 | dx_hash_info *hinfo); |
| 885 | 885 | ||
| 886 | /* ialloc.c */ | 886 | /* ialloc.c */ |
| 887 | extern struct inode * ext3_new_inode (handle_t *, struct inode *, int); | 887 | extern struct inode * ext3_new_inode (handle_t *, struct inode *, |
| 888 | const struct qstr *, int); | ||
| 888 | extern void ext3_free_inode (handle_t *, struct inode *); | 889 | extern void ext3_free_inode (handle_t *, struct inode *); |
| 889 | extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); | 890 | extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); |
| 890 | extern unsigned long ext3_count_free_inodes (struct super_block *); | 891 | 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 3b94c91f20a..6deef5dc95f 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h | |||
| @@ -63,6 +63,7 @@ extern const struct xattr_handler reiserfs_xattr_trusted_handler; | |||
| 63 | extern const struct xattr_handler reiserfs_xattr_security_handler; | 63 | extern const struct xattr_handler reiserfs_xattr_security_handler; |
| 64 | #ifdef CONFIG_REISERFS_FS_SECURITY | 64 | #ifdef CONFIG_REISERFS_FS_SECURITY |
| 65 | int reiserfs_security_init(struct inode *dir, struct inode *inode, | 65 | int reiserfs_security_init(struct inode *dir, struct inode *inode, |
| 66 | const struct qstr *qstr, | ||
| 66 | struct reiserfs_security_handle *sec); | 67 | struct reiserfs_security_handle *sec); |
| 67 | int reiserfs_security_write(struct reiserfs_transaction_handle *th, | 68 | int reiserfs_security_write(struct reiserfs_transaction_handle *th, |
| 68 | struct inode *inode, | 69 | struct inode *inode, |
| @@ -130,6 +131,7 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode) | |||
| 130 | #ifndef CONFIG_REISERFS_FS_SECURITY | 131 | #ifndef CONFIG_REISERFS_FS_SECURITY |
| 131 | static inline int reiserfs_security_init(struct inode *dir, | 132 | static inline int reiserfs_security_init(struct inode *dir, |
| 132 | struct inode *inode, | 133 | struct inode *inode, |
| 134 | const struct qstr *qstr, | ||
| 133 | struct reiserfs_security_handle *sec) | 135 | struct reiserfs_security_handle *sec) |
| 134 | { | 136 | { |
| 135 | return 0; | 137 | return 0; |
diff --git a/include/linux/security.h b/include/linux/security.h index b2b7f9749f5..84a202ac3de 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
| 26 | #include <linux/fsnotify.h> | 26 | #include <linux/fsnotify.h> |
| 27 | #include <linux/binfmts.h> | 27 | #include <linux/binfmts.h> |
| 28 | #include <linux/dcache.h> | ||
| 28 | #include <linux/signal.h> | 29 | #include <linux/signal.h> |
| 29 | #include <linux/resource.h> | 30 | #include <linux/resource.h> |
| 30 | #include <linux/sem.h> | 31 | #include <linux/sem.h> |
| @@ -267,6 +268,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
| 267 | * @orig the original mount data copied from userspace. | 268 | * @orig the original mount data copied from userspace. |
| 268 | * @copy copied data which will be passed to the security module. | 269 | * @copy copied data which will be passed to the security module. |
| 269 | * Returns 0 if the copy was successful. | 270 | * Returns 0 if the copy was successful. |
| 271 | * @sb_remount: | ||
| 272 | * Extracts security system specifc mount options and verifys no changes | ||
| 273 | * are being made to those options. | ||
| 274 | * @sb superblock being remounted | ||
| 275 | * @data contains the filesystem-specific data. | ||
| 276 | * Return 0 if permission is granted. | ||
| 270 | * @sb_umount: | 277 | * @sb_umount: |
| 271 | * Check permission before the @mnt file system is unmounted. | 278 | * Check permission before the @mnt file system is unmounted. |
| 272 | * @mnt contains the mounted file system. | 279 | * @mnt contains the mounted file system. |
| @@ -315,6 +322,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
| 315 | * then it should return -EOPNOTSUPP to skip this processing. | 322 | * then it should return -EOPNOTSUPP to skip this processing. |
| 316 | * @inode contains the inode structure of the newly created inode. | 323 | * @inode contains the inode structure of the newly created inode. |
| 317 | * @dir contains the inode structure of the parent directory. | 324 | * @dir contains the inode structure of the parent directory. |
| 325 | * @qstr contains the last path component of the new object | ||
| 318 | * @name will be set to the allocated name suffix (e.g. selinux). | 326 | * @name will be set to the allocated name suffix (e.g. selinux). |
| 319 | * @value will be set to the allocated attribute value. | 327 | * @value will be set to the allocated attribute value. |
| 320 | * @len will be set to the length of the value. | 328 | * @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) | |||
| 1257 | * @cap contains the capability <include/linux/capability.h>. | 1265 | * @cap contains the capability <include/linux/capability.h>. |
| 1258 | * @audit: Whether to write an audit message or not | 1266 | * @audit: Whether to write an audit message or not |
| 1259 | * Return 0 if the capability is granted for @tsk. | 1267 | * Return 0 if the capability is granted for @tsk. |
| 1260 | * @sysctl: | ||
| 1261 | * Check permission before accessing the @table sysctl variable in the | ||
| 1262 | * manner specified by @op. | ||
| 1263 | * @table contains the ctl_table structure for the sysctl variable. | ||
| 1264 | * @op contains the operation (001 = search, 002 = write, 004 = read). | ||
| 1265 | * Return 0 if permission is granted. | ||
| 1266 | * @syslog: | 1268 | * @syslog: |
| 1267 | * Check permission before accessing the kernel message ring or changing | 1269 | * Check permission before accessing the kernel message ring or changing |
| 1268 | * logging to the console. | 1270 | * logging to the console. |
| @@ -1383,7 +1385,6 @@ struct security_operations { | |||
| 1383 | const kernel_cap_t *permitted); | 1385 | const kernel_cap_t *permitted); |
| 1384 | int (*capable) (struct task_struct *tsk, const struct cred *cred, | 1386 | int (*capable) (struct task_struct *tsk, const struct cred *cred, |
| 1385 | int cap, int audit); | 1387 | int cap, int audit); |
| 1386 | int (*sysctl) (struct ctl_table *table, int op); | ||
| 1387 | int (*quotactl) (int cmds, int type, int id, struct super_block *sb); | 1388 | int (*quotactl) (int cmds, int type, int id, struct super_block *sb); |
| 1388 | int (*quota_on) (struct dentry *dentry); | 1389 | int (*quota_on) (struct dentry *dentry); |
| 1389 | int (*syslog) (int type); | 1390 | int (*syslog) (int type); |
| @@ -1399,6 +1400,7 @@ struct security_operations { | |||
| 1399 | int (*sb_alloc_security) (struct super_block *sb); | 1400 | int (*sb_alloc_security) (struct super_block *sb); |
| 1400 | void (*sb_free_security) (struct super_block *sb); | 1401 | void (*sb_free_security) (struct super_block *sb); |
| 1401 | int (*sb_copy_data) (char *orig, char *copy); | 1402 | int (*sb_copy_data) (char *orig, char *copy); |
| 1403 | int (*sb_remount) (struct super_block *sb, void *data); | ||
| 1402 | int (*sb_kern_mount) (struct super_block *sb, int flags, void *data); | 1404 | int (*sb_kern_mount) (struct super_block *sb, int flags, void *data); |
| 1403 | int (*sb_show_options) (struct seq_file *m, struct super_block *sb); | 1405 | int (*sb_show_options) (struct seq_file *m, struct super_block *sb); |
| 1404 | int (*sb_statfs) (struct dentry *dentry); | 1406 | int (*sb_statfs) (struct dentry *dentry); |
| @@ -1435,7 +1437,8 @@ struct security_operations { | |||
| 1435 | int (*inode_alloc_security) (struct inode *inode); | 1437 | int (*inode_alloc_security) (struct inode *inode); |
| 1436 | void (*inode_free_security) (struct inode *inode); | 1438 | void (*inode_free_security) (struct inode *inode); |
| 1437 | int (*inode_init_security) (struct inode *inode, struct inode *dir, | 1439 | int (*inode_init_security) (struct inode *inode, struct inode *dir, |
| 1438 | char **name, void **value, size_t *len); | 1440 | const struct qstr *qstr, char **name, |
| 1441 | void **value, size_t *len); | ||
| 1439 | int (*inode_create) (struct inode *dir, | 1442 | int (*inode_create) (struct inode *dir, |
| 1440 | struct dentry *dentry, int mode); | 1443 | struct dentry *dentry, int mode); |
| 1441 | int (*inode_link) (struct dentry *old_dentry, | 1444 | int (*inode_link) (struct dentry *old_dentry, |
| @@ -1665,7 +1668,6 @@ int security_capset(struct cred *new, const struct cred *old, | |||
| 1665 | int security_capable(const struct cred *cred, int cap); | 1668 | int security_capable(const struct cred *cred, int cap); |
| 1666 | int security_real_capable(struct task_struct *tsk, int cap); | 1669 | int security_real_capable(struct task_struct *tsk, int cap); |
| 1667 | int security_real_capable_noaudit(struct task_struct *tsk, int cap); | 1670 | int security_real_capable_noaudit(struct task_struct *tsk, int cap); |
| 1668 | int security_sysctl(struct ctl_table *table, int op); | ||
| 1669 | int security_quotactl(int cmds, int type, int id, struct super_block *sb); | 1671 | int security_quotactl(int cmds, int type, int id, struct super_block *sb); |
| 1670 | int security_quota_on(struct dentry *dentry); | 1672 | int security_quota_on(struct dentry *dentry); |
| 1671 | int security_syslog(int type); | 1673 | int security_syslog(int type); |
| @@ -1681,6 +1683,7 @@ int security_bprm_secureexec(struct linux_binprm *bprm); | |||
| 1681 | int security_sb_alloc(struct super_block *sb); | 1683 | int security_sb_alloc(struct super_block *sb); |
| 1682 | void security_sb_free(struct super_block *sb); | 1684 | void security_sb_free(struct super_block *sb); |
| 1683 | int security_sb_copy_data(char *orig, char *copy); | 1685 | int security_sb_copy_data(char *orig, char *copy); |
| 1686 | int security_sb_remount(struct super_block *sb, void *data); | ||
| 1684 | int security_sb_kern_mount(struct super_block *sb, int flags, void *data); | 1687 | int security_sb_kern_mount(struct super_block *sb, int flags, void *data); |
| 1685 | int security_sb_show_options(struct seq_file *m, struct super_block *sb); | 1688 | int security_sb_show_options(struct seq_file *m, struct super_block *sb); |
| 1686 | int security_sb_statfs(struct dentry *dentry); | 1689 | int security_sb_statfs(struct dentry *dentry); |
| @@ -1696,7 +1699,8 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); | |||
| 1696 | int security_inode_alloc(struct inode *inode); | 1699 | int security_inode_alloc(struct inode *inode); |
| 1697 | void security_inode_free(struct inode *inode); | 1700 | void security_inode_free(struct inode *inode); |
| 1698 | int security_inode_init_security(struct inode *inode, struct inode *dir, | 1701 | int security_inode_init_security(struct inode *inode, struct inode *dir, |
| 1699 | char **name, void **value, size_t *len); | 1702 | const struct qstr *qstr, char **name, |
| 1703 | void **value, size_t *len); | ||
| 1700 | int security_inode_create(struct inode *dir, struct dentry *dentry, int mode); | 1704 | int security_inode_create(struct inode *dir, struct dentry *dentry, int mode); |
| 1701 | int security_inode_link(struct dentry *old_dentry, struct inode *dir, | 1705 | int security_inode_link(struct dentry *old_dentry, struct inode *dir, |
| 1702 | struct dentry *new_dentry); | 1706 | struct dentry *new_dentry); |
| @@ -1883,11 +1887,6 @@ int security_real_capable_noaudit(struct task_struct *tsk, int cap) | |||
| 1883 | return ret; | 1887 | return ret; |
| 1884 | } | 1888 | } |
| 1885 | 1889 | ||
| 1886 | static inline int security_sysctl(struct ctl_table *table, int op) | ||
| 1887 | { | ||
| 1888 | return 0; | ||
| 1889 | } | ||
| 1890 | |||
| 1891 | static inline int security_quotactl(int cmds, int type, int id, | 1890 | static inline int security_quotactl(int cmds, int type, int id, |
| 1892 | struct super_block *sb) | 1891 | struct super_block *sb) |
| 1893 | { | 1892 | { |
| @@ -1964,6 +1963,11 @@ static inline int security_sb_copy_data(char *orig, char *copy) | |||
| 1964 | return 0; | 1963 | return 0; |
| 1965 | } | 1964 | } |
| 1966 | 1965 | ||
| 1966 | static inline int security_sb_remount(struct super_block *sb, void *data) | ||
| 1967 | { | ||
| 1968 | return 0; | ||
| 1969 | } | ||
| 1970 | |||
| 1967 | static inline int security_sb_kern_mount(struct super_block *sb, int flags, void *data) | 1971 | static inline int security_sb_kern_mount(struct super_block *sb, int flags, void *data) |
| 1968 | { | 1972 | { |
| 1969 | return 0; | 1973 | return 0; |
| @@ -2023,6 +2027,7 @@ static inline void security_inode_free(struct inode *inode) | |||
| 2023 | 2027 | ||
| 2024 | static inline int security_inode_init_security(struct inode *inode, | 2028 | static inline int security_inode_init_security(struct inode *inode, |
| 2025 | struct inode *dir, | 2029 | struct inode *dir, |
| 2030 | const struct qstr *qstr, | ||
| 2026 | char **name, | 2031 | char **name, |
| 2027 | void **value, | 2032 | void **value, |
| 2028 | size_t *len) | 2033 | size_t *len) |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 0f1bd83db98..56f6fc1178a 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -1685,13 +1685,8 @@ static int test_perm(int mode, int op) | |||
| 1685 | 1685 | ||
| 1686 | int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) | 1686 | int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) |
| 1687 | { | 1687 | { |
| 1688 | int error; | ||
| 1689 | int mode; | 1688 | int mode; |
| 1690 | 1689 | ||
| 1691 | error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC)); | ||
| 1692 | if (error) | ||
| 1693 | return error; | ||
| 1694 | |||
| 1695 | if (root->permissions) | 1690 | if (root->permissions) |
| 1696 | mode = root->permissions(root, current->nsproxy, table); | 1691 | mode = root->permissions(root, current->nsproxy, table); |
| 1697 | else | 1692 | else |
diff --git a/mm/shmem.c b/mm/shmem.c index 5ee67c99060..7c9cdc6fe13 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -1843,8 +1843,9 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
| 1843 | 1843 | ||
| 1844 | inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); | 1844 | inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); |
| 1845 | if (inode) { | 1845 | if (inode) { |
| 1846 | error = security_inode_init_security(inode, dir, NULL, NULL, | 1846 | error = security_inode_init_security(inode, dir, |
| 1847 | NULL); | 1847 | &dentry->d_name, NULL, |
| 1848 | NULL, NULL); | ||
| 1848 | if (error) { | 1849 | if (error) { |
| 1849 | if (error != -EOPNOTSUPP) { | 1850 | if (error != -EOPNOTSUPP) { |
| 1850 | iput(inode); | 1851 | iput(inode); |
| @@ -1983,8 +1984,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
| 1983 | if (!inode) | 1984 | if (!inode) |
| 1984 | return -ENOSPC; | 1985 | return -ENOSPC; |
| 1985 | 1986 | ||
| 1986 | error = security_inode_init_security(inode, dir, NULL, NULL, | 1987 | error = security_inode_init_security(inode, dir, &dentry->d_name, NULL, |
| 1987 | NULL); | 1988 | NULL, NULL); |
| 1988 | if (error) { | 1989 | if (error) { |
| 1989 | if (error != -EOPNOTSUPP) { | 1990 | if (error != -EOPNOTSUPP) { |
| 1990 | iput(inode); | 1991 | iput(inode); |
diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c index 58a12c27870..539855ff31f 100644 --- a/scripts/selinux/genheaders/genheaders.c +++ b/scripts/selinux/genheaders/genheaders.c | |||
| @@ -43,6 +43,8 @@ int main(int argc, char *argv[]) | |||
| 43 | int i, j, k; | 43 | int i, j, k; |
| 44 | int isids_len; | 44 | int isids_len; |
| 45 | FILE *fout; | 45 | FILE *fout; |
| 46 | const char *needle = "SOCKET"; | ||
| 47 | char *substr; | ||
| 46 | 48 | ||
| 47 | progname = argv[0]; | 49 | progname = argv[0]; |
| 48 | 50 | ||
| @@ -88,6 +90,24 @@ int main(int argc, char *argv[]) | |||
| 88 | fprintf(fout, "%2d\n", i); | 90 | fprintf(fout, "%2d\n", i); |
| 89 | } | 91 | } |
| 90 | fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1); | 92 | fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1); |
| 93 | fprintf(fout, "\nstatic inline bool security_is_socket_class(u16 kern_tclass)\n"); | ||
| 94 | fprintf(fout, "{\n"); | ||
| 95 | fprintf(fout, "\tbool sock = false;\n\n"); | ||
| 96 | fprintf(fout, "\tswitch (kern_tclass) {\n"); | ||
| 97 | for (i = 0; secclass_map[i].name; i++) { | ||
| 98 | struct security_class_mapping *map = &secclass_map[i]; | ||
| 99 | substr = strstr(map->name, needle); | ||
| 100 | if (substr && strcmp(substr, needle) == 0) | ||
| 101 | fprintf(fout, "\tcase SECCLASS_%s:\n", map->name); | ||
| 102 | } | ||
| 103 | fprintf(fout, "\t\tsock = true;\n"); | ||
| 104 | fprintf(fout, "\t\tbreak;\n"); | ||
| 105 | fprintf(fout, "\tdefault:\n"); | ||
| 106 | fprintf(fout, "\t\tbreak;\n"); | ||
| 107 | fprintf(fout, "\t}\n\n"); | ||
| 108 | fprintf(fout, "\treturn sock;\n"); | ||
| 109 | fprintf(fout, "}\n"); | ||
| 110 | |||
| 91 | fprintf(fout, "\n#endif\n"); | 111 | fprintf(fout, "\n#endif\n"); |
| 92 | fclose(fout); | 112 | fclose(fout); |
| 93 | 113 | ||
diff --git a/security/capability.c b/security/capability.c index 2a5df2b7da8..ab3d807accc 100644 --- a/security/capability.c +++ b/security/capability.c | |||
| @@ -12,11 +12,6 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/security.h> | 13 | #include <linux/security.h> |
| 14 | 14 | ||
| 15 | static int cap_sysctl(ctl_table *table, int op) | ||
| 16 | { | ||
| 17 | return 0; | ||
| 18 | } | ||
| 19 | |||
| 20 | static int cap_syslog(int type) | 15 | static int cap_syslog(int type) |
| 21 | { | 16 | { |
| 22 | return 0; | 17 | return 0; |
| @@ -59,6 +54,11 @@ static int cap_sb_copy_data(char *orig, char *copy) | |||
| 59 | return 0; | 54 | return 0; |
| 60 | } | 55 | } |
| 61 | 56 | ||
| 57 | static int cap_sb_remount(struct super_block *sb, void *data) | ||
| 58 | { | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 62 | static int cap_sb_kern_mount(struct super_block *sb, int flags, void *data) | 62 | static int cap_sb_kern_mount(struct super_block *sb, int flags, void *data) |
| 63 | { | 63 | { |
| 64 | return 0; | 64 | return 0; |
| @@ -118,7 +118,8 @@ static void cap_inode_free_security(struct inode *inode) | |||
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static int cap_inode_init_security(struct inode *inode, struct inode *dir, | 120 | static int cap_inode_init_security(struct inode *inode, struct inode *dir, |
| 121 | char **name, void **value, size_t *len) | 121 | const struct qstr *qstr, char **name, |
| 122 | void **value, size_t *len) | ||
| 122 | { | 123 | { |
| 123 | return -EOPNOTSUPP; | 124 | return -EOPNOTSUPP; |
| 124 | } | 125 | } |
| @@ -880,7 +881,6 @@ void __init security_fixup_ops(struct security_operations *ops) | |||
| 880 | set_to_cap_if_null(ops, capable); | 881 | set_to_cap_if_null(ops, capable); |
| 881 | set_to_cap_if_null(ops, quotactl); | 882 | set_to_cap_if_null(ops, quotactl); |
| 882 | set_to_cap_if_null(ops, quota_on); | 883 | set_to_cap_if_null(ops, quota_on); |
| 883 | set_to_cap_if_null(ops, sysctl); | ||
| 884 | set_to_cap_if_null(ops, syslog); | 884 | set_to_cap_if_null(ops, syslog); |
| 885 | set_to_cap_if_null(ops, settime); | 885 | set_to_cap_if_null(ops, settime); |
| 886 | set_to_cap_if_null(ops, vm_enough_memory); | 886 | set_to_cap_if_null(ops, vm_enough_memory); |
| @@ -892,6 +892,7 @@ void __init security_fixup_ops(struct security_operations *ops) | |||
| 892 | set_to_cap_if_null(ops, sb_alloc_security); | 892 | set_to_cap_if_null(ops, sb_alloc_security); |
| 893 | set_to_cap_if_null(ops, sb_free_security); | 893 | set_to_cap_if_null(ops, sb_free_security); |
| 894 | set_to_cap_if_null(ops, sb_copy_data); | 894 | set_to_cap_if_null(ops, sb_copy_data); |
| 895 | set_to_cap_if_null(ops, sb_remount); | ||
| 895 | set_to_cap_if_null(ops, sb_kern_mount); | 896 | set_to_cap_if_null(ops, sb_kern_mount); |
| 896 | set_to_cap_if_null(ops, sb_show_options); | 897 | set_to_cap_if_null(ops, sb_show_options); |
| 897 | set_to_cap_if_null(ops, sb_statfs); | 898 | set_to_cap_if_null(ops, sb_statfs); |
diff --git a/security/security.c b/security/security.c index 1a4993b1144..47b8a447118 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -181,11 +181,6 @@ int security_real_capable_noaudit(struct task_struct *tsk, int cap) | |||
| 181 | return ret; | 181 | return ret; |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | int security_sysctl(struct ctl_table *table, int op) | ||
| 185 | { | ||
| 186 | return security_ops->sysctl(table, op); | ||
| 187 | } | ||
| 188 | |||
| 189 | int security_quotactl(int cmds, int type, int id, struct super_block *sb) | 184 | int security_quotactl(int cmds, int type, int id, struct super_block *sb) |
| 190 | { | 185 | { |
| 191 | return security_ops->quotactl(cmds, type, id, sb); | 186 | return security_ops->quotactl(cmds, type, id, sb); |
| @@ -271,6 +266,11 @@ int security_sb_copy_data(char *orig, char *copy) | |||
| 271 | } | 266 | } |
| 272 | EXPORT_SYMBOL(security_sb_copy_data); | 267 | EXPORT_SYMBOL(security_sb_copy_data); |
| 273 | 268 | ||
| 269 | int security_sb_remount(struct super_block *sb, void *data) | ||
| 270 | { | ||
| 271 | return security_ops->sb_remount(sb, data); | ||
| 272 | } | ||
| 273 | |||
| 274 | int security_sb_kern_mount(struct super_block *sb, int flags, void *data) | 274 | int security_sb_kern_mount(struct super_block *sb, int flags, void *data) |
| 275 | { | 275 | { |
| 276 | return security_ops->sb_kern_mount(sb, flags, data); | 276 | return security_ops->sb_kern_mount(sb, flags, data); |
| @@ -335,11 +335,13 @@ void security_inode_free(struct inode *inode) | |||
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | int security_inode_init_security(struct inode *inode, struct inode *dir, | 337 | int security_inode_init_security(struct inode *inode, struct inode *dir, |
| 338 | char **name, void **value, size_t *len) | 338 | const struct qstr *qstr, char **name, |
| 339 | void **value, size_t *len) | ||
| 339 | { | 340 | { |
| 340 | if (unlikely(IS_PRIVATE(inode))) | 341 | if (unlikely(IS_PRIVATE(inode))) |
| 341 | return -EOPNOTSUPP; | 342 | return -EOPNOTSUPP; |
| 342 | return security_ops->inode_init_security(inode, dir, name, value, len); | 343 | return security_ops->inode_init_security(inode, dir, qstr, name, value, |
| 344 | len); | ||
| 343 | } | 345 | } |
| 344 | EXPORT_SYMBOL(security_inode_init_security); | 346 | EXPORT_SYMBOL(security_inode_init_security); |
| 345 | 347 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index c8d69927068..d52a9250741 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -24,9 +24,11 @@ | |||
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
| 27 | #include <linux/kd.h> | ||
| 27 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| 28 | #include <linux/tracehook.h> | 29 | #include <linux/tracehook.h> |
| 29 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
| 31 | #include <linux/ext2_fs.h> | ||
| 30 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
| 31 | #include <linux/security.h> | 33 | #include <linux/security.h> |
| 32 | #include <linux/xattr.h> | 34 | #include <linux/xattr.h> |
| @@ -36,14 +38,15 @@ | |||
| 36 | #include <linux/mman.h> | 38 | #include <linux/mman.h> |
| 37 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
| 38 | #include <linux/pagemap.h> | 40 | #include <linux/pagemap.h> |
| 41 | #include <linux/proc_fs.h> | ||
| 39 | #include <linux/swap.h> | 42 | #include <linux/swap.h> |
| 40 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
| 41 | #include <linux/syscalls.h> | 44 | #include <linux/syscalls.h> |
| 45 | #include <linux/dcache.h> | ||
| 42 | #include <linux/file.h> | 46 | #include <linux/file.h> |
| 43 | #include <linux/fdtable.h> | 47 | #include <linux/fdtable.h> |
| 44 | #include <linux/namei.h> | 48 | #include <linux/namei.h> |
| 45 | #include <linux/mount.h> | 49 | #include <linux/mount.h> |
| 46 | #include <linux/proc_fs.h> | ||
| 47 | #include <linux/netfilter_ipv4.h> | 50 | #include <linux/netfilter_ipv4.h> |
| 48 | #include <linux/netfilter_ipv6.h> | 51 | #include <linux/netfilter_ipv6.h> |
| 49 | #include <linux/tty.h> | 52 | #include <linux/tty.h> |
| @@ -70,7 +73,6 @@ | |||
| 70 | #include <net/ipv6.h> | 73 | #include <net/ipv6.h> |
| 71 | #include <linux/hugetlb.h> | 74 | #include <linux/hugetlb.h> |
| 72 | #include <linux/personality.h> | 75 | #include <linux/personality.h> |
| 73 | #include <linux/sysctl.h> | ||
| 74 | #include <linux/audit.h> | 76 | #include <linux/audit.h> |
| 75 | #include <linux/string.h> | 77 | #include <linux/string.h> |
| 76 | #include <linux/selinux.h> | 78 | #include <linux/selinux.h> |
| @@ -1120,39 +1122,35 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc | |||
| 1120 | } | 1122 | } |
| 1121 | 1123 | ||
| 1122 | #ifdef CONFIG_PROC_FS | 1124 | #ifdef CONFIG_PROC_FS |
| 1123 | static int selinux_proc_get_sid(struct proc_dir_entry *de, | 1125 | static int selinux_proc_get_sid(struct dentry *dentry, |
| 1124 | u16 tclass, | 1126 | u16 tclass, |
| 1125 | u32 *sid) | 1127 | u32 *sid) |
| 1126 | { | 1128 | { |
| 1127 | int buflen, rc; | 1129 | int rc; |
| 1128 | char *buffer, *path, *end; | 1130 | char *buffer, *path; |
| 1129 | 1131 | ||
| 1130 | buffer = (char *)__get_free_page(GFP_KERNEL); | 1132 | buffer = (char *)__get_free_page(GFP_KERNEL); |
| 1131 | if (!buffer) | 1133 | if (!buffer) |
| 1132 | return -ENOMEM; | 1134 | return -ENOMEM; |
| 1133 | 1135 | ||
| 1134 | buflen = PAGE_SIZE; | 1136 | path = dentry_path_raw(dentry, buffer, PAGE_SIZE); |
| 1135 | end = buffer+buflen; | 1137 | if (IS_ERR(path)) |
| 1136 | *--end = '\0'; | 1138 | rc = PTR_ERR(path); |
| 1137 | buflen--; | 1139 | else { |
| 1138 | path = end-1; | 1140 | /* each process gets a /proc/PID/ entry. Strip off the |
| 1139 | *path = '/'; | 1141 | * PID part to get a valid selinux labeling. |
| 1140 | while (de && de != de->parent) { | 1142 | * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */ |
| 1141 | buflen -= de->namelen + 1; | 1143 | while (path[1] >= '0' && path[1] <= '9') { |
| 1142 | if (buflen < 0) | 1144 | path[1] = '/'; |
| 1143 | break; | 1145 | path++; |
| 1144 | end -= de->namelen; | 1146 | } |
| 1145 | memcpy(end, de->name, de->namelen); | 1147 | rc = security_genfs_sid("proc", path, tclass, sid); |
| 1146 | *--end = '/'; | ||
| 1147 | path = end; | ||
| 1148 | de = de->parent; | ||
| 1149 | } | 1148 | } |
| 1150 | rc = security_genfs_sid("proc", path, tclass, sid); | ||
| 1151 | free_page((unsigned long)buffer); | 1149 | free_page((unsigned long)buffer); |
| 1152 | return rc; | 1150 | return rc; |
| 1153 | } | 1151 | } |
| 1154 | #else | 1152 | #else |
| 1155 | static int selinux_proc_get_sid(struct proc_dir_entry *de, | 1153 | static int selinux_proc_get_sid(struct dentry *dentry, |
| 1156 | u16 tclass, | 1154 | u16 tclass, |
| 1157 | u32 *sid) | 1155 | u32 *sid) |
| 1158 | { | 1156 | { |
| @@ -1300,10 +1298,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1300 | 1298 | ||
| 1301 | /* Try to obtain a transition SID. */ | 1299 | /* Try to obtain a transition SID. */ |
| 1302 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 1300 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
| 1303 | rc = security_transition_sid(isec->task_sid, | 1301 | rc = security_transition_sid(isec->task_sid, sbsec->sid, |
| 1304 | sbsec->sid, | 1302 | isec->sclass, NULL, &sid); |
| 1305 | isec->sclass, | ||
| 1306 | &sid); | ||
| 1307 | if (rc) | 1303 | if (rc) |
| 1308 | goto out_unlock; | 1304 | goto out_unlock; |
| 1309 | isec->sid = sid; | 1305 | isec->sid = sid; |
| @@ -1316,10 +1312,9 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1316 | isec->sid = sbsec->sid; | 1312 | isec->sid = sbsec->sid; |
| 1317 | 1313 | ||
| 1318 | if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { | 1314 | if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { |
| 1319 | struct proc_inode *proci = PROC_I(inode); | 1315 | if (opt_dentry) { |
| 1320 | if (proci->pde) { | ||
| 1321 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 1316 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
| 1322 | rc = selinux_proc_get_sid(proci->pde, | 1317 | rc = selinux_proc_get_sid(opt_dentry, |
| 1323 | isec->sclass, | 1318 | isec->sclass, |
| 1324 | &sid); | 1319 | &sid); |
| 1325 | if (rc) | 1320 | if (rc) |
| @@ -1578,7 +1573,7 @@ static int may_create(struct inode *dir, | |||
| 1578 | return rc; | 1573 | return rc; |
| 1579 | 1574 | ||
| 1580 | if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { | 1575 | if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { |
| 1581 | rc = security_transition_sid(sid, dsec->sid, tclass, &newsid); | 1576 | rc = security_transition_sid(sid, dsec->sid, tclass, NULL, &newsid); |
| 1582 | if (rc) | 1577 | if (rc) |
| 1583 | return rc; | 1578 | return rc; |
| 1584 | } | 1579 | } |
| @@ -1862,82 +1857,6 @@ static int selinux_capable(struct task_struct *tsk, const struct cred *cred, | |||
| 1862 | return task_has_capability(tsk, cred, cap, audit); | 1857 | return task_has_capability(tsk, cred, cap, audit); |
| 1863 | } | 1858 | } |
| 1864 | 1859 | ||
| 1865 | static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) | ||
| 1866 | { | ||
| 1867 | int buflen, rc; | ||
| 1868 | char *buffer, *path, *end; | ||
| 1869 | |||
| 1870 | rc = -ENOMEM; | ||
| 1871 | buffer = (char *)__get_free_page(GFP_KERNEL); | ||
| 1872 | if (!buffer) | ||
| 1873 | goto out; | ||
| 1874 | |||
| 1875 | buflen = PAGE_SIZE; | ||
| 1876 | end = buffer+buflen; | ||
| 1877 | *--end = '\0'; | ||
| 1878 | buflen--; | ||
| 1879 | path = end-1; | ||
| 1880 | *path = '/'; | ||
| 1881 | while (table) { | ||
| 1882 | const char *name = table->procname; | ||
| 1883 | size_t namelen = strlen(name); | ||
| 1884 | buflen -= namelen + 1; | ||
| 1885 | if (buflen < 0) | ||
| 1886 | goto out_free; | ||
| 1887 | end -= namelen; | ||
| 1888 | memcpy(end, name, namelen); | ||
| 1889 | *--end = '/'; | ||
| 1890 | path = end; | ||
| 1891 | table = table->parent; | ||
| 1892 | } | ||
| 1893 | buflen -= 4; | ||
| 1894 | if (buflen < 0) | ||
| 1895 | goto out_free; | ||
| 1896 | end -= 4; | ||
| 1897 | memcpy(end, "/sys", 4); | ||
| 1898 | path = end; | ||
| 1899 | rc = security_genfs_sid("proc", path, tclass, sid); | ||
| 1900 | out_free: | ||
| 1901 | free_page((unsigned long)buffer); | ||
| 1902 | out: | ||
| 1903 | return rc; | ||
| 1904 | } | ||
| 1905 | |||
| 1906 | static int selinux_sysctl(ctl_table *table, int op) | ||
| 1907 | { | ||
| 1908 | int error = 0; | ||
| 1909 | u32 av; | ||
| 1910 | u32 tsid, sid; | ||
| 1911 | int rc; | ||
| 1912 | |||
| 1913 | sid = current_sid(); | ||
| 1914 | |||
| 1915 | rc = selinux_sysctl_get_sid(table, (op == 0001) ? | ||
| 1916 | SECCLASS_DIR : SECCLASS_FILE, &tsid); | ||
| 1917 | if (rc) { | ||
| 1918 | /* Default to the well-defined sysctl SID. */ | ||
| 1919 | tsid = SECINITSID_SYSCTL; | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | /* The op values are "defined" in sysctl.c, thereby creating | ||
| 1923 | * a bad coupling between this module and sysctl.c */ | ||
| 1924 | if (op == 001) { | ||
| 1925 | error = avc_has_perm(sid, tsid, | ||
| 1926 | SECCLASS_DIR, DIR__SEARCH, NULL); | ||
| 1927 | } else { | ||
| 1928 | av = 0; | ||
| 1929 | if (op & 004) | ||
| 1930 | av |= FILE__READ; | ||
| 1931 | if (op & 002) | ||
| 1932 | av |= FILE__WRITE; | ||
| 1933 | if (av) | ||
| 1934 | error = avc_has_perm(sid, tsid, | ||
| 1935 | SECCLASS_FILE, av, NULL); | ||
| 1936 | } | ||
| 1937 | |||
| 1938 | return error; | ||
| 1939 | } | ||
| 1940 | |||
| 1941 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | 1860 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) |
| 1942 | { | 1861 | { |
| 1943 | const struct cred *cred = current_cred(); | 1862 | const struct cred *cred = current_cred(); |
| @@ -2060,7 +1979,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
| 2060 | } else { | 1979 | } else { |
| 2061 | /* Check for a default transition on this program. */ | 1980 | /* Check for a default transition on this program. */ |
| 2062 | rc = security_transition_sid(old_tsec->sid, isec->sid, | 1981 | rc = security_transition_sid(old_tsec->sid, isec->sid, |
| 2063 | SECCLASS_PROCESS, &new_tsec->sid); | 1982 | SECCLASS_PROCESS, NULL, |
| 1983 | &new_tsec->sid); | ||
| 2064 | if (rc) | 1984 | if (rc) |
| 2065 | return rc; | 1985 | return rc; |
| 2066 | } | 1986 | } |
| @@ -2443,6 +2363,91 @@ out: | |||
| 2443 | return rc; | 2363 | return rc; |
| 2444 | } | 2364 | } |
| 2445 | 2365 | ||
| 2366 | static int selinux_sb_remount(struct super_block *sb, void *data) | ||
| 2367 | { | ||
| 2368 | int rc, i, *flags; | ||
| 2369 | struct security_mnt_opts opts; | ||
| 2370 | char *secdata, **mount_options; | ||
| 2371 | struct superblock_security_struct *sbsec = sb->s_security; | ||
| 2372 | |||
| 2373 | if (!(sbsec->flags & SE_SBINITIALIZED)) | ||
| 2374 | return 0; | ||
| 2375 | |||
| 2376 | if (!data) | ||
| 2377 | return 0; | ||
| 2378 | |||
| 2379 | if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) | ||
| 2380 | return 0; | ||
| 2381 | |||
| 2382 | security_init_mnt_opts(&opts); | ||
| 2383 | secdata = alloc_secdata(); | ||
| 2384 | if (!secdata) | ||
| 2385 | return -ENOMEM; | ||
| 2386 | rc = selinux_sb_copy_data(data, secdata); | ||
| 2387 | if (rc) | ||
| 2388 | goto out_free_secdata; | ||
| 2389 | |||
| 2390 | rc = selinux_parse_opts_str(secdata, &opts); | ||
| 2391 | if (rc) | ||
| 2392 | goto out_free_secdata; | ||
| 2393 | |||
| 2394 | mount_options = opts.mnt_opts; | ||
| 2395 | flags = opts.mnt_opts_flags; | ||
| 2396 | |||
| 2397 | for (i = 0; i < opts.num_mnt_opts; i++) { | ||
| 2398 | u32 sid; | ||
| 2399 | size_t len; | ||
| 2400 | |||
| 2401 | if (flags[i] == SE_SBLABELSUPP) | ||
| 2402 | continue; | ||
| 2403 | len = strlen(mount_options[i]); | ||
| 2404 | rc = security_context_to_sid(mount_options[i], len, &sid); | ||
| 2405 | if (rc) { | ||
| 2406 | printk(KERN_WARNING "SELinux: security_context_to_sid" | ||
| 2407 | "(%s) failed for (dev %s, type %s) errno=%d\n", | ||
| 2408 | mount_options[i], sb->s_id, sb->s_type->name, rc); | ||
| 2409 | goto out_free_opts; | ||
| 2410 | } | ||
| 2411 | rc = -EINVAL; | ||
| 2412 | switch (flags[i]) { | ||
| 2413 | case FSCONTEXT_MNT: | ||
| 2414 | if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) | ||
| 2415 | goto out_bad_option; | ||
| 2416 | break; | ||
| 2417 | case CONTEXT_MNT: | ||
| 2418 | if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) | ||
| 2419 | goto out_bad_option; | ||
| 2420 | break; | ||
| 2421 | case ROOTCONTEXT_MNT: { | ||
| 2422 | struct inode_security_struct *root_isec; | ||
| 2423 | root_isec = sb->s_root->d_inode->i_security; | ||
| 2424 | |||
| 2425 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) | ||
| 2426 | goto out_bad_option; | ||
| 2427 | break; | ||
| 2428 | } | ||
| 2429 | case DEFCONTEXT_MNT: | ||
| 2430 | if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) | ||
| 2431 | goto out_bad_option; | ||
| 2432 | break; | ||
| 2433 | default: | ||
| 2434 | goto out_free_opts; | ||
| 2435 | } | ||
| 2436 | } | ||
| 2437 | |||
| 2438 | rc = 0; | ||
| 2439 | out_free_opts: | ||
| 2440 | security_free_mnt_opts(&opts); | ||
| 2441 | out_free_secdata: | ||
| 2442 | free_secdata(secdata); | ||
| 2443 | return rc; | ||
| 2444 | out_bad_option: | ||
| 2445 | printk(KERN_WARNING "SELinux: unable to change security options " | ||
| 2446 | "during remount (dev %s, type=%s)\n", sb->s_id, | ||
| 2447 | sb->s_type->name); | ||
| 2448 | goto out_free_opts; | ||
| 2449 | } | ||
| 2450 | |||
| 2446 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | 2451 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) |
| 2447 | { | 2452 | { |
| 2448 | const struct cred *cred = current_cred(); | 2453 | const struct cred *cred = current_cred(); |
| @@ -2509,8 +2514,8 @@ static void selinux_inode_free_security(struct inode *inode) | |||
| 2509 | } | 2514 | } |
| 2510 | 2515 | ||
| 2511 | static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | 2516 | static int selinux_inode_init_security(struct inode *inode, struct inode *dir, |
| 2512 | char **name, void **value, | 2517 | const struct qstr *qstr, char **name, |
| 2513 | size_t *len) | 2518 | void **value, size_t *len) |
| 2514 | { | 2519 | { |
| 2515 | const struct task_security_struct *tsec = current_security(); | 2520 | const struct task_security_struct *tsec = current_security(); |
| 2516 | struct inode_security_struct *dsec; | 2521 | struct inode_security_struct *dsec; |
| @@ -2531,7 +2536,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 2531 | else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { | 2536 | else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { |
| 2532 | rc = security_transition_sid(sid, dsec->sid, | 2537 | rc = security_transition_sid(sid, dsec->sid, |
| 2533 | inode_mode_to_security_class(inode->i_mode), | 2538 | inode_mode_to_security_class(inode->i_mode), |
| 2534 | &newsid); | 2539 | qstr, &newsid); |
| 2535 | if (rc) { | 2540 | if (rc) { |
| 2536 | printk(KERN_WARNING "%s: " | 2541 | printk(KERN_WARNING "%s: " |
| 2537 | "security_transition_sid failed, rc=%d (dev=%s " | 2542 | "security_transition_sid failed, rc=%d (dev=%s " |
| @@ -2932,16 +2937,47 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
| 2932 | unsigned long arg) | 2937 | unsigned long arg) |
| 2933 | { | 2938 | { |
| 2934 | const struct cred *cred = current_cred(); | 2939 | const struct cred *cred = current_cred(); |
| 2935 | u32 av = 0; | 2940 | int error = 0; |
| 2936 | 2941 | ||
| 2937 | if (_IOC_DIR(cmd) & _IOC_WRITE) | 2942 | switch (cmd) { |
| 2938 | av |= FILE__WRITE; | 2943 | case FIONREAD: |
| 2939 | if (_IOC_DIR(cmd) & _IOC_READ) | 2944 | /* fall through */ |
| 2940 | av |= FILE__READ; | 2945 | case FIBMAP: |
| 2941 | if (!av) | 2946 | /* fall through */ |
| 2942 | av = FILE__IOCTL; | 2947 | case FIGETBSZ: |
| 2948 | /* fall through */ | ||
| 2949 | case EXT2_IOC_GETFLAGS: | ||
| 2950 | /* fall through */ | ||
| 2951 | case EXT2_IOC_GETVERSION: | ||
| 2952 | error = file_has_perm(cred, file, FILE__GETATTR); | ||
| 2953 | break; | ||
| 2954 | |||
| 2955 | case EXT2_IOC_SETFLAGS: | ||
| 2956 | /* fall through */ | ||
| 2957 | case EXT2_IOC_SETVERSION: | ||
| 2958 | error = file_has_perm(cred, file, FILE__SETATTR); | ||
| 2959 | break; | ||
| 2960 | |||
| 2961 | /* sys_ioctl() checks */ | ||
| 2962 | case FIONBIO: | ||
| 2963 | /* fall through */ | ||
| 2964 | case FIOASYNC: | ||
| 2965 | error = file_has_perm(cred, file, 0); | ||
| 2966 | break; | ||
| 2943 | 2967 | ||
| 2944 | return file_has_perm(cred, file, av); | 2968 | case KDSKBENT: |
| 2969 | case KDSKBSENT: | ||
| 2970 | error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG, | ||
| 2971 | SECURITY_CAP_AUDIT); | ||
| 2972 | break; | ||
| 2973 | |||
| 2974 | /* default case assumes that the command will go | ||
| 2975 | * to the file's ioctl() function. | ||
| 2976 | */ | ||
| 2977 | default: | ||
| 2978 | error = file_has_perm(cred, file, FILE__IOCTL); | ||
| 2979 | } | ||
| 2980 | return error; | ||
| 2945 | } | 2981 | } |
| 2946 | 2982 | ||
| 2947 | static int default_noexec; | 2983 | static int default_noexec; |
| @@ -3644,9 +3680,16 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid) | |||
| 3644 | 3680 | ||
| 3645 | /* socket security operations */ | 3681 | /* socket security operations */ |
| 3646 | 3682 | ||
| 3647 | static u32 socket_sockcreate_sid(const struct task_security_struct *tsec) | 3683 | static int socket_sockcreate_sid(const struct task_security_struct *tsec, |
| 3684 | u16 secclass, u32 *socksid) | ||
| 3648 | { | 3685 | { |
| 3649 | return tsec->sockcreate_sid ? : tsec->sid; | 3686 | if (tsec->sockcreate_sid > SECSID_NULL) { |
| 3687 | *socksid = tsec->sockcreate_sid; | ||
| 3688 | return 0; | ||
| 3689 | } | ||
| 3690 | |||
| 3691 | return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL, | ||
| 3692 | socksid); | ||
| 3650 | } | 3693 | } |
| 3651 | 3694 | ||
| 3652 | static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) | 3695 | 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, | |||
| 3670 | const struct task_security_struct *tsec = current_security(); | 3713 | const struct task_security_struct *tsec = current_security(); |
| 3671 | u32 newsid; | 3714 | u32 newsid; |
| 3672 | u16 secclass; | 3715 | u16 secclass; |
| 3716 | int rc; | ||
| 3673 | 3717 | ||
| 3674 | if (kern) | 3718 | if (kern) |
| 3675 | return 0; | 3719 | return 0; |
| 3676 | 3720 | ||
| 3677 | newsid = socket_sockcreate_sid(tsec); | ||
| 3678 | secclass = socket_type_to_security_class(family, type, protocol); | 3721 | secclass = socket_type_to_security_class(family, type, protocol); |
| 3722 | rc = socket_sockcreate_sid(tsec, secclass, &newsid); | ||
| 3723 | if (rc) | ||
| 3724 | return rc; | ||
| 3725 | |||
| 3679 | return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL); | 3726 | return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL); |
| 3680 | } | 3727 | } |
| 3681 | 3728 | ||
| @@ -3687,12 +3734,16 @@ static int selinux_socket_post_create(struct socket *sock, int family, | |||
| 3687 | struct sk_security_struct *sksec; | 3734 | struct sk_security_struct *sksec; |
| 3688 | int err = 0; | 3735 | int err = 0; |
| 3689 | 3736 | ||
| 3737 | isec->sclass = socket_type_to_security_class(family, type, protocol); | ||
| 3738 | |||
| 3690 | if (kern) | 3739 | if (kern) |
| 3691 | isec->sid = SECINITSID_KERNEL; | 3740 | isec->sid = SECINITSID_KERNEL; |
| 3692 | else | 3741 | else { |
| 3693 | isec->sid = socket_sockcreate_sid(tsec); | 3742 | err = socket_sockcreate_sid(tsec, isec->sclass, &(isec->sid)); |
| 3743 | if (err) | ||
| 3744 | return err; | ||
| 3745 | } | ||
| 3694 | 3746 | ||
| 3695 | isec->sclass = socket_type_to_security_class(family, type, protocol); | ||
| 3696 | isec->initialized = 1; | 3747 | isec->initialized = 1; |
| 3697 | 3748 | ||
| 3698 | if (sock->sk) { | 3749 | if (sock->sk) { |
| @@ -4002,7 +4053,6 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | |||
| 4002 | { | 4053 | { |
| 4003 | int err = 0; | 4054 | int err = 0; |
| 4004 | struct sk_security_struct *sksec = sk->sk_security; | 4055 | struct sk_security_struct *sksec = sk->sk_security; |
| 4005 | u32 peer_sid; | ||
| 4006 | u32 sk_sid = sksec->sid; | 4056 | u32 sk_sid = sksec->sid; |
| 4007 | struct common_audit_data ad; | 4057 | struct common_audit_data ad; |
| 4008 | char *addrp; | 4058 | char *addrp; |
| @@ -4021,20 +4071,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | |||
| 4021 | return err; | 4071 | return err; |
| 4022 | } | 4072 | } |
| 4023 | 4073 | ||
| 4024 | if (selinux_policycap_netpeer) { | 4074 | err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad); |
| 4025 | err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); | 4075 | if (err) |
| 4026 | if (err) | 4076 | return err; |
| 4027 | return err; | 4077 | err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad); |
| 4028 | err = avc_has_perm(sk_sid, peer_sid, | ||
| 4029 | SECCLASS_PEER, PEER__RECV, &ad); | ||
| 4030 | if (err) | ||
| 4031 | selinux_netlbl_err(skb, err, 0); | ||
| 4032 | } else { | ||
| 4033 | err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad); | ||
| 4034 | if (err) | ||
| 4035 | return err; | ||
| 4036 | err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad); | ||
| 4037 | } | ||
| 4038 | 4078 | ||
| 4039 | return err; | 4079 | return err; |
| 4040 | } | 4080 | } |
| @@ -4529,9 +4569,8 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
| 4529 | SECCLASS_PACKET, PACKET__SEND, &ad)) | 4569 | SECCLASS_PACKET, PACKET__SEND, &ad)) |
| 4530 | return NF_DROP_ERR(-ECONNREFUSED); | 4570 | return NF_DROP_ERR(-ECONNREFUSED); |
| 4531 | 4571 | ||
| 4532 | if (selinux_policycap_netpeer) | 4572 | if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) |
| 4533 | if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) | 4573 | return NF_DROP_ERR(-ECONNREFUSED); |
| 4534 | return NF_DROP_ERR(-ECONNREFUSED); | ||
| 4535 | 4574 | ||
| 4536 | return NF_ACCEPT; | 4575 | return NF_ACCEPT; |
| 4537 | } | 4576 | } |
| @@ -4574,27 +4613,14 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
| 4574 | * from the sending socket, otherwise use the kernel's sid */ | 4613 | * from the sending socket, otherwise use the kernel's sid */ |
| 4575 | sk = skb->sk; | 4614 | sk = skb->sk; |
| 4576 | if (sk == NULL) { | 4615 | if (sk == NULL) { |
| 4577 | switch (family) { | 4616 | if (skb->skb_iif) { |
| 4578 | case PF_INET: | 4617 | secmark_perm = PACKET__FORWARD_OUT; |
| 4579 | if (IPCB(skb)->flags & IPSKB_FORWARDED) | ||
| 4580 | secmark_perm = PACKET__FORWARD_OUT; | ||
| 4581 | else | ||
| 4582 | secmark_perm = PACKET__SEND; | ||
| 4583 | break; | ||
| 4584 | case PF_INET6: | ||
| 4585 | if (IP6CB(skb)->flags & IP6SKB_FORWARDED) | ||
| 4586 | secmark_perm = PACKET__FORWARD_OUT; | ||
| 4587 | else | ||
| 4588 | secmark_perm = PACKET__SEND; | ||
| 4589 | break; | ||
| 4590 | default: | ||
| 4591 | return NF_DROP_ERR(-ECONNREFUSED); | ||
| 4592 | } | ||
| 4593 | if (secmark_perm == PACKET__FORWARD_OUT) { | ||
| 4594 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) | 4618 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) |
| 4595 | return NF_DROP; | 4619 | return NF_DROP; |
| 4596 | } else | 4620 | } else { |
| 4621 | secmark_perm = PACKET__SEND; | ||
| 4597 | peer_sid = SECINITSID_KERNEL; | 4622 | peer_sid = SECINITSID_KERNEL; |
| 4623 | } | ||
| 4598 | } else { | 4624 | } else { |
| 4599 | struct sk_security_struct *sksec = sk->sk_security; | 4625 | struct sk_security_struct *sksec = sk->sk_security; |
| 4600 | peer_sid = sksec->sid; | 4626 | peer_sid = sksec->sid; |
| @@ -4848,7 +4874,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4848 | * message queue this message will be stored in | 4874 | * message queue this message will be stored in |
| 4849 | */ | 4875 | */ |
| 4850 | rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG, | 4876 | rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG, |
| 4851 | &msec->sid); | 4877 | NULL, &msec->sid); |
| 4852 | if (rc) | 4878 | if (rc) |
| 4853 | return rc; | 4879 | return rc; |
| 4854 | } | 4880 | } |
| @@ -5402,7 +5428,6 @@ static struct security_operations selinux_ops = { | |||
| 5402 | .ptrace_traceme = selinux_ptrace_traceme, | 5428 | .ptrace_traceme = selinux_ptrace_traceme, |
| 5403 | .capget = selinux_capget, | 5429 | .capget = selinux_capget, |
| 5404 | .capset = selinux_capset, | 5430 | .capset = selinux_capset, |
| 5405 | .sysctl = selinux_sysctl, | ||
| 5406 | .capable = selinux_capable, | 5431 | .capable = selinux_capable, |
| 5407 | .quotactl = selinux_quotactl, | 5432 | .quotactl = selinux_quotactl, |
| 5408 | .quota_on = selinux_quota_on, | 5433 | .quota_on = selinux_quota_on, |
| @@ -5420,6 +5445,7 @@ static struct security_operations selinux_ops = { | |||
| 5420 | .sb_alloc_security = selinux_sb_alloc_security, | 5445 | .sb_alloc_security = selinux_sb_alloc_security, |
| 5421 | .sb_free_security = selinux_sb_free_security, | 5446 | .sb_free_security = selinux_sb_free_security, |
| 5422 | .sb_copy_data = selinux_sb_copy_data, | 5447 | .sb_copy_data = selinux_sb_copy_data, |
| 5448 | .sb_remount = selinux_sb_remount, | ||
| 5423 | .sb_kern_mount = selinux_sb_kern_mount, | 5449 | .sb_kern_mount = selinux_sb_kern_mount, |
| 5424 | .sb_show_options = selinux_sb_show_options, | 5450 | .sb_show_options = selinux_sb_show_options, |
| 5425 | .sb_statfs = selinux_sb_statfs, | 5451 | .sb_statfs = selinux_sb_statfs, |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 7ed3663332e..b8c53723e09 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | #define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ | 12 | #define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ |
| 13 | "write", "associate", "unix_read", "unix_write" | 13 | "write", "associate", "unix_read", "unix_write" |
| 14 | 14 | ||
| 15 | /* | ||
| 16 | * Note: The name for any socket class should be suffixed by "socket", | ||
| 17 | * and doesn't contain more than one substr of "socket". | ||
| 18 | */ | ||
| 15 | struct security_class_mapping secclass_map[] = { | 19 | struct security_class_mapping secclass_map[] = { |
| 16 | { "security", | 20 | { "security", |
| 17 | { "compute_av", "compute_create", "compute_member", | 21 | { "compute_av", "compute_create", "compute_member", |
| @@ -132,8 +136,7 @@ struct security_class_mapping secclass_map[] = { | |||
| 132 | { "appletalk_socket", | 136 | { "appletalk_socket", |
| 133 | { COMMON_SOCK_PERMS, NULL } }, | 137 | { COMMON_SOCK_PERMS, NULL } }, |
| 134 | { "packet", | 138 | { "packet", |
| 135 | { "send", "recv", "relabelto", "flow_in", "flow_out", | 139 | { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } }, |
| 136 | "forward_in", "forward_out", NULL } }, | ||
| 137 | { "key", | 140 | { "key", |
| 138 | { "view", "read", "write", "search", "link", "setattr", "create", | 141 | { "view", "read", "write", "search", "link", "setattr", "create", |
| 139 | NULL } }, | 142 | NULL } }, |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 671273eb111..348eb00cb66 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #ifndef _SELINUX_SECURITY_H_ | 8 | #ifndef _SELINUX_SECURITY_H_ |
| 9 | #define _SELINUX_SECURITY_H_ | 9 | #define _SELINUX_SECURITY_H_ |
| 10 | 10 | ||
| 11 | #include <linux/dcache.h> | ||
| 11 | #include <linux/magic.h> | 12 | #include <linux/magic.h> |
| 12 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 13 | #include "flask.h" | 14 | #include "flask.h" |
| @@ -28,13 +29,14 @@ | |||
| 28 | #define POLICYDB_VERSION_POLCAP 22 | 29 | #define POLICYDB_VERSION_POLCAP 22 |
| 29 | #define POLICYDB_VERSION_PERMISSIVE 23 | 30 | #define POLICYDB_VERSION_PERMISSIVE 23 |
| 30 | #define POLICYDB_VERSION_BOUNDARY 24 | 31 | #define POLICYDB_VERSION_BOUNDARY 24 |
| 32 | #define POLICYDB_VERSION_FILENAME_TRANS 25 | ||
| 31 | 33 | ||
| 32 | /* Range of policy versions we understand*/ | 34 | /* Range of policy versions we understand*/ |
| 33 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE | 35 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE |
| 34 | #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX | 36 | #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX |
| 35 | #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE | 37 | #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE |
| 36 | #else | 38 | #else |
| 37 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY | 39 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_FILENAME_TRANS |
| 38 | #endif | 40 | #endif |
| 39 | 41 | ||
| 40 | /* Mask for just the mount related flags */ | 42 | /* Mask for just the mount related flags */ |
| @@ -106,8 +108,8 @@ void security_compute_av(u32 ssid, u32 tsid, | |||
| 106 | void security_compute_av_user(u32 ssid, u32 tsid, | 108 | void security_compute_av_user(u32 ssid, u32 tsid, |
| 107 | u16 tclass, struct av_decision *avd); | 109 | u16 tclass, struct av_decision *avd); |
| 108 | 110 | ||
| 109 | int security_transition_sid(u32 ssid, u32 tsid, | 111 | int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, |
| 110 | u16 tclass, u32 *out_sid); | 112 | const struct qstr *qstr, u32 *out_sid); |
| 111 | 113 | ||
| 112 | int security_transition_sid_user(u32 ssid, u32 tsid, | 114 | int security_transition_sid_user(u32 ssid, u32 tsid, |
| 113 | u16 tclass, u32 *out_sid); | 115 | u16 tclass, u32 *out_sid); |
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 3417f9cc1cb..63ce2f9e441 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | * | 14 | * |
| 15 | * Copyright (C) 2003 Tresys Technology, LLC | 15 | * Copyright (C) 2003 Tresys Technology, LLC |
| 16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
| 17 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
| 18 | * the Free Software Foundation, version 2. | 18 | * the Free Software Foundation, version 2. |
| 19 | * | 19 | * |
| 20 | * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp> | 20 | * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp> |
| @@ -27,16 +27,16 @@ struct avtab_key { | |||
| 27 | u16 source_type; /* source type */ | 27 | u16 source_type; /* source type */ |
| 28 | u16 target_type; /* target type */ | 28 | u16 target_type; /* target type */ |
| 29 | u16 target_class; /* target object class */ | 29 | u16 target_class; /* target object class */ |
| 30 | #define AVTAB_ALLOWED 1 | 30 | #define AVTAB_ALLOWED 0x0001 |
| 31 | #define AVTAB_AUDITALLOW 2 | 31 | #define AVTAB_AUDITALLOW 0x0002 |
| 32 | #define AVTAB_AUDITDENY 4 | 32 | #define AVTAB_AUDITDENY 0x0004 |
| 33 | #define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) | 33 | #define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) |
| 34 | #define AVTAB_TRANSITION 16 | 34 | #define AVTAB_TRANSITION 0x0010 |
| 35 | #define AVTAB_MEMBER 32 | 35 | #define AVTAB_MEMBER 0x0020 |
| 36 | #define AVTAB_CHANGE 64 | 36 | #define AVTAB_CHANGE 0x0040 |
| 37 | #define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) | 37 | #define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) |
| 38 | #define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ | 38 | #define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ |
| 39 | #define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ | 39 | #define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ |
| 40 | u16 specified; /* what field is specified */ | 40 | u16 specified; /* what field is specified */ |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 1ef8e4e8988..e96174216bc 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
| @@ -512,7 +512,8 @@ int mls_compute_sid(struct context *scontext, | |||
| 512 | struct context *tcontext, | 512 | struct context *tcontext, |
| 513 | u16 tclass, | 513 | u16 tclass, |
| 514 | u32 specified, | 514 | u32 specified, |
| 515 | struct context *newcontext) | 515 | struct context *newcontext, |
| 516 | bool sock) | ||
| 516 | { | 517 | { |
| 517 | struct range_trans rtr; | 518 | struct range_trans rtr; |
| 518 | struct mls_range *r; | 519 | struct mls_range *r; |
| @@ -531,7 +532,7 @@ int mls_compute_sid(struct context *scontext, | |||
| 531 | return mls_range_set(newcontext, r); | 532 | return mls_range_set(newcontext, r); |
| 532 | /* Fallthrough */ | 533 | /* Fallthrough */ |
| 533 | case AVTAB_CHANGE: | 534 | case AVTAB_CHANGE: |
| 534 | if (tclass == policydb.process_class) | 535 | if ((tclass == policydb.process_class) || (sock == true)) |
| 535 | /* Use the process MLS attributes. */ | 536 | /* Use the process MLS attributes. */ |
| 536 | return mls_context_cpy(newcontext, scontext); | 537 | return mls_context_cpy(newcontext, scontext); |
| 537 | else | 538 | else |
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index cd9152632e5..037bf9d82d4 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h | |||
| @@ -49,7 +49,8 @@ int mls_compute_sid(struct context *scontext, | |||
| 49 | struct context *tcontext, | 49 | struct context *tcontext, |
| 50 | u16 tclass, | 50 | u16 tclass, |
| 51 | u32 specified, | 51 | u32 specified, |
| 52 | struct context *newcontext); | 52 | struct context *newcontext, |
| 53 | bool sock); | ||
| 53 | 54 | ||
| 54 | int mls_setup_user_range(struct context *fromcon, struct user_datum *user, | 55 | int mls_setup_user_range(struct context *fromcon, struct user_datum *user, |
| 55 | struct context *usercon); | 56 | struct context *usercon); |
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 57363562f0f..e7b850ad57e 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
| @@ -123,6 +123,11 @@ static struct policydb_compat_info policydb_compat[] = { | |||
| 123 | .sym_num = SYM_NUM, | 123 | .sym_num = SYM_NUM, |
| 124 | .ocon_num = OCON_NUM, | 124 | .ocon_num = OCON_NUM, |
| 125 | }, | 125 | }, |
| 126 | { | ||
| 127 | .version = POLICYDB_VERSION_FILENAME_TRANS, | ||
| 128 | .sym_num = SYM_NUM, | ||
| 129 | .ocon_num = OCON_NUM, | ||
| 130 | }, | ||
| 126 | }; | 131 | }; |
| 127 | 132 | ||
| 128 | static struct policydb_compat_info *policydb_lookup_compat(int version) | 133 | static struct policydb_compat_info *policydb_lookup_compat(int version) |
| @@ -704,6 +709,7 @@ void policydb_destroy(struct policydb *p) | |||
| 704 | int i; | 709 | int i; |
| 705 | struct role_allow *ra, *lra = NULL; | 710 | struct role_allow *ra, *lra = NULL; |
| 706 | struct role_trans *tr, *ltr = NULL; | 711 | struct role_trans *tr, *ltr = NULL; |
| 712 | struct filename_trans *ft, *nft; | ||
| 707 | 713 | ||
| 708 | for (i = 0; i < SYM_NUM; i++) { | 714 | for (i = 0; i < SYM_NUM; i++) { |
| 709 | cond_resched(); | 715 | cond_resched(); |
| @@ -781,6 +787,15 @@ void policydb_destroy(struct policydb *p) | |||
| 781 | } | 787 | } |
| 782 | flex_array_free(p->type_attr_map_array); | 788 | flex_array_free(p->type_attr_map_array); |
| 783 | } | 789 | } |
| 790 | |||
| 791 | ft = p->filename_trans; | ||
| 792 | while (ft) { | ||
| 793 | nft = ft->next; | ||
| 794 | kfree(ft->name); | ||
| 795 | kfree(ft); | ||
| 796 | ft = nft; | ||
| 797 | } | ||
| 798 | |||
| 784 | ebitmap_destroy(&p->policycaps); | 799 | ebitmap_destroy(&p->policycaps); |
| 785 | ebitmap_destroy(&p->permissive_map); | 800 | ebitmap_destroy(&p->permissive_map); |
| 786 | 801 | ||
| @@ -1788,6 +1803,76 @@ out: | |||
| 1788 | return rc; | 1803 | return rc; |
| 1789 | } | 1804 | } |
| 1790 | 1805 | ||
| 1806 | static int filename_trans_read(struct policydb *p, void *fp) | ||
| 1807 | { | ||
| 1808 | struct filename_trans *ft, *last; | ||
| 1809 | u32 nel, len; | ||
| 1810 | char *name; | ||
| 1811 | __le32 buf[4]; | ||
| 1812 | int rc, i; | ||
| 1813 | |||
| 1814 | if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS) | ||
| 1815 | return 0; | ||
| 1816 | |||
| 1817 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 1818 | if (rc) | ||
| 1819 | goto out; | ||
| 1820 | nel = le32_to_cpu(buf[0]); | ||
| 1821 | |||
| 1822 | printk(KERN_ERR "%s: nel=%d\n", __func__, nel); | ||
| 1823 | |||
| 1824 | last = p->filename_trans; | ||
| 1825 | while (last && last->next) | ||
| 1826 | last = last->next; | ||
| 1827 | |||
| 1828 | for (i = 0; i < nel; i++) { | ||
| 1829 | rc = -ENOMEM; | ||
| 1830 | ft = kzalloc(sizeof(*ft), GFP_KERNEL); | ||
| 1831 | if (!ft) | ||
| 1832 | goto out; | ||
| 1833 | |||
| 1834 | /* add it to the tail of the list */ | ||
| 1835 | if (!last) | ||
| 1836 | p->filename_trans = ft; | ||
| 1837 | else | ||
| 1838 | last->next = ft; | ||
| 1839 | last = ft; | ||
| 1840 | |||
| 1841 | /* length of the path component string */ | ||
| 1842 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 1843 | if (rc) | ||
| 1844 | goto out; | ||
| 1845 | len = le32_to_cpu(buf[0]); | ||
| 1846 | |||
| 1847 | rc = -ENOMEM; | ||
| 1848 | name = kmalloc(len + 1, GFP_KERNEL); | ||
| 1849 | if (!name) | ||
| 1850 | goto out; | ||
| 1851 | |||
| 1852 | ft->name = name; | ||
| 1853 | |||
| 1854 | /* path component string */ | ||
| 1855 | rc = next_entry(name, fp, len); | ||
| 1856 | if (rc) | ||
| 1857 | goto out; | ||
| 1858 | name[len] = 0; | ||
| 1859 | |||
| 1860 | printk(KERN_ERR "%s: ft=%p ft->name=%p ft->name=%s\n", __func__, ft, ft->name, ft->name); | ||
| 1861 | |||
| 1862 | rc = next_entry(buf, fp, sizeof(u32) * 4); | ||
| 1863 | if (rc) | ||
| 1864 | goto out; | ||
| 1865 | |||
| 1866 | ft->stype = le32_to_cpu(buf[0]); | ||
| 1867 | ft->ttype = le32_to_cpu(buf[1]); | ||
| 1868 | ft->tclass = le32_to_cpu(buf[2]); | ||
| 1869 | ft->otype = le32_to_cpu(buf[3]); | ||
| 1870 | } | ||
| 1871 | rc = 0; | ||
| 1872 | out: | ||
| 1873 | return rc; | ||
| 1874 | } | ||
| 1875 | |||
| 1791 | static int genfs_read(struct policydb *p, void *fp) | 1876 | static int genfs_read(struct policydb *p, void *fp) |
| 1792 | { | 1877 | { |
| 1793 | int i, j, rc; | 1878 | int i, j, rc; |
| @@ -2251,6 +2336,10 @@ int policydb_read(struct policydb *p, void *fp) | |||
| 2251 | lra = ra; | 2336 | lra = ra; |
| 2252 | } | 2337 | } |
| 2253 | 2338 | ||
| 2339 | rc = filename_trans_read(p, fp); | ||
| 2340 | if (rc) | ||
| 2341 | goto bad; | ||
| 2342 | |||
| 2254 | rc = policydb_index(p); | 2343 | rc = policydb_index(p); |
| 2255 | if (rc) | 2344 | if (rc) |
| 2256 | goto bad; | 2345 | goto bad; |
| @@ -3025,6 +3114,43 @@ static int range_write(struct policydb *p, void *fp) | |||
| 3025 | return 0; | 3114 | return 0; |
| 3026 | } | 3115 | } |
| 3027 | 3116 | ||
| 3117 | static int filename_trans_write(struct policydb *p, void *fp) | ||
| 3118 | { | ||
| 3119 | struct filename_trans *ft; | ||
| 3120 | u32 len, nel = 0; | ||
| 3121 | __le32 buf[4]; | ||
| 3122 | int rc; | ||
| 3123 | |||
| 3124 | for (ft = p->filename_trans; ft; ft = ft->next) | ||
| 3125 | nel++; | ||
| 3126 | |||
| 3127 | buf[0] = cpu_to_le32(nel); | ||
| 3128 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
| 3129 | if (rc) | ||
| 3130 | return rc; | ||
| 3131 | |||
| 3132 | for (ft = p->filename_trans; ft; ft = ft->next) { | ||
| 3133 | len = strlen(ft->name); | ||
| 3134 | buf[0] = cpu_to_le32(len); | ||
| 3135 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
| 3136 | if (rc) | ||
| 3137 | return rc; | ||
| 3138 | |||
| 3139 | rc = put_entry(ft->name, sizeof(char), len, fp); | ||
| 3140 | if (rc) | ||
| 3141 | return rc; | ||
| 3142 | |||
| 3143 | buf[0] = ft->stype; | ||
| 3144 | buf[1] = ft->ttype; | ||
| 3145 | buf[2] = ft->tclass; | ||
| 3146 | buf[3] = ft->otype; | ||
| 3147 | |||
| 3148 | rc = put_entry(buf, sizeof(u32), 4, fp); | ||
| 3149 | if (rc) | ||
| 3150 | return rc; | ||
| 3151 | } | ||
| 3152 | return 0; | ||
| 3153 | } | ||
| 3028 | /* | 3154 | /* |
| 3029 | * Write the configuration data in a policy database | 3155 | * Write the configuration data in a policy database |
| 3030 | * structure to a policy database binary representation | 3156 | * structure to a policy database binary representation |
| @@ -3135,6 +3261,10 @@ int policydb_write(struct policydb *p, void *fp) | |||
| 3135 | if (rc) | 3261 | if (rc) |
| 3136 | return rc; | 3262 | return rc; |
| 3137 | 3263 | ||
| 3264 | rc = filename_trans_write(p, fp); | ||
| 3265 | if (rc) | ||
| 3266 | return rc; | ||
| 3267 | |||
| 3138 | rc = ocontext_write(p, info, fp); | 3268 | rc = ocontext_write(p, info, fp); |
| 3139 | if (rc) | 3269 | if (rc) |
| 3140 | return rc; | 3270 | return rc; |
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index 4e3ab9d0b31..732ea4a6868 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h | |||
| @@ -77,6 +77,15 @@ struct role_trans { | |||
| 77 | struct role_trans *next; | 77 | struct role_trans *next; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | struct filename_trans { | ||
| 81 | struct filename_trans *next; | ||
| 82 | u32 stype; /* current process */ | ||
| 83 | u32 ttype; /* parent dir context */ | ||
| 84 | u16 tclass; /* class of new object */ | ||
| 85 | const char *name; /* last path component */ | ||
| 86 | u32 otype; /* expected of new object */ | ||
| 87 | }; | ||
| 88 | |||
| 80 | struct role_allow { | 89 | struct role_allow { |
| 81 | u32 role; /* current role */ | 90 | u32 role; /* current role */ |
| 82 | u32 new_role; /* new role */ | 91 | u32 new_role; /* new role */ |
| @@ -217,6 +226,9 @@ struct policydb { | |||
| 217 | /* role transitions */ | 226 | /* role transitions */ |
| 218 | struct role_trans *role_tr; | 227 | struct role_trans *role_tr; |
| 219 | 228 | ||
| 229 | /* file transitions with the last path component */ | ||
| 230 | struct filename_trans *filename_trans; | ||
| 231 | |||
| 220 | /* bools indexed by (value - 1) */ | 232 | /* bools indexed by (value - 1) */ |
| 221 | struct cond_bool_datum **bool_val_to_struct; | 233 | struct cond_bool_datum **bool_val_to_struct; |
| 222 | /* type enforcement conditional access vectors and transitions */ | 234 | /* 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) | |||
| 302 | return 0; | 314 | return 0; |
| 303 | } | 315 | } |
| 304 | 316 | ||
| 305 | static inline int put_entry(void *buf, size_t bytes, int num, struct policy_file *fp) | 317 | static inline int put_entry(const void *buf, size_t bytes, int num, struct policy_file *fp) |
| 306 | { | 318 | { |
| 307 | size_t len = bytes * num; | 319 | size_t len = bytes * num; |
| 308 | 320 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index a03cfaf0ee0..3e7544d2a07 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -201,6 +201,21 @@ static u16 unmap_class(u16 tclass) | |||
| 201 | return tclass; | 201 | return tclass; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | /* | ||
| 205 | * Get kernel value for class from its policy value | ||
| 206 | */ | ||
| 207 | static u16 map_class(u16 pol_value) | ||
| 208 | { | ||
| 209 | u16 i; | ||
| 210 | |||
| 211 | for (i = 1; i < current_mapping_size; i++) { | ||
| 212 | if (current_mapping[i].value == pol_value) | ||
| 213 | return i; | ||
| 214 | } | ||
| 215 | |||
| 216 | return pol_value; | ||
| 217 | } | ||
| 218 | |||
| 204 | static void map_decision(u16 tclass, struct av_decision *avd, | 219 | static void map_decision(u16 tclass, struct av_decision *avd, |
| 205 | int allow_unknown) | 220 | int allow_unknown) |
| 206 | { | 221 | { |
| @@ -1343,10 +1358,27 @@ out: | |||
| 1343 | return -EACCES; | 1358 | return -EACCES; |
| 1344 | } | 1359 | } |
| 1345 | 1360 | ||
| 1361 | static void filename_compute_type(struct policydb *p, struct context *newcontext, | ||
| 1362 | u32 scon, u32 tcon, u16 tclass, | ||
| 1363 | const struct qstr *qstr) | ||
| 1364 | { | ||
| 1365 | struct filename_trans *ft; | ||
| 1366 | for (ft = p->filename_trans; ft; ft = ft->next) { | ||
| 1367 | if (ft->stype == scon && | ||
| 1368 | ft->ttype == tcon && | ||
| 1369 | ft->tclass == tclass && | ||
| 1370 | !strcmp(ft->name, qstr->name)) { | ||
| 1371 | newcontext->type = ft->otype; | ||
| 1372 | return; | ||
| 1373 | } | ||
| 1374 | } | ||
| 1375 | } | ||
| 1376 | |||
| 1346 | static int security_compute_sid(u32 ssid, | 1377 | static int security_compute_sid(u32 ssid, |
| 1347 | u32 tsid, | 1378 | u32 tsid, |
| 1348 | u16 orig_tclass, | 1379 | u16 orig_tclass, |
| 1349 | u32 specified, | 1380 | u32 specified, |
| 1381 | const struct qstr *qstr, | ||
| 1350 | u32 *out_sid, | 1382 | u32 *out_sid, |
| 1351 | bool kern) | 1383 | bool kern) |
| 1352 | { | 1384 | { |
| @@ -1357,6 +1389,7 @@ static int security_compute_sid(u32 ssid, | |||
| 1357 | struct avtab_node *node; | 1389 | struct avtab_node *node; |
| 1358 | u16 tclass; | 1390 | u16 tclass; |
| 1359 | int rc = 0; | 1391 | int rc = 0; |
| 1392 | bool sock; | ||
| 1360 | 1393 | ||
| 1361 | if (!ss_initialized) { | 1394 | if (!ss_initialized) { |
| 1362 | switch (orig_tclass) { | 1395 | switch (orig_tclass) { |
| @@ -1374,10 +1407,13 @@ static int security_compute_sid(u32 ssid, | |||
| 1374 | 1407 | ||
| 1375 | read_lock(&policy_rwlock); | 1408 | read_lock(&policy_rwlock); |
| 1376 | 1409 | ||
| 1377 | if (kern) | 1410 | if (kern) { |
| 1378 | tclass = unmap_class(orig_tclass); | 1411 | tclass = unmap_class(orig_tclass); |
| 1379 | else | 1412 | sock = security_is_socket_class(orig_tclass); |
| 1413 | } else { | ||
| 1380 | tclass = orig_tclass; | 1414 | tclass = orig_tclass; |
| 1415 | sock = security_is_socket_class(map_class(tclass)); | ||
| 1416 | } | ||
| 1381 | 1417 | ||
| 1382 | scontext = sidtab_search(&sidtab, ssid); | 1418 | scontext = sidtab_search(&sidtab, ssid); |
| 1383 | if (!scontext) { | 1419 | if (!scontext) { |
| @@ -1408,7 +1444,7 @@ static int security_compute_sid(u32 ssid, | |||
| 1408 | } | 1444 | } |
| 1409 | 1445 | ||
| 1410 | /* Set the role and type to default values. */ | 1446 | /* Set the role and type to default values. */ |
| 1411 | if (tclass == policydb.process_class) { | 1447 | if ((tclass == policydb.process_class) || (sock == true)) { |
| 1412 | /* Use the current role and type of process. */ | 1448 | /* Use the current role and type of process. */ |
| 1413 | newcontext.role = scontext->role; | 1449 | newcontext.role = scontext->role; |
| 1414 | newcontext.type = scontext->type; | 1450 | newcontext.type = scontext->type; |
| @@ -1442,6 +1478,11 @@ static int security_compute_sid(u32 ssid, | |||
| 1442 | newcontext.type = avdatum->data; | 1478 | newcontext.type = avdatum->data; |
| 1443 | } | 1479 | } |
| 1444 | 1480 | ||
| 1481 | /* if we have a qstr this is a file trans check so check those rules */ | ||
| 1482 | if (qstr) | ||
| 1483 | filename_compute_type(&policydb, &newcontext, scontext->type, | ||
| 1484 | tcontext->type, tclass, qstr); | ||
| 1485 | |||
| 1445 | /* Check for class-specific changes. */ | 1486 | /* Check for class-specific changes. */ |
| 1446 | if (tclass == policydb.process_class) { | 1487 | if (tclass == policydb.process_class) { |
| 1447 | if (specified & AVTAB_TRANSITION) { | 1488 | if (specified & AVTAB_TRANSITION) { |
| @@ -1460,7 +1501,8 @@ static int security_compute_sid(u32 ssid, | |||
| 1460 | 1501 | ||
| 1461 | /* Set the MLS attributes. | 1502 | /* Set the MLS attributes. |
| 1462 | This is done last because it may allocate memory. */ | 1503 | This is done last because it may allocate memory. */ |
| 1463 | rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext); | 1504 | rc = mls_compute_sid(scontext, tcontext, tclass, specified, |
| 1505 | &newcontext, sock); | ||
| 1464 | if (rc) | 1506 | if (rc) |
| 1465 | goto out_unlock; | 1507 | goto out_unlock; |
| 1466 | 1508 | ||
| @@ -1495,22 +1537,17 @@ out: | |||
| 1495 | * if insufficient memory is available, or %0 if the new SID was | 1537 | * if insufficient memory is available, or %0 if the new SID was |
| 1496 | * computed successfully. | 1538 | * computed successfully. |
| 1497 | */ | 1539 | */ |
| 1498 | int security_transition_sid(u32 ssid, | 1540 | int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, |
| 1499 | u32 tsid, | 1541 | const struct qstr *qstr, u32 *out_sid) |
| 1500 | u16 tclass, | ||
| 1501 | u32 *out_sid) | ||
| 1502 | { | 1542 | { |
| 1503 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1543 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
| 1504 | out_sid, true); | 1544 | qstr, out_sid, true); |
| 1505 | } | 1545 | } |
| 1506 | 1546 | ||
| 1507 | int security_transition_sid_user(u32 ssid, | 1547 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) |
| 1508 | u32 tsid, | ||
| 1509 | u16 tclass, | ||
| 1510 | u32 *out_sid) | ||
| 1511 | { | 1548 | { |
| 1512 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1549 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
| 1513 | out_sid, false); | 1550 | NULL, out_sid, false); |
| 1514 | } | 1551 | } |
| 1515 | 1552 | ||
| 1516 | /** | 1553 | /** |
| @@ -1531,8 +1568,8 @@ int security_member_sid(u32 ssid, | |||
| 1531 | u16 tclass, | 1568 | u16 tclass, |
| 1532 | u32 *out_sid) | 1569 | u32 *out_sid) |
| 1533 | { | 1570 | { |
| 1534 | return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid, | 1571 | return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, NULL, |
| 1535 | false); | 1572 | out_sid, false); |
| 1536 | } | 1573 | } |
| 1537 | 1574 | ||
| 1538 | /** | 1575 | /** |
| @@ -1553,8 +1590,8 @@ int security_change_sid(u32 ssid, | |||
| 1553 | u16 tclass, | 1590 | u16 tclass, |
| 1554 | u32 *out_sid) | 1591 | u32 *out_sid) |
| 1555 | { | 1592 | { |
| 1556 | return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid, | 1593 | return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL, |
| 1557 | false); | 1594 | out_sid, false); |
| 1558 | } | 1595 | } |
| 1559 | 1596 | ||
| 1560 | /* Clone the SID into the new SID table. */ | 1597 | /* Clone the SID into the new SID table. */ |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index fff78d3b51a..728c57e3d65 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
| @@ -208,7 +208,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, | |||
| 208 | if (!uctx) | 208 | if (!uctx) |
| 209 | goto not_from_user; | 209 | goto not_from_user; |
| 210 | 210 | ||
| 211 | if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX) | 211 | if (uctx->ctx_alg != XFRM_SC_ALG_SELINUX) |
| 212 | return -EINVAL; | 212 | return -EINVAL; |
| 213 | 213 | ||
| 214 | str_len = uctx->ctx_len; | 214 | str_len = uctx->ctx_len; |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 5ab3f39442f..23c7a6d0c80 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <net/cipso_ipv4.h> | 33 | #include <net/cipso_ipv4.h> |
| 34 | #include <linux/audit.h> | 34 | #include <linux/audit.h> |
| 35 | #include <linux/magic.h> | 35 | #include <linux/magic.h> |
| 36 | #include <linux/dcache.h> | ||
| 36 | #include "smack.h" | 37 | #include "smack.h" |
| 37 | 38 | ||
| 38 | #define task_security(task) (task_cred_xxx((task), security)) | 39 | #define task_security(task) (task_cred_xxx((task), security)) |
| @@ -501,6 +502,7 @@ static void smack_inode_free_security(struct inode *inode) | |||
| 501 | * smack_inode_init_security - copy out the smack from an inode | 502 | * smack_inode_init_security - copy out the smack from an inode |
| 502 | * @inode: the inode | 503 | * @inode: the inode |
| 503 | * @dir: unused | 504 | * @dir: unused |
| 505 | * @qstr: unused | ||
| 504 | * @name: where to put the attribute name | 506 | * @name: where to put the attribute name |
| 505 | * @value: where to put the attribute value | 507 | * @value: where to put the attribute value |
| 506 | * @len: where to put the length of the attribute | 508 | * @len: where to put the length of the attribute |
| @@ -508,7 +510,8 @@ static void smack_inode_free_security(struct inode *inode) | |||
| 508 | * Returns 0 if it all works out, -ENOMEM if there's no memory | 510 | * Returns 0 if it all works out, -ENOMEM if there's no memory |
| 509 | */ | 511 | */ |
| 510 | static int smack_inode_init_security(struct inode *inode, struct inode *dir, | 512 | static int smack_inode_init_security(struct inode *inode, struct inode *dir, |
| 511 | char **name, void **value, size_t *len) | 513 | const struct qstr *qstr, char **name, |
| 514 | void **value, size_t *len) | ||
| 512 | { | 515 | { |
| 513 | char *isp = smk_of_inode(inode); | 516 | char *isp = smk_of_inode(inode); |
| 514 | char *dsp = smk_of_inode(dir); | 517 | char *dsp = smk_of_inode(dir); |
