Skip to content

Commit 9676ca7

Browse files
Yang Erkungregkh
authored andcommitted
scsi: sg: Resolve soft lockup issue when opening /dev/sgX
[ Upstream commit d06a310 ] The parameter def_reserved_size defines the default buffer size reserved for each Sg_fd and should be restricted to a range between 0 and 1,048,576 (see https://tldp.org/HOWTO/SCSI-Generic-HOWTO/proc.html). Although the function sg_proc_write_dressz enforces this limit, it is possible to bypass it by directly modifying the module parameter as shown below, which then causes a soft lockup: echo -1 > /sys/module/sg/parameters/def_reserved_size exec 4<> /dev/sg0 watchdog: BUG: soft lockup - CPU#5 stuck for 26 seconds! [bash:537] Modules loaded: CPU: 5 UID: 0 PID: 537 Command: bash, kernel version 6.19.0-rc3+ #134, PREEMPT disabled Hardware: QEMU Standard PC (i440FX + PIIX, 1996), BIOS version 1.16.1-2.fc37 dated 04/01/2014 ... Call Trace: sg_build_reserve+0x5c/0xa0 sg_add_sfp+0x168/0x270 sg_open+0x16e/0x340 chrdev_open+0xbe/0x230 do_dentry_open+0x175/0x480 vfs_open+0x34/0xf0 do_open+0x265/0x3d0 path_openat+0x110/0x290 do_filp_open+0xc3/0x170 do_sys_openat2+0x71/0xe0 __x64_sys_openat+0x6d/0xa0 do_syscall_64+0x62/0x310 entry_SYSCALL_64_after_hwframe+0x76/0x7e The fix is to use module_param_cb to validate and reject invalid values assigned to def_reserved_size. Fixes: 6460e75 ("[SCSI] sg: fixes for large page_size") Signed-off-by: Yang Erkun <yangerkun@huawei.com> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Link: https://patch.msgid.link/20260127062044.3034148-3-yangerkun@huawei.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent dbfe689 commit 9676ca7

1 file changed

Lines changed: 27 additions & 2 deletions

File tree

drivers/scsi/sg.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,10 +1622,35 @@ sg_remove_device(struct device *cl_dev)
16221622
}
16231623

16241624
module_param_named(scatter_elem_sz, scatter_elem_sz, int, S_IRUGO | S_IWUSR);
1625-
module_param_named(def_reserved_size, def_reserved_size, int,
1626-
S_IRUGO | S_IWUSR);
16271625
module_param_named(allow_dio, sg_allow_dio, int, S_IRUGO | S_IWUSR);
16281626

1627+
static int def_reserved_size_set(const char *val, const struct kernel_param *kp)
1628+
{
1629+
int size, ret;
1630+
1631+
if (!val)
1632+
return -EINVAL;
1633+
1634+
ret = kstrtoint(val, 0, &size);
1635+
if (ret)
1636+
return ret;
1637+
1638+
/* limit to 1 MB */
1639+
if (size < 0 || size > 1048576)
1640+
return -ERANGE;
1641+
1642+
def_reserved_size = size;
1643+
return 0;
1644+
}
1645+
1646+
static const struct kernel_param_ops def_reserved_size_ops = {
1647+
.set = def_reserved_size_set,
1648+
.get = param_get_int,
1649+
};
1650+
1651+
module_param_cb(def_reserved_size, &def_reserved_size_ops, &def_reserved_size,
1652+
S_IRUGO | S_IWUSR);
1653+
16291654
MODULE_AUTHOR("Douglas Gilbert");
16301655
MODULE_DESCRIPTION("SCSI generic (sg) driver");
16311656
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)