Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Nov 2018 03:19:49 +0000 (20:19 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Nov 2018 03:19:49 +0000 (20:19 -0700)
Pull misc vfs updates from Al Viro:
 "No common topic, really - a handful of assorted stuff; the least
  trivial bits are Mark's dedupe patches"

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  fs/exofs: only use true/false for asignment of bool type variable
  fs/exofs: fix potential memory leak in mount option parsing
  Delete invalid assignment statements in do_sendfile
  iomap: remove duplicated include from iomap.c
  vfs: dedupe should return EPERM if permission is not granted
  vfs: allow dedupe of user owned read-only files
  ntfs: don't open-code ERR_CAST
  ext4: don't open-code ERR_CAST

fs/exofs/super.c
fs/ext4/ialloc.c
fs/ext4/namei.c
fs/iomap.c
fs/ntfs/namei.c
fs/read_write.c

index 41cf2fbee50da4cb9ec0999a967d7d777fb7fc45..906839a4da8ff8215f7a18f26030cfbc18b9b0e3 100644 (file)
@@ -101,6 +101,7 @@ static int parse_options(char *options, struct exofs_mountopt *opts)
                token = match_token(p, tokens, args);
                switch (token) {
                case Opt_name:
+                       kfree(opts->dev_name);
                        opts->dev_name = match_strdup(&args[0]);
                        if (unlikely(!opts->dev_name)) {
                                EXOFS_ERR("Error allocating dev_name");
@@ -117,7 +118,7 @@ static int parse_options(char *options, struct exofs_mountopt *opts)
                                          EXOFS_MIN_PID);
                                return -EINVAL;
                        }
-                       s_pid = 1;
+                       s_pid = true;
                        break;
                case Opt_to:
                        if (match_int(&args[0], &option))
@@ -866,8 +867,10 @@ static struct dentry *exofs_mount(struct file_system_type *type,
        int ret;
 
        ret = parse_options(data, &opts);
-       if (ret)
+       if (ret) {
+               kfree(opts.dev_name);
                return ERR_PTR(ret);
+       }
 
        if (!opts.dev_name)
                opts.dev_name = dev_name;
index 2addcb8730e19afedcabac390e775124e6a66559..014f6a698cb712a25929f135238cb88614360d31 100644 (file)
@@ -1216,7 +1216,7 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
        bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
        bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
        if (IS_ERR(bitmap_bh))
-               return (struct inode *) bitmap_bh;
+               return ERR_CAST(bitmap_bh);
 
        /* Having the inode bit set should be a 100% indicator that this
         * is a valid orphan (no e2fsck run on fs).  Orphans also include
index 67a38532032ae89cfcbaec35fe139992cbf2875e..17adcb16a9c85f8fee50f2796ed10c79f7e32cd7 100644 (file)
@@ -1556,7 +1556,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
 
        bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
        if (IS_ERR(bh))
-               return (struct dentry *) bh;
+               return ERR_CAST(bh);
        inode = NULL;
        if (bh) {
                __u32 ino = le32_to_cpu(de->inode);
@@ -1600,7 +1600,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
 
        bh = ext4_find_entry(d_inode(child), &dotdot, &de, NULL);
        if (IS_ERR(bh))
-               return (struct dentry *) bh;
+               return ERR_CAST(bh);
        if (!bh)
                return ERR_PTR(-ENOENT);
        ino = le32_to_cpu(de->inode);
index 970ee3964e98a2a85932dc8d0e4532ea60ce6b59..64ce240217a18985dd0510fd968b257dce214cd4 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/task_io_accounting_ops.h>
 #include <linux/dax.h>
 #include <linux/sched/signal.h>
-#include <linux/swap.h>
 
 #include "internal.h"
 
index 4690cd75d8d7948a056fe899bc4600ade10b8566..3986c7a1f6a88c2b0ed421a1f6fbc45c7a68405c 100644 (file)
@@ -312,7 +312,7 @@ static struct dentry *ntfs_get_parent(struct dentry *child_dent)
        /* Get the mft record of the inode belonging to the child dentry. */
        mrec = map_mft_record(ni);
        if (IS_ERR(mrec))
-               return (struct dentry *)mrec;
+               return ERR_CAST(mrec);
        /* Find the first file name attribute in the mft record. */
        ctx = ntfs_attr_get_search_ctx(ni, mrec);
        if (unlikely(!ctx)) {
index 603794b207ebad39946e96bcbfff73332fc9a0a0..5a2ee488c5d2a3b35cb8cb941c652215cb96f7da 100644 (file)
@@ -1407,7 +1407,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
                goto fput_in;
        if (!(out.file->f_mode & FMODE_WRITE))
                goto fput_out;
-       retval = -EINVAL;
        in_inode = file_inode(in.file);
        out_inode = file_inode(out.file);
        out_pos = out.file->f_pos;
@@ -1977,6 +1976,20 @@ out_error:
 }
 EXPORT_SYMBOL(vfs_dedupe_file_range_compare);
 
+/* Check whether we are allowed to dedupe the destination file */
+static bool allow_file_dedupe(struct file *file)
+{
+       if (capable(CAP_SYS_ADMIN))
+               return true;
+       if (file->f_mode & FMODE_WRITE)
+               return true;
+       if (uid_eq(current_fsuid(), file_inode(file)->i_uid))
+               return true;
+       if (!inode_permission(file_inode(file), MAY_WRITE))
+               return true;
+       return false;
+}
+
 int vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
                              struct file *dst_file, loff_t dst_pos, u64 len)
 {
@@ -1990,8 +2003,8 @@ int vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
        if (ret < 0)
                goto out_drop_write;
 
-       ret = -EINVAL;
-       if (!(capable(CAP_SYS_ADMIN) || (dst_file->f_mode & FMODE_WRITE)))
+       ret = -EPERM;
+       if (!allow_file_dedupe(dst_file))
                goto out_drop_write;
 
        ret = -EXDEV;