[PATCH RFC 13/23] scsi: sg: let procfs copy in writes
From: Christian Brauner
Date: Mon Nov 02 2026 - 13:31:49 EST
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) <brauner@xxxxxxxxxx>
---
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 c7386fbe5580..87569e302f26 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2287,18 +2287,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);
@@ -2359,7 +2359,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;
@@ -2367,7 +2367,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;
@@ -2375,7 +2375,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;
@@ -2384,7 +2384,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