aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-05 12:28:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-05 12:28:45 -0400
commit51987affd626b8e4ce9f4c65e1950cb9159f0f58 (patch)
tree9c10c7f5accd7cf6717597af815d6f80d4efbfd5
parent6203838dec05352bc357625b1e9ba0a10d3bca35 (diff)
parent4e9036042fedaffcd868d7f7aa948756c48c637d (diff)
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: - a couple of ->i_link use-after-free fixes - regression fix for wrong errno on absent device name in mount(2) (this cycle stuff) - ancient UFS braino in large GID handling on Solaris UFS images (bogus cut'n'paste from large UID handling; wrong field checked to decide whether we should look at old (16bit) or new (32bit) field) * 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: ufs: fix braino in ufs_get_inode_gid() for solaris UFS flavour Abort file_remove_privs() for non-reg. files [fix] get rid of checking for absent device name in vfs_get_tree() apparmorfs: fix use-after-free on symlink traversal securityfs: fix use-after-free on symlink traversal
-rw-r--r--fs/inode.c9
-rw-r--r--fs/super.c5
-rw-r--r--fs/ufs/util.h2
-rw-r--r--security/apparmor/apparmorfs.c13
-rw-r--r--security/inode.c13
5 files changed, 26 insertions, 16 deletions
diff --git a/fs/inode.c b/fs/inode.c
index e9d97add2b36..9a453f3637f8 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1817,8 +1817,13 @@ int file_remove_privs(struct file *file)
1817 int kill; 1817 int kill;
1818 int error = 0; 1818 int error = 0;
1819 1819
1820 /* Fast path for nothing security related */ 1820 /*
1821 if (IS_NOSEC(inode)) 1821 * Fast path for nothing security related.
1822 * As well for non-regular files, e.g. blkdev inodes.
1823 * For example, blkdev_write_iter() might get here
1824 * trying to remove privs which it is not allowed to.
1825 */
1826 if (IS_NOSEC(inode) || !S_ISREG(inode->i_mode))
1822 return 0; 1827 return 0;
1823 1828
1824 kill = dentry_needs_remove_privs(dentry); 1829 kill = dentry_needs_remove_privs(dentry);
diff --git a/fs/super.c b/fs/super.c
index 583a0124bc39..2739f57515f8 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1467,11 +1467,6 @@ int vfs_get_tree(struct fs_context *fc)
1467 struct super_block *sb; 1467 struct super_block *sb;
1468 int error; 1468 int error;
1469 1469
1470 if (fc->fs_type->fs_flags & FS_REQUIRES_DEV && !fc->source) {
1471 errorf(fc, "Filesystem requires source device");
1472 return -ENOENT;
1473 }
1474
1475 if (fc->root) 1470 if (fc->root)
1476 return -EBUSY; 1471 return -EBUSY;
1477 1472
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 1fd3011ea623..7fd4802222b8 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -229,7 +229,7 @@ ufs_get_inode_gid(struct super_block *sb, struct ufs_inode *inode)
229 case UFS_UID_44BSD: 229 case UFS_UID_44BSD:
230 return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid); 230 return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid);
231 case UFS_UID_EFT: 231 case UFS_UID_EFT:
232 if (inode->ui_u1.oldids.ui_suid == 0xFFFF) 232 if (inode->ui_u1.oldids.ui_sgid == 0xFFFF)
233 return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid); 233 return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid);
234 /* Fall through */ 234 /* Fall through */
235 default: 235 default:
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index fefee040bf79..b9298d2e8165 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -123,17 +123,22 @@ static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
123 return 0; 123 return 0;
124} 124}
125 125
126static void aafs_evict_inode(struct inode *inode) 126static void aafs_i_callback(struct rcu_head *head)
127{ 127{
128 truncate_inode_pages_final(&inode->i_data); 128 struct inode *inode = container_of(head, struct inode, i_rcu);
129 clear_inode(inode);
130 if (S_ISLNK(inode->i_mode)) 129 if (S_ISLNK(inode->i_mode))
131 kfree(inode->i_link); 130 kfree(inode->i_link);
131 free_inode_nonrcu(inode);
132}
133
134static void aafs_destroy_inode(struct inode *inode)
135{
136 call_rcu(&inode->i_rcu, aafs_i_callback);
132} 137}
133 138
134static const struct super_operations aafs_super_ops = { 139static const struct super_operations aafs_super_ops = {
135 .statfs = simple_statfs, 140 .statfs = simple_statfs,
136 .evict_inode = aafs_evict_inode, 141 .destroy_inode = aafs_destroy_inode,
137 .show_path = aafs_show_path, 142 .show_path = aafs_show_path,
138}; 143};
139 144
diff --git a/security/inode.c b/security/inode.c
index b7772a9b315e..421dd72b5876 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -27,17 +27,22 @@
27static struct vfsmount *mount; 27static struct vfsmount *mount;
28static int mount_count; 28static int mount_count;
29 29
30static void securityfs_evict_inode(struct inode *inode) 30static void securityfs_i_callback(struct rcu_head *head)
31{ 31{
32 truncate_inode_pages_final(&inode->i_data); 32 struct inode *inode = container_of(head, struct inode, i_rcu);
33 clear_inode(inode);
34 if (S_ISLNK(inode->i_mode)) 33 if (S_ISLNK(inode->i_mode))
35 kfree(inode->i_link); 34 kfree(inode->i_link);
35 free_inode_nonrcu(inode);
36}
37
38static void securityfs_destroy_inode(struct inode *inode)
39{
40 call_rcu(&inode->i_rcu, securityfs_i_callback);
36} 41}
37 42
38static const struct super_operations securityfs_super_operations = { 43static const struct super_operations securityfs_super_operations = {
39 .statfs = simple_statfs, 44 .statfs = simple_statfs,
40 .evict_inode = securityfs_evict_inode, 45 .destroy_inode = securityfs_destroy_inode,
41}; 46};
42 47
43static int fill_super(struct super_block *sb, void *data, int silent) 48static int fill_super(struct super_block *sb, void *data, int silent)