Skip to content

Commit a321172

Browse files
committed
sys/linux: add descriptions for BSG devices
BSG is a block layer version of SG driver with its own devices, which can be found in /dev/bsg/*. Currently, syzkaller barely touches related code in block/ and drivers/scsi/ source directories, so update the descriptions to nudge the fuzzer in the right direction. Specifically, - create a separate description file dev_bsg.txt; - move openat$bsg from sys.txt and fix the way devices in question are accessed; - describe necessary syscalls and structs, most importantly, sg_io_v4. - add a few TODOs to address later. A few words about flaws in sq_io_v4 description: Some fields were left more ambigious than desired. Once more research into the way bsg operates is done, as well as related coverage is gathered, those flaws will be corrected.
1 parent ed3e87f commit a321172

File tree

3 files changed

+107
-1
lines changed

3 files changed

+107
-1
lines changed

sys/linux/dev_bsg.txt

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright 2025 syzkaller project authors. All rights reserved.
2+
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3+
4+
include <linux/blkdev.h>
5+
include <scsi/scsi.h>
6+
include <scsi/scsi_ioctl.h>
7+
include <scsi/sg.h>
8+
include <linux/bsg.h>
9+
10+
resource fd_bsg[fd_sg]
11+
12+
openat$bsg(fd const[AT_FDCWD], file ptr[in, string[bsg_devices]], flags flags[open_flags], mode const[0]) fd_bsg
13+
14+
# bsg shares some ioctl calls with main sg driver in sys/linux/dev_sg.txt.
15+
# Describe them here separately for the sake of clarity and visibility.
16+
ioctl$BSG_GET_COMMAND_Q(fd fd_bsg, cmd const[SG_GET_COMMAND_Q], arg ptr[out, int32])
17+
ioctl$BSG_SET_COMMAND_Q(fd fd_bsg, cmd const[SG_SET_COMMAND_Q], arg ptr[in, bool32])
18+
19+
ioctl$BSG_GET_VERSION_NUM(fd fd_bsg, cmd const[SG_GET_VERSION_NUM], arg ptr[out, int32])
20+
ioctl$BSG_SET_TIMEOUT(fd fd_bsg, cmd const[SG_SET_TIMEOUT], arg ptr[in, int64])
21+
ioctl$BSG_GET_TIMEOUT(fd fd_bsg, cmd const[SG_GET_TIMEOUT], arg const[0])
22+
ioctl$BSG_GET_RESERVED_SIZE(fd fd_bsg, cmd const[SG_GET_RESERVED_SIZE], arg ptr[out, int32])
23+
ioctl$BSG_SET_RESERVED_SIZE(fd fd_bsg, cmd const[SG_SET_RESERVED_SIZE], arg ptr[in, int32])
24+
ioctl$BSG_EMULATED_HOST(fd fd_bsg, cmd const[SG_EMULATED_HOST], arg ptr[out, int32])
25+
26+
ioctl$BSG_IO(fd fd_bsg, cmd const[SG_IO], arg ptr[inout, sg_io_v4])
27+
28+
# TODO: Double-check and narrow down some of the missing constraints
29+
# on expected values in this struct to make fuzzing more effective.
30+
# For instance, such fields as:
31+
# req_tag, req_prio, d[in,out]_iovec_count, d[in,out]_xferp, flags, usr_ptr
32+
sg_io_v4 {
33+
guard flags[bsg_guard, int32]
34+
prot const[BSG_PROTOCOL_SCSI, int32]
35+
subprot int32[bsg_sub_protocols]
36+
37+
req_len len[req, int64]
38+
req ptr[in, array[int8, 1:SCSI_CDB_SIZE]]
39+
req_tag int32
40+
req_attr const[0, int32]
41+
req_prio int32
42+
req_extra int32
43+
max_resp_len bytesize[resp, int32]
44+
resp ptr[out, array[int8, SCSI_SENSE_BUFFERSIZE]]
45+
46+
# TODO: Figure out the logic behind scatter lists pointed to by din_xferp (and dout_xferp)
47+
# and how to account for it in syz-lang. For now, keep it simple with 0.
48+
dout_iovec_count const[0, int32]
49+
dout_xfer_len len[dout_xferp, int32]
50+
din_iovec_count const[0, int32]
51+
din_xfer_len len[din_xferp, int32]
52+
dout_xferp ptr[in, array[int8, 0:BSG_XFER_SIZE]]
53+
din_xferp ptr[out, array[int8, 0:BSG_XFER_SIZE]]
54+
55+
timeout int32
56+
flags flags[bsg_flags, int32]
57+
usr_ptr int64
58+
spare_in int32
59+
60+
drv_status const[0, int32]
61+
trans_status const[0, int32]
62+
dev_status const[0, int32]
63+
retry_delay const[0, int32]
64+
info const[0, int32]
65+
dur const[0, int32]
66+
resp_len const[0, int32]
67+
din_resid const[0, int32]
68+
dout_resid const[0, int32]
69+
gen_tag const[0, int64]
70+
spare_out const[0, int32]
71+
72+
pad const[0, int32]
73+
}
74+
75+
# TODO: Format for bsg devices' names: "/dev/bsg/a:b:c:d". Figure out if a more sensible option exists
76+
# apart from hardcoding it (like below).
77+
bsg_devices = "/dev/bsg/0:0:0:0", "/dev/bsg/1:0:0:0", "/dev/bsg/2:0:0:0", "/dev/bsg/3:0:0:0"
78+
bsg_sub_protocols = BSG_SUB_PROTOCOL_SCSI_CMD, BSG_SUB_PROTOCOL_SCSI_TMF, BSG_SUB_PROTOCOL_SCSI_TRANSPORT
79+
bsg_flags = BSG_FLAG_Q_AT_TAIL, BSG_FLAG_Q_AT_HEAD
80+
bsg_guard = 0, 'Q'
81+
82+
define SCSI_SENSE_BUFFERSIZE 96
83+
define SCSI_CDB_SIZE 32
84+
define BSG_XFER_SIZE 128

sys/linux/dev_bsg.txt.const

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Code generated by syz-sysgen. DO NOT EDIT.
2+
arches = 386, amd64, arm, arm64, mips64le, ppc64le, riscv64, s390x
3+
AT_FDCWD = 18446744073709551516
4+
BSG_FLAG_Q_AT_HEAD = 32
5+
BSG_FLAG_Q_AT_TAIL = 16
6+
BSG_PROTOCOL_SCSI = 0
7+
BSG_SUB_PROTOCOL_SCSI_CMD = 0
8+
BSG_SUB_PROTOCOL_SCSI_TMF = 1
9+
BSG_SUB_PROTOCOL_SCSI_TRANSPORT = 2
10+
BSG_XFER_SIZE = 128
11+
SCSI_CDB_SIZE = 32
12+
SCSI_SENSE_BUFFERSIZE = 96
13+
SG_EMULATED_HOST = 8707
14+
SG_GET_COMMAND_Q = 8816
15+
SG_GET_RESERVED_SIZE = 8818
16+
SG_GET_TIMEOUT = 8706
17+
SG_GET_VERSION_NUM = 8834
18+
SG_IO = 8837
19+
SG_SET_COMMAND_Q = 8817
20+
SG_SET_RESERVED_SIZE = 8821
21+
SG_SET_TIMEOUT = 8705
22+
__NR_ioctl = 54, amd64:16, arm64:riscv64:29, mips64le:5015
23+
__NR_openat = 56, 386:295, amd64:257, arm:322, mips64le:5247, ppc64le:286, s390x:288

sys/linux/sys.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,6 @@ openat$nmem0(fd const[AT_FDCWD], file ptr[in, string["/dev/nmem0"]], flags flags
727727
openat$nvram(fd const[AT_FDCWD], file ptr[in, string["/dev/nvram"]], flags flags[open_flags], mode const[0]) fd
728728
openat$ocfs2_control(fd const[AT_FDCWD], file ptr[in, string["/dev/ocfs2_control"]], flags flags[open_flags], mode const[0]) fd
729729
openat$nvme_fabrics(fd const[AT_FDCWD], file ptr[in, string["/dev/nvme-fabrics"]], flags flags[open_flags], mode const[0]) fd
730-
openat$bsg(fd const[AT_FDCWD], file ptr[in, string["/dev/bsg"]], flags flags[open_flags], mode const[0]) fd
731730

732731
pipefd {
733732
rfd fd

0 commit comments

Comments
 (0)