# Copyright 2019 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. # https://elixir.bootlin.com/linux/latest/source/drivers/usb/core/devio.c include include include include include define MAXDRIVERNAME USBDEVFS_MAXDRIVERNAME + 1 resource fd_usbfs[fd] syz_open_dev$usbfs(dev ptr[in, string["/dev/bus/usb/00#/00#"]], id intptr, flags flags[open_flags]) fd_usbfs read$usbfs(fd fd_usbfs, buf buffer[out], count len[buf]) mmap$usbfs(addr vma, len len[addr], prot flags[mmap_prot], flags flags[mmap_flags], fd fd_usbfs, offset fileoff) _ = __NR_mmap2 # TODO: arg is a pointer to a previously submitted URB. ioctl$USBDEVFS_REAPURB(fd fd_usbfs, cmd const[USBDEVFS_REAPURB], arg ptr[out, int64]) ioctl$USBDEVFS_REAPURBNDELAY(fd fd_usbfs, cmd const[USBDEVFS_REAPURBNDELAY], arg ptr[out, int64]) ioctl$USBDEVFS_CONTROL(fd fd_usbfs, cmd const[USBDEVFS_CONTROL], arg ptr[in, usbdevfs_ctrltransfer]) ioctl$USBDEVFS_BULK(fd fd_usbfs, cmd const[USBDEVFS_BULK], arg ptr[in, usbdevfs_bulktransfer]) ioctl$USBDEVFS_RESETEP(fd fd_usbfs, cmd const[USBDEVFS_RESETEP], arg ptr[in, usbdevfs_ep]) ioctl$USBDEVFS_RESET(fd fd_usbfs, cmd const[USBDEVFS_RESET]) ioctl$USBDEVFS_CLEAR_HALT(fd fd_usbfs, cmd const[USBDEVFS_CLEAR_HALT], arg ptr[in, usbdevfs_ep]) ioctl$USBDEVFS_GETDRIVER(fd fd_usbfs, cmd const[USBDEVFS_GETDRIVER], arg ptr[inout, usbdevfs_getdriver]) ioctl$USBDEVFS_CONNECTINFO(fd fd_usbfs, cmd const[USBDEVFS_CONNECTINFO], arg ptr[out, usbdevfs_connectinfo]) ioctl$USBDEVFS_SETINTERFACE(fd fd_usbfs, cmd const[USBDEVFS_SETINTERFACE], arg ptr[in, usbdevfs_setinterface]) ioctl$USBDEVFS_SETCONFIGURATION(fd fd_usbfs, cmd const[USBDEVFS_SETCONFIGURATION], arg ptr[in, int32]) ioctl$USBDEVFS_SUBMITURB(fd fd_usbfs, cmd const[USBDEVFS_SUBMITURB], arg ptr[in, usbdevfs_urb]) # TODO: arg is a pointer to a previously submitted URB. ioctl$USBDEVFS_DISCARDURB(fd fd_usbfs, cmd const[USBDEVFS_DISCARDURB], arg ptr[in, int64]) ioctl$USBDEVFS_DISCSIGNAL(fd fd_usbfs, cmd const[USBDEVFS_DISCSIGNAL], arg ptr[in, usbdevfs_disconnectsignal]) ioctl$USBDEVFS_CLAIMINTERFACE(fd fd_usbfs, cmd const[USBDEVFS_CLAIMINTERFACE], arg ptr[in, int32]) ioctl$USBDEVFS_RELEASEINTERFACE(fd fd_usbfs, cmd const[USBDEVFS_RELEASEINTERFACE], arg ptr[in, int32]) ioctl$USBDEVFS_IOCTL(fd fd_usbfs, cmd const[USBDEVFS_IOCTL], arg ptr[in, usbdevfs_ioctl]) ioctl$USBDEVFS_CLAIM_PORT(fd fd_usbfs, cmd const[USBDEVFS_CLAIM_PORT], arg ptr[in, int32]) ioctl$USBDEVFS_RELEASE_PORT(fd fd_usbfs, cmd const[USBDEVFS_RELEASE_PORT], arg ptr[in, int32]) ioctl$USBDEVFS_GET_CAPABILITIES(fd fd_usbfs, cmd const[USBDEVFS_GET_CAPABILITIES], arg ptr[out, int32]) ioctl$USBDEVFS_DISCONNECT_CLAIM(fd fd_usbfs, cmd const[USBDEVFS_DISCONNECT_CLAIM], arg ptr[in, usbdevfs_disconnect_claim]) ioctl$USBDEVFS_ALLOC_STREAMS(fd fd_usbfs, cmd const[USBDEVFS_ALLOC_STREAMS], arg ptr[in, usbdevfs_streams]) ioctl$USBDEVFS_FREE_STREAMS(fd fd_usbfs, cmd const[USBDEVFS_FREE_STREAMS], arg ptr[in, usbdevfs_streams]) ioctl$USBDEVFS_DROP_PRIVILEGES(fd fd_usbfs, cmd const[USBDEVFS_DROP_PRIVILEGES], arg ptr[in, int32]) ioctl$USBDEVFS_GET_SPEED(fd fd_usbfs, cmd const[USBDEVFS_GET_SPEED]) ioctl$USBDEVFS_FORBID_SUSPEND(fd fd_usbfs, cmd const[USBDEVFS_FORBID_SUSPEND]) ioctl$USBDEVFS_ALLOW_SUSPEND(fd fd_usbfs, cmd const[USBDEVFS_ALLOW_SUSPEND]) ioctl$USBDEVFS_WAIT_FOR_RESUME(fd fd_usbfs, cmd const[USBDEVFS_WAIT_FOR_RESUME]) usbdevfs_ep { num int8:7[0:15] dir int8:1 } usbdevfs_ctrltransfer { bRequestType flags[usb_request_type_flags, int8] bRequest flags[usb_requests, int8] wValue int16 wIndex int16 wLength len[data, int16] timeout int32 data ptr[inout, array[int8]] } usb_request_type_flags = USB_DIR_OUT, USB_DIR_IN, USB_TYPE_MASK, USB_TYPE_STANDARD, USB_TYPE_CLASS, USB_TYPE_VENDOR, USB_TYPE_RESERVED, USB_RECIP_MASK, USB_RECIP_DEVICE, USB_RECIP_INTERFACE, USB_RECIP_ENDPOINT, USB_RECIP_OTHER, USB_RECIP_PORT, USB_RECIP_RPIPE usbdevfs_bulktransfer { ep align32[usbdevfs_ep] len len[data, int32] timeout int32 data ptr[inout, array[int8]] } usbdevfs_getdriver { interface int32 driver array[int8, MAXDRIVERNAME] } usbdevfs_connectinfo { devnum int32 slow int8 } usbdevfs_setinterface { interface int32 altsetting int32 } usbdevfs_urb [ urb_type_control usbdevfs_urb_control urb_type_bulk usbdevfs_urb_bulk urb_type_interrupt usbdevfs_urb_interrupt urb_type_iso usbdevfs_urb_iso ] [varlen] usbdevfs_urb_control { type const[USBDEVFS_URB_TYPE_CONTROL, int8] endpoint usbdevfs_ep status int32 flags flags[urb_flags, int32] buffer ptr[in, usb_ctrlrequest] buffer_length len[buffer, int32] actual_length int32 start_frame int32 u const[0, int32] error_count int32 signr int32 usercontext ptr[in, array[int8]] } usb_ctrlrequest { bRequestType flags[usb_request_type_flags, int8] bRequest flags[usb_requests, int8] wValue int16 wIndex int16 wLength int16 } [packed] usbdevfs_urb_bulk { type const[USBDEVFS_URB_TYPE_BULK, int8] endpoint usbdevfs_ep status int32 flags flags[urb_flags, int32] buffer ptr[in, array[int8]] buffer_length len[buffer, int32] actual_length int32 start_frame int32 stream_id int32 error_count int32 signr int32 usercontext ptr[in, array[int8]] } usbdevfs_urb_interrupt { type const[USBDEVFS_URB_TYPE_INTERRUPT, int8] endpoint usbdevfs_ep status int32 flags flags[urb_flags, int32] buffer ptr[in, array[int8]] buffer_length len[buffer, int32] actual_length int32 start_frame int32 u const[0, int32] error_count int32 signr int32 usercontext ptr[in, array[int8]] } usbdevfs_urb_iso { type const[USBDEVFS_URB_TYPE_ISO, int8] endpoint usbdevfs_ep status int32 flags flags[urb_flags, int32] buffer ptr[in, array[int8]] buffer_length len[buffer, int32] actual_length int32 start_frame int32 number_of_packets len[iso_frame_desc, int32] error_count int32 signr int32 usercontext ptr[in, array[int8]] iso_frame_desc array[usbdevfs_iso_packet_desc, 1:127] } urb_flags = USBDEVFS_URB_SHORT_NOT_OK, USBDEVFS_URB_ISO_ASAP, USBDEVFS_URB_BULK_CONTINUATION, USBDEVFS_URB_NO_FSBR, USBDEVFS_URB_ZERO_PACKET, USBDEVFS_URB_NO_INTERRUPT usbdevfs_iso_packet_desc { length int32 actual_length int32 status int32 } usbdevfs_disconnectsignal { signr int32 context ptr[in, array[int8]] } usbdevfs_ioctl [ usbdevfs_disconnect usbdevfs_ioctl_disconnect usbdevfs_connect usbdevfs_ioctl_connect usbdevfs_driver usbdevfs_ioctl_driver ] usbdevfs_ioctl_disconnect { ifno int32 ioctl_code const[USBDEVFS_DISCONNECT, int32] data const[0, intptr] } usbdevfs_ioctl_connect { ifno int32 ioctl_code const[USBDEVFS_CONNECT, int32] data const[0, intptr] } usbdevfs_ioctl_driver { ifno int32 ioctl_code int32 data ptr[inout, array[int8]] } usbdevfs_disconnect_claim { interface int32 flags flags[disconnect_flags, int32] driver array[int8, MAXDRIVERNAME] } disconnect_flags = USBDEVFS_DISCONNECT_CLAIM_IF_DRIVER, USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER usbdevfs_streams { num_streams int32[2:65536] num_eps len[eps, int32] eps array[usbdevfs_ep, 1:USB_MAXENDPOINTS] }