|
| 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, int32] |
| 38 | + req ptr[in, array[int8, 1:SCSI_CDB_SIZE]] |
| 39 | + req_tag int64 |
| 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 ptr[inout, array[int8]] |
| 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 |
0 commit comments