github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/sys/linux/dev_comedi.txt (about) 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 <uapi/asm/ioctl.h> 5 include <uapi/linux/fcntl.h> 6 include <uapi/linux/comedi.h> 7 8 # Descriptions for fuzzing COMEDI drivers. 9 10 # Currently, there is little hope to fuzz most comedi drivers as that requires special qemu setup with emulated pci capabilities, 11 # while some usb drivers (like vmk80xx) are accessible via vusb approach. 12 # For now, focus instead on manually configurable legacy drivers: create static devices via module option comedi.comedi_num_legacy_minors, 13 # and attempt to configure them via COMEDI_DEVCONFIG ioctl. This leads to marginally deeper exploration of this driver stack. 14 15 # TODO: Expand coverage properly by emulating required pci hardware. 16 17 resource fd_comedi[fd] 18 19 openat$comedi(fd const[AT_FDCWD], file ptr[in, string[comedi_devices]], flags flags[open_flags], mode const[0]) fd_comedi 20 21 # Account for both configurable and dynamically allocated comedi devices. Depending on what value is passed 22 # to config option 'comedi.comedi_num_legacy_minors=N', the first N devices will be static. No reason to set N 23 # higher than 4. 24 # TODO: Come up with a more elegant way to list devices to open. Maybe a modified syz_open_dev() is in order? 25 comedi_devices = "/dev/comedi0", "/dev/comedi1", "/dev/comedi2", "/dev/comedi3", "/dev/comedi4", "/dev/comedi5" 26 27 ioctl$COMEDI_DEVCONFIG(fd fd_comedi, cmd const[COMEDI_DEVCONFIG], arg ptr[in, comedi_devconfig]) 28 ioctl$COMEDI_DEVINFO(fd fd_comedi, cmd const[COMEDI_DEVINFO], arg ptr[out, comedi_devinfo]) 29 ioctl$COMEDI_SUBDINFO(fd fd_comedi, cmd const[COMEDI_SUBDINFO], arg ptr[out, comedi_subdinfo]) 30 ioctl$COMEDI_CHANINFO(fd fd_comedi, cmd const[COMEDI_CHANINFO], arg ptr[inout, comedi_chaninfo]) 31 ioctl$COMEDI_LOCK(fd fd_comedi, cmd const[COMEDI_LOCK]) 32 ioctl$COMEDI_UNLOCK(fd fd_comedi, cmd const[COMEDI_UNLOCK]) 33 ioctl$COMEDI_CANCEL(fd fd_comedi, cmd const[COMEDI_CANCEL]) 34 ioctl$COMEDI_RANGEINFO(fd fd_comedi, cmd const[COMEDI_RANGEINFO], arg ptr[inout, comedi_rangeinfo]) 35 ioctl$COMEDI_CMD(fd fd_comedi, cmd const[COMEDI_CMD], arg ptr[inout, comedi_cmd]) 36 ioctl$COMEDI_CMDTEST(fd fd_comedi, cmd const[COMEDI_CMDTEST], arg ptr[inout, comedi_cmd]) 37 ioctl$COMEDI_INSNLIST(fd fd_comedi, cmd const[COMEDI_INSNLIST], arg ptr[inout, comedi_insnlist]) 38 ioctl$COMEDI_INSN(fd fd_comedi, cmd const[COMEDI_INSN], arg ptr[inout, comedi_insn]) 39 ioctl$COMEDI_BUFCONFIG(fd fd_comedi, cmd const[COMEDI_BUFCONFIG], arg ptr[inout, comedi_bufconfig]) 40 ioctl$COMEDI_BUFINFO(fd fd_comedi, cmd const[COMEDI_BUFINFO], arg ptr[inout, comedi_bufinfo]) 41 ioctl$COMEDI_POLL(fd fd_comedi, cmd const[COMEDI_POLL]) 42 ioctl$COMEDI_SETRSUBD(fd fd_comedi, cmd const[COMEDI_SETRSUBD]) 43 ioctl$COMEDI_SETWSUBD(fd fd_comedi, cmd const[COMEDI_SETWSUBD]) 44 45 comedi_devconfig { 46 # TODO: For now, use driver names to try to configure devices. Maybe add all related board names to these strings as well? 47 board_name string[comedi_drivers, COMEDI_NAMELEN] 48 options array[int32, COMEDI_NDEVCONFOPTS] 49 } 50 51 # List of all drivers that support "manual" configuration via comedi_config utility or COMEDI_DEVCONFIG ioctl. Only driver names for now. 52 comedi_drivers = "8255", "adl_pci9118", "adq12b", "aio_aio12_8", "aio_iiro_16", "amplc_dio200", "amplc_pc236", "amplc_pc263", "c6xdigio", "comedi_bond", "comedi_parport", "comedi_test", "dac02", "das08_isa", "das16m1", "das1800", "das6402", "das800", "dmm32at", "dt2801", "dt2811", "dt2814", "dt2815", "dt2817", "dt282x", "fl512", "mpc624", "multiq3", "ni_at_a2150", "ni_at_ao", "ni_atmio16d", "ni_daq_700", "ni_labpc", "pcl711", "pcl724", "pcl726", "pcl730", "pcl812", "pcl816", "pcl818", "pcm3724", "pcmad", "pcmda12", "pcmmio", "pcmuio", "rti800", "rti802", "s526" 53 54 comedi_devinfo { 55 version int32 56 n_subdevs int32 57 driver_name array[int8, COMEDI_NAMELEN] 58 board_name array[int8, COMEDI_NAMELEN] 59 read_subd int32 60 write_subd int32 61 unused array[const[0, int32], 30] 62 } 63 64 comedi_subdinfo { 65 type flags[comedi_subd_type, int32] 66 n_chan int32 67 subd_flags flags[comedi_sdf, int32] 68 timer_type int32 69 len_chanlist int32 70 maxdata int32 71 flags int32 72 range_type int32 73 sett_time_0 int32 74 insn_bits_supp flags[comedi_insn_bits_supp, int32] 75 unused array[const[0, int32], 8] 76 } 77 78 comedi_subd_type = COMEDI_SUBD_UNUSED, COMEDI_SUBD_AI, COMEDI_SUBD_AO, COMEDI_SUBD_DI, COMEDI_SUBD_DO, COMEDI_SUBD_DIO, COMEDI_SUBD_COUNTER, COMEDI_SUBD_TIMER, COMEDI_SUBD_MEMORY, COMEDI_SUBD_CALIB, COMEDI_SUBD_PROC, COMEDI_SUBD_SERIAL, COMEDI_SUBD_PWM 79 comedi_sdf = SDF_BUSY, SDF_BUSY_OWNER, SDF_LOCKED, SDF_LOCK_OWNER, SDF_MAXDATA, SDF_FLAGS, SDF_RANGETYPE, SDF_PWM_COUNTER, SDF_PWM_HBRIDGE, SDF_CMD, SDF_SOFT_CALIBRATED, SDF_CMD_WRITE, SDF_CMD_READ, SDF_READABLE, SDF_WRITABLE, SDF_WRITEABLE, SDF_INTERNAL, SDF_GROUND, SDF_COMMON, SDF_DIFF, SDF_OTHER, SDF_DITHER, SDF_DEGLITCH, SDF_MMAP, SDF_RUNNING, SDF_LSAMPL, SDF_PACKED 80 comedi_insn_bits_supp = COMEDI_UNKNOWN_SUPPORT, COMEDI_SUPPORTED, COMEDI_UNSUPPORTED 81 82 # Some data used in comedi_chaninfo depends on what COMEDI_SUBDINFO ioctl obtains. Keep it simple for now. 83 # Use semi-arbitrary limits on list sizes as they may differ depending on the driver. 84 comedi_chaninfo { 85 subdev int32 86 maxd_list ptr[out, array[int32, 0:COMEDI_CHANINFO_MAX_LIST_SIZE]] 87 flaglist ptr[out, int32] 88 rangelist ptr[out, array[int32, 0:COMEDI_CHANINFO_MAX_LIST_SIZE]] 89 unused array[const[0, int32], 4] 90 } 91 92 comedi_rangeinfo { 93 range_type int32 94 range_ptr ptr[out, array[comedi_krange]] 95 } 96 97 comedi_krange { 98 min int32 99 max int32 100 flags flags[comedi_krange_flags, int32] 101 } 102 103 comedi_krange_flags = RF_EXTERNAL, 0 104 105 comedi_bufconfig { 106 subd int32 107 flags int32 108 max_size int32 109 size int32 110 unused array[const[0, int32], 4] 111 } 112 113 comedi_bufinfo { 114 subd int32 115 bytes_read int32 116 117 # These are indexes, not proper pointers. 118 buf_write_ptr int32 119 buf_read_ptr int32 120 121 buf_write_count int32 122 buf_read_count int32 123 bytes_written int32 124 unused array[const[0, int32], 4] 125 } 126 127 # TODO: COMEDI_INSN[LIST] ioctls reliably trigger a WARNING stemming from attempts to kmalloc too much. 128 # While the error is real, descriptions may be flawed as well. Should we restrict sizes here to trigger the warning less often? 129 comedi_insn { 130 insn flags[comedi_insn_type, int32] 131 n len[data, int32] 132 # Use semi-arbitrary limits on data as COMEDI expects it to be. 133 data ptr[inout, array[int32, COMEDI_INSN_MIN_DATA_SIZE:COMEDI_INSN_MAX_DATA_SIZE]] 134 subdev int32 135 chanspec int32 136 unused array[const[0, int32], 3] 137 } 138 139 comedi_insn_type = INSN_MASK_WRITE, INSN_MASK_READ, INSN_MASK_SPECIAL, INSN_READ, INSN_WRITE, INSN_BITS, INSN_CONFIG, INSN_DEVICE_CONFIG, INSN_GTOD, INSN_WAIT, INSN_INTTRIG 140 141 comedi_insnlist { 142 n_insns len[insns, int32] 143 # Restrict somewhat the number of COMEDI instructions otherwise same kmalloc warning slows down the fuzzing process. 144 insns ptr[inout, array[comedi_insn, 0:COMEDI_INSNLIST_SIZE]] 145 } 146 147 comedi_cmd { 148 subdev int32 149 flags flags[comedi_cmdf, int32] 150 start_src flags[comedi_trig, int32] 151 start_arg int32 152 scan_begin_src flags[comedi_trig, int32] 153 scan_begin_arg int32 154 convert_src flags[comedi_trig, int32] 155 convert_arg int32 156 scan_end_src flags[comedi_trig, int32] 157 scan_end_arg int32 158 stop_src flags[comedi_trig, int32] 159 stop_arg int32 160 chanlist ptr[inout, array[int32]] 161 chanlist_len len[chanlist, int32] 162 data ptr[inout, array[int8]] 163 data_len len[data, int32] 164 } 165 166 comedi_cmdf = CMDF_BOGUS, CMDF_PRIORITY, CMDF_WAKE_EOS, CMDF_WRITE, CMDF_RAWDATA, CMDF_ROUND_MASK, CMDF_ROUND_NEAREST, CMDF_ROUND_DOWN, CMDF_ROUND_UP, CMDF_ROUND_UP_NEXT 167 comedi_trig = TRIG_ANY, TRIG_INVALID, TRIG_NONE, TRIG_NOW, TRIG_FOLLOW, TRIG_TIMER, TRIG_COUNT, TRIG_EXT, TRIG_INT, TRIG_OTHER 168 169 define COMEDI_CHANINFO_MAX_LIST_SIZE 65536 170 define COMEDI_INSN_MIN_DATA_SIZE 15 171 define COMEDI_INSN_MAX_DATA_SIZE 65537 172 define COMEDI_INSNLIST_SIZE 16