aboutsummaryrefslogtreecommitdiffstats
path: root/sys/linux/dev_bsg.txt
blob: f3fc3275bbd13331ff34eb34dee2531f1b30efad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# Copyright 2025 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

include <linux/blkdev.h>
include <scsi/scsi.h>
include <scsi/scsi_ioctl.h>
include <scsi/sg.h>
include <linux/bsg.h>

resource fd_bsg[fd_sg]

openat$bsg(fd const[AT_FDCWD], file ptr[in, string[bsg_devices]], flags flags[open_flags], mode const[0]) fd_bsg

# bsg shares some ioctl calls with main sg driver in sys/linux/dev_sg.txt.
# Describe them here separately for the sake of clarity and visibility.
ioctl$BSG_GET_COMMAND_Q(fd fd_bsg, cmd const[SG_GET_COMMAND_Q], arg ptr[out, int32])
ioctl$BSG_SET_COMMAND_Q(fd fd_bsg, cmd const[SG_SET_COMMAND_Q], arg ptr[in, bool32])

ioctl$BSG_GET_VERSION_NUM(fd fd_bsg, cmd const[SG_GET_VERSION_NUM], arg ptr[out, int32])
ioctl$BSG_SET_TIMEOUT(fd fd_bsg, cmd const[SG_SET_TIMEOUT], arg ptr[in, int64])
ioctl$BSG_GET_TIMEOUT(fd fd_bsg, cmd const[SG_GET_TIMEOUT], arg const[0])
ioctl$BSG_GET_RESERVED_SIZE(fd fd_bsg, cmd const[SG_GET_RESERVED_SIZE], arg ptr[out, int32])
ioctl$BSG_SET_RESERVED_SIZE(fd fd_bsg, cmd const[SG_SET_RESERVED_SIZE], arg ptr[in, int32])
ioctl$BSG_EMULATED_HOST(fd fd_bsg, cmd const[SG_EMULATED_HOST], arg ptr[out, int32])

ioctl$BSG_IO(fd fd_bsg, cmd const[SG_IO], arg ptr[inout, sg_io_v4])

# TODO: Double-check and narrow down some of the missing constraints
# on expected values in this struct to make fuzzing more effective.
# For instance, such fields as:
# req_tag, req_prio, d[in,out]_iovec_count, d[in,out]_xferp, flags, usr_ptr
sg_io_v4 {
	guard			flags[bsg_guard, int32]
	prot			const[BSG_PROTOCOL_SCSI, int32]
	subprot			int32[bsg_sub_protocols]

	req_len			len[req, int32]
	req			ptr[in, array[int8, 1:SCSI_CDB_SIZE]]
	req_tag			int64
	req_attr		const[0, int32]
	req_prio		int32
	req_extra		int32
	max_resp_len		bytesize[resp, int32]
	resp			ptr[out, array[int8, SCSI_SENSE_BUFFERSIZE]]

# TODO: Figure out the logic behind scatter lists pointed to by din_xferp (and dout_xferp)
# and how to account for it in syz-lang. For now, keep it simple with 0.
	dout_iovec_count	const[0, int32]
	dout_xfer_len		len[dout_xferp, int32]
	din_iovec_count		const[0, int32]
	din_xfer_len		len[din_xferp, int32]
	dout_xferp		ptr[in, array[int8, 0:BSG_XFER_SIZE]]
	din_xferp		ptr[out, array[int8, 0:BSG_XFER_SIZE]]

	timeout			int32
	flags			flags[bsg_flags, int32]
	usr_ptr			ptr[inout, array[int8]]
	spare_in		int32

	drv_status		const[0, int32]
	trans_status		const[0, int32]
	dev_status		const[0, int32]
	retry_delay		const[0, int32]
	info			const[0, int32]
	dur			const[0, int32]
	resp_len		const[0, int32]
	din_resid		const[0, int32]
	dout_resid		const[0, int32]
	gen_tag			const[0, int64]
	spare_out		const[0, int32]

	pad			const[0, int32]
}

# TODO: Format for bsg devices' names: "/dev/bsg/a:b:c:d". Figure out if a more sensible option exists
# apart from hardcoding it (like below).
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"
bsg_sub_protocols = BSG_SUB_PROTOCOL_SCSI_CMD, BSG_SUB_PROTOCOL_SCSI_TMF, BSG_SUB_PROTOCOL_SCSI_TRANSPORT
bsg_flags = BSG_FLAG_Q_AT_TAIL, BSG_FLAG_Q_AT_HEAD
bsg_guard = 0, 'Q'

define SCSI_SENSE_BUFFERSIZE	96
define SCSI_CDB_SIZE	32
define BSG_XFER_SIZE	128