Merge tag 'renesas-dt-fixes-for-v4.15' of https://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / kernel / sysctl.c
index 4a13a389e99b243a5e261d3b3a12b67e2e681c11..557d4672857793f746b9dfe0d8d1a0527bd2ac87 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/kexec.h>
 #include <linux/bpf.h>
 #include <linux/mount.h>
+#include <linux/pipe_fs_i.h>
 
 #include <linux/uaccess.h>
 #include <asm/processor.h>
@@ -1816,7 +1817,7 @@ static struct ctl_table fs_table[] = {
        {
                .procname       = "pipe-max-size",
                .data           = &pipe_max_size,
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(pipe_max_size),
                .mode           = 0644,
                .proc_handler   = &pipe_proc_fn,
                .extra1         = &pipe_min_size,
@@ -2575,12 +2576,13 @@ static int do_proc_douintvec_minmax_conv(unsigned long *lvalp,
        if (write) {
                unsigned int val = *lvalp;
 
+               if (*lvalp > UINT_MAX)
+                       return -EINVAL;
+
                if ((param->min && *param->min > val) ||
                    (param->max && *param->max < val))
                        return -ERANGE;
 
-               if (*lvalp > UINT_MAX)
-                       return -EINVAL;
                *valp = val;
        } else {
                unsigned int val = *valp;
@@ -2620,6 +2622,48 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
                                 do_proc_douintvec_minmax_conv, &param);
 }
 
+struct do_proc_dopipe_max_size_conv_param {
+       unsigned int *min;
+};
+
+static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
+                                       unsigned int *valp,
+                                       int write, void *data)
+{
+       struct do_proc_dopipe_max_size_conv_param *param = data;
+
+       if (write) {
+               unsigned int val;
+
+               if (*lvalp > UINT_MAX)
+                       return -EINVAL;
+
+               val = round_pipe_size(*lvalp);
+               if (val == 0)
+                       return -EINVAL;
+
+               if (param->min && *param->min > val)
+                       return -ERANGE;
+
+               *valp = val;
+       } else {
+               unsigned int val = *valp;
+               *lvalp = (unsigned long) val;
+       }
+
+       return 0;
+}
+
+int proc_dopipe_max_size(struct ctl_table *table, int write,
+                        void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       struct do_proc_dopipe_max_size_conv_param param = {
+               .min = (unsigned int *) table->extra1,
+       };
+       return do_proc_douintvec(table, write, buffer, lenp, ppos,
+                                do_proc_dopipe_max_size_conv, &param);
+}
+
 static void validate_coredump_safety(void)
 {
 #ifdef CONFIG_COREDUMP
@@ -3083,14 +3127,12 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
                        else
                                bitmap_copy(bitmap, tmp_bitmap, bitmap_len);
                }
-               kfree(tmp_bitmap);
                *lenp -= left;
                *ppos += *lenp;
-               return 0;
-       } else {
-               kfree(tmp_bitmap);
-               return err;
        }
+
+       kfree(tmp_bitmap);
+       return err;
 }
 
 #else /* CONFIG_PROC_SYSCTL */
@@ -3125,6 +3167,12 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
        return -ENOSYS;
 }
 
+int proc_dopipe_max_size(struct ctl_table *table, int write,
+                        void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       return -ENOSYS;
+}
+
 int proc_dointvec_jiffies(struct ctl_table *table, int write,
                    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -3168,6 +3216,7 @@ EXPORT_SYMBOL(proc_douintvec);
 EXPORT_SYMBOL(proc_dointvec_jiffies);
 EXPORT_SYMBOL(proc_dointvec_minmax);
 EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
+EXPORT_SYMBOL_GPL(proc_dopipe_max_size);
 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
 EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
 EXPORT_SYMBOL(proc_dostring);