Implement ->proc_write_buf() so procfs copies in what is written before
it pins the entry, and set the label from that copy. Writes larger than
PAGE_SIZE - 1 bytes fail with -EINVAL from procfs now. A write that
large only ever worked when most of it was trailing newlines or came
after a NUL, ntfs_set_label() refused a label that long with
-ENAMETOOLONG or -EFBIG.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 fs/ntfs3/super.c | 27 +++++++++------------------
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index 3d669e957ea4..fca73d2766c0 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -536,37 +536,28 @@ static int ntfs3_label_show(struct seq_file *m, void *o)
 }
 
 /* write /proc/fs/ntfs3/<dev>/label */
-static ssize_t ntfs3_label_write(struct file *file, const char __user *buffer,
-                                size_t count, loff_t *ppos)
+static ssize_t ntfs3_label_write(struct file *file, char *buf, size_t count,
+                                loff_t *ppos)
 {
        int err;
        struct super_block *sb = pde_data(file_inode(file));
-       ssize_t ret = count;
-       u8 *label;
+       size_t len = count;
 
        if (sb_rdonly(sb))
                return -EROFS;
 
-       label = memdup_user(buffer, count);
-       if (IS_ERR(label))
-               return PTR_ERR(label);
+       while (len > 0 && buf[len - 1] == '\n')
+               len -= 1;
 
-       while (ret > 0 && label[ret - 1] == '\n')
-               ret -= 1;
-
-       err = ntfs_set_label(sb->s_fs_info, label, ret);
+       err = ntfs_set_label(sb->s_fs_info, (u8 *)buf, len);
 
        if (err < 0) {
                ntfs_err(sb, "failed (%d) to write label", err);
-               ret = err;
-               goto out;
+               return err;
        }
 
        *ppos += count;
-       ret = count;
-out:
-       kfree(label);
-       return ret;
+       return count;
 }
 
 static const struct proc_ops ntfs3_volinfo_fops = {
@@ -575,7 +566,7 @@ static const struct proc_ops ntfs3_volinfo_fops = {
 
 static const struct proc_ops ntfs3_label_fops = {
        .proc_show = ntfs3_label_show,
-       .proc_write = ntfs3_label_write,
+       .proc_write_buf = ntfs3_label_write,
 };
 
 static void ntfs_create_procdir(struct super_block *sb)

-- 
2.53.0


Reply via email to