Implement ->proc_write_buf() for allow_dio and def_reserved_size so procfs copies in what is written before it pins the entry, and parse the number from that copy. kstrtoul_from_user() looked at the first 66 bytes of whatever was written. Now the whole write is parsed, and anything larger than PAGE_SIZE - 1 bytes fails with -EINVAL from procfs before the capability check. Signed-off-by: Christian Brauner (Amutable) --- drivers/scsi/sg.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index fb3ab74e8727..df955896e65f 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -2288,18 +2288,18 @@ sg_get_dev(int dev) #ifdef CONFIG_SCSI_PROC_FS static int sg_proc_seq_show_int(struct seq_file *s, void *v); -static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer, +static ssize_t sg_proc_write_adio(struct file *filp, char *buffer, size_t count, loff_t *off); static const struct proc_ops adio_proc_ops = { .proc_show = sg_proc_seq_show_int, - .proc_write = sg_proc_write_adio, + .proc_write_buf = sg_proc_write_adio, }; static ssize_t sg_proc_write_dressz(struct file *filp, - const char __user *buffer, size_t count, loff_t *off); + char *buffer, size_t count, loff_t *off); static const struct proc_ops dressz_proc_ops = { .proc_show = sg_proc_seq_show_int, - .proc_write = sg_proc_write_dressz, + .proc_write_buf = sg_proc_write_dressz, }; static int sg_proc_seq_show_version(struct seq_file *s, void *v); @@ -2360,7 +2360,7 @@ static int sg_proc_seq_show_int(struct seq_file *s, void *v) } static ssize_t -sg_proc_write_adio(struct file *filp, const char __user *buffer, +sg_proc_write_adio(struct file *filp, char *buffer, size_t count, loff_t *off) { int err; @@ -2368,7 +2368,7 @@ sg_proc_write_adio(struct file *filp, const char __user *buffer, if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; - err = kstrtoul_from_user(buffer, count, 0, &num); + err = kstrtoul(buffer, 0, &num); if (err) return err; sg_allow_dio = num ? 1 : 0; @@ -2376,7 +2376,7 @@ sg_proc_write_adio(struct file *filp, const char __user *buffer, } static ssize_t -sg_proc_write_dressz(struct file *filp, const char __user *buffer, +sg_proc_write_dressz(struct file *filp, char *buffer, size_t count, loff_t *off) { int err; @@ -2385,7 +2385,7 @@ sg_proc_write_dressz(struct file *filp, const char __user *buffer, if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; - err = kstrtoul_from_user(buffer, count, 0, &k); + err = kstrtoul(buffer, 0, &k); if (err) return err; if (k <= 1048576) { /* limit "big buff" to 1 MB */ -- 2.53.0