From: rtm@csail.mit.edu
To: linux-usb@vger.kernel.org
Subject: USB hub code can dereference NULL hub and hub->ports
Date: Mon, 20 Jan 2025 12:27:19 -0500 [thread overview]
Message-ID: <95564.1737394039@localhost> (raw)
[-- Attachment #1: Type: text/plain, Size: 4176 bytes --]
The attached program, which acts via usbip as a USB device or hub,
causes my linux machines to dereference some NULL pointers in
drivers/usb/core/hub.c. These are places where udev->maxchild > 0, but
either usb_hub_to_struct_hub(udev) returns NULL, or the returned hub
has hub->ports == NULL.
This is one such place:
static void recursively_mark_NOTATTACHED(struct usb_device *udev)
{
struct usb_hub *hub = usb_hub_to_struct_hub(udev);
int i;
for (i = 0; i < udev->maxchild; ++i) {
if (hub->ports[i]->child)
And this:
static void hub_disconnect_children(struct usb_device *udev)
{
struct usb_hub *hub = usb_hub_to_struct_hub(udev);
int i;
/* Free up all the children before we remove this device */
for (i = 0; i < udev->maxchild; i++) {
if (hub->ports[i]->child)
This can see NULL hub->ports:
void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
struct usb_hub_descriptor *desc)
{
struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
enum usb_port_connect_type connect_type;
int i;
if (!hub)
return;
if (!hub_is_superspeed(hdev)) {
for (i = 1; i <= hdev->maxchild; i++) {
struct usb_port *port_dev = hub->ports[i - 1];
This can see a NULL hub:
static int hub_set_address(struct usb_device *udev, int devnum)
{
int retval;
unsigned int timeout_ms = USB_CTRL_SET_TIMEOUT;
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
if (hub->hdev->quirks & USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT)
I've attached a demo that runs into some of these NULL dereferences.
It depends on being able to run usbip (and modeprobe vhci-hcd).
# uname -a
Linux xxx 6.13.0-rc3-00017-gf44d154d6e3d #14 SMP Mon Jan 20 04:52:59 EST 2025 x86_64 x86_64 x86_64 GNU/Linux
# cc usbhub11b.c
# ./a.out
...
hub 1-1:1.16: bad descriptor, ignoring hub
hub 1-1:1.16: probe with driver hub failed with error -5
BUG: kernel NULL pointer dereference, address: 0000000000000250
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: Oops: 0000 [#1] SMP DEBUG_PAGEALLOC PTI
CPU: 8 UID: 0 PID: 302 Comm: kworker/8:1 Not tainted 6.13.0-rc3-00017-gf44d154d6
e3d #14
Hardware name: FreeBSD BHYVE/BHYVE, BIOS 14.0 10/17/2021
Workqueue: usb_hub_wq hub_event
RIP: 0010:recursively_mark_NOTATTACHED+0x37/0x90
Code: 48 85 ff 74 71 4c 8b a7 18 04 00 00 4d 85 e4 74 13 85 c0 74 3a 49 8b 94 24
98 00 00 00 4c 8b a2 c8 00 00 00 85 c0 7e 27 31 db <49> 8b 84 24 50 02 00 00 48
8b 04 d8 48 8b 38 48 85 ff 74 05 e8 b0
RSP: 0018:ffffc9000096bd28 EFLAGS: 00010046
RAX: 0000000000000001 RBX: 0000000000000000 RCX: ffff888106224c00
RDX: ffff8881037bc000 RSI: 0000000000000007 RDI: ffff88810a502000
RBP: ffff88810a502000 R08: 000000000000005a R09: 0000000000000000
R10: ffff88810a502000 R11: ffff88810a502000 R12: 0000000000000000
R13: ffff88810a502000 R14: ffff8881062241f0 R15: 0000000000000001
FS: 0000000000000000(0000) GS:ffff88842dc00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000250 CR3: 0000000003636001 CR4: 00000000003706f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
? __die+0x1e/0x60
? page_fault_oops+0x157/0x450
? set_track_prepare+0x3b/0x60
? usb_control_msg+0xfd/0x150
? check_bytes_and_report.isra.0+0x48/0x120
? exc_page_fault+0x66/0x140
? asm_exc_page_fault+0x26/0x30
? recursively_mark_NOTATTACHED+0x37/0x90
? usb_control_msg+0xfd/0x150
usb_disconnect+0x37/0x2c0
hub_event+0xc8f/0x1870
usb_disconnect+0x37/0x2c0
hub_event+0xc8f/0x1870
? trace_event_raw_event_sched_switch+0x51/0x150
process_one_work+0x13f/0x330
worker_thread+0x25a/0x370
? _raw_spin_unlock_irqrestore+0xd/0x20
? __pfx_worker_thread+0x10/0x10
kthread+0xdc/0x110
? __pfx_kthread+0x10/0x10
ret_from_fork+0x2f/0x50
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Robert Morris
rtm@mit.edu
[-- Attachment #2: usbhub11b.c --]
[-- Type: application/octet-stream, Size: 18361 bytes --]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <assert.h>
int symcmd = 5;
int symcmd2 = -1;
int sym_all_scsi = 0;
int sym_scsi_cmd = -1;
unsigned long aa[] = {
0x1000000000ull,
0x10000000ull,
0x25000000ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
0x0ull,
};
int aai;
static inline unsigned long real_symx() {
return aa[aai++];
}
static int started = 0;
static unsigned long symx() {
#define NSYM 64
static unsigned long sa[NSYM];
static int sai = 0;
if(started == 0){
started = 1;
usleep(200000);
for(int i = 0; i < NSYM; i++){
sa[i] = real_symx();
}
}
if(sai >= NSYM){
printf("!!! ran out of SYM\n");
return 0;
}
return sa[sai++];
}
struct op_common {
unsigned short version;
unsigned short code;
unsigned int status;
};
struct usbip_usb_device {
char path[256];
char busid[32];
uint32_t busnum;
uint32_t devnum;
uint32_t speed;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bConfigurationValue;
uint8_t bNumConfigurations;
uint8_t bNumInterfaces;
} __attribute__((packed));
struct usbip_header_basic {
unsigned int command;
unsigned int seqnum;
unsigned int devid;
unsigned int direction;
unsigned int ep;
};
struct usbip_header_cmd_submit {
unsigned int transfer_flags;
int transfer_buffer_length;
int start_frame;
int number_of_packets;
int interval;
unsigned char setup[8];
};
struct usbip_header_ret_submit {
int status;
int actual_length;
int start_frame;
int number_of_packets;
int error_count;
};
int
readable(int fd)
{
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
struct timeval tv;
tv.tv_sec = 4;
tv.tv_usec = 0;
int ss = select(fd + 1, &readfds, (fd_set*)0, (fd_set*)0, &tv);
return FD_ISSET(fd, &readfds);
}
int
readn(int fd, void *xbuf, int n)
{
char *buf = xbuf;
int got = 0;
while(got < n){
if(readable(fd) == 0){
printf("usbip0: timeout\n");
return -1;
}
int cc = read(fd, buf+got, n-got);
if(cc <= 0){
perror("usbip0: read");
return -1;
}
got += cc;
}
return got;
}
void
mkif(char **xp, int num, int alt, int eps, int cl, int subcl, int proto, int iff)
{
char *p = *xp;
// usb_interface_descriptor
*p++ = 9; // bLength
*p++ = 4; // bDescriptorType USB_DT_INTERFACE
*p++ = num; // bInterfaceNumber
*p++ = alt; // bAlternateSetting
*p++ = eps; // bNumEndpoints
*p++ = cl; // bInterfaceClass
*p++ = subcl; // bInterfaceSubClass
*p++ = proto; // bInterfaceProtocol
*p++ = iff; // iInterface
*xp = p;
}
void
mkad(char **xp, int type, int subtype)
{
char *p = *xp;
// Additional Descriptor
*p++ = 0; // bLength (filled in later)
*p++ = type; // bDescriptorType
*p++ = subtype; // bDescriptorSubtype
if(type == 36 && subtype == 1){
// AS_GENERAL
*p++ = 1; // bTerminalLink
*p++ = 1; // bDelay
*p++ = 1; // wFormatTag PCM
p++;
} else if(type == 36 && subtype == 2){
// FORMAT_TYPE
*p++ = 1; // bFormatType
*p++ = 2; // bNrChannels
*p++ = 3; // bSubframeSize
*p++ = 24; // bBitResolution
*p++ = 2; // bSamFreqType
*p++ = 2; // bSamFreqType
p += 5;
} else {
*p++ = 0; // bcdADC
*p++ = 1;
*(short*)p = 0x5f; // wTotalLength
p += 2;
*p++ = 2; // bInCollection
*p++ = 1; // baInterfaceNr(0)
*p++ = 2; // baInterfaceNr(1)
}
*(*xp) = p - (*xp); // bLength
*xp = p;
}
void
mkadx(char **xp, int type, int subtype, int len, int a[])
{
char *p = *xp;
// Additional Descriptor
*p++ = 0; // bLength (filled in later)
*p++ = type; // bDescriptorType
*p++ = subtype; // bDescriptorSubtype
for(int i = 0; i < len - 3; i++)
*p++ = a[i];
*(*xp) = p - (*xp); // bLength
*xp = p;
}
void
mkep(char **xp, int epa, int attr, int maxp)
{
char *p = *xp;
// usb_endpoint_descriptor
*p++ = 9;
*p++ = 5; // bDescriptorType USB_DT_ENDPOINT
*p++ = epa; // bEndpointAddress
*p++ = attr; // bmAttributes
*(short*)p = maxp; // wMaxPacketSize
p += 2;
*p++ = 7; // bInterval
p += 2; // ???
*xp = p;
}
int
main(int argc, char *argv[])
{
struct rlimit r;
r.rlim_cur = r.rlim_max = 0;
setrlimit(RLIMIT_CORE, &r);
int port = 3240;
int s, yes = 1;
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
s = socket(AF_INET, SOCK_STREAM, 0);
if(s < 0){
perror("socket");
exit(1);
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
if(bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0){
perror("fastfingerd: bind");
exit(1);
}
if(listen(s, 3000) < 0){
perror("fastfingerd: listen");
exit(1);
}
system("modprobe vhci-hcd");
// system("usbip/src/usbip attach -r 127.0.0.1 -b 1-1 &");
system("usbip attach -r 127.0.0.1 -b 1-1 &");
sleep(2);
sync();
sleep(1);
int s1;
unsigned sinlen = sizeof(sin);
s1 = accept(s, (struct sockaddr *) &sin, &sinlen);
if(s1 < 0){
perror("accept");
exit(1);
}
close(s);
struct op_common op;
// OP_REQ_IMPORT
readn(s1, &op, sizeof(op));
//printf("version 0x%x code 0x%x status 0x%x\n",
// op.version, op.code, op.status);
char busid[32];
readn(s1, busid, sizeof(busid));
op.code = htons(0x03); // OP_REP_IMPORT
op.status = htonl(0); // ST_OK
write(s1, &op, sizeof(op));
struct usbip_usb_device uud;
memset(&uud, 0, sizeof(uud));
strcpy(uud.busid, busid);
//uud.speed = htonl(2); // USB_SPEED_FULL
uud.speed = htonl(3); // USB_SPEED_HIGH
//uud.speed = htonl(5); // USB_SPEED_SUPER
write(s1, &uud, sizeof(uud));
// now talking to the kernel
int cmdno = 0;
int lastTag = 0; // usb_stor_BulkTransport line 1255
unsigned char CDB[16]; // SCSI command
memset(CDB, 0, sizeof(CDB));
while(1){
struct usbip_header_basic ibh;
//sync(); // don't sync() -- deadlock.
if(readn(s1, &ibh, sizeof(ibh)) < 0)
break;
#if 1
printf("%d: command 0x%x seqnum %d devid 0x%x direction 0x%x ep 0x%x\n",
cmdno,
ntohl(ibh.command),
ntohl(ibh.seqnum),
ntohl(ibh.devid),
ntohl(ibh.direction),
ntohl(ibh.ep));
#endif
if(ntohl(ibh.command) == 1){
// USBIP_CMD_SUBMIT
struct usbip_header_cmd_submit cs;
memset(&cs, 0, sizeof(cs));
if(readn(s1, &cs, sizeof(cs)) < 0)
break;
#if 1
printf(" flags 0x%x buflen %d np %d, ",
ntohl(cs.transfer_flags),
ntohl(cs.transfer_buffer_length),
ntohl(cs.number_of_packets));
for(int i = 0; i < 8; i++)
printf("%02x ", cs.setup[i] & 0xff);
printf("\n");
#endif
int translen = ntohl(cs.transfer_buffer_length);
if(ibh.direction == 0){
char ibuf[4096];
assert(translen <= sizeof(ibuf));
if(readn(s1, ibuf, translen) < 0)
break;
if(translen >= 16 && memcmp(ibuf, "USBC", 4) == 0){
// struct bulk_cb_wrap
lastTag = ibuf[4];
printf(" USBC tag=%d dtl=%d fl=0x%02x lun=%d len=%d\n",
*(int*)(ibuf+4),
*(int*)(ibuf+8),
ibuf[12] & 0xff,
ibuf[13] & 0xff,
ibuf[14] & 0xff);
printf(" ");
for(int i = 0; i < 16; i++)
printf("%02x ", ibuf[15+i] & 0xff);
printf("\n");
memcpy(CDB, ibuf+15, sizeof(CDB));
} else if(translen > 0){
for(int i = 0; i < translen && i < 16; i++)
printf("%02x ", ibuf[i] & 0xff);
printf("\n");
}
}
struct usbip_header_basic obh;
memset(&obh, 0, sizeof(obh));
obh.command = htonl(3); // USBIP_RET_SUBMIT
obh.seqnum = ibh.seqnum;
obh.devid = ibh.devid;
obh.direction = htonl(!ntohl(ibh.direction));
obh.ep = ibh.ep;
write(s1, &obh, sizeof(obh));
char rsbuf[sizeof(cs)];
memset(rsbuf, 0, sizeof(rsbuf));
struct usbip_header_ret_submit *rs = (void*)rsbuf;
if(ibh.direction){
rs->actual_length = htonl(translen);
} else {
rs->actual_length = htonl(31);
}
write(s1, rs, sizeof(rsbuf));
if(ibh.direction){
char buf64[4096];
if(translen > sizeof(buf64)){
printf("huge translen\n");
break;
}
memset(buf64, 0, sizeof(buf64));
if(cs.setup[1] == 0x06){
// USB_REQ_GET_DESCRIPTOR
if(cs.setup[0] == 0x80 && cs.setup[3] == 1){
// USB_DT_DEVICE
// struct usb_device_descriptor
buf64[0] = 18; // bLength
buf64[1] = 1; // bDescriptorType = USB_DT_DEVICE
buf64[2] = 0x10; // bcdUSB
buf64[3] = 0x02; // bcdUSB
buf64[4] = 9; // bDeviceClass
buf64[5] = 0; // bDeviceSubClass
buf64[6] = 2; // bDeviceProtocol
buf64[7] = 64; // bMaxPacketSize0
*(short*)(buf64+8) = 0x2109; // idVendor VIA Labs
*(short*)(buf64+10) = 0x2822; // idProduct Hub
//*(short*)(buf64+8) = 0x1a40; // idVendor Terminus Technology
//*(short*)(buf64+10) = 0x0101; // idProduct Hub
buf64[12] = 0xa3; // bcdDevice
buf64[13] = 1; // bcdDevice
buf64[14] = 1; // iManufacturer
buf64[15] = 2; // iProduct
buf64[16] = 0; // iSerial
buf64[17] = 1; // bNumConfigurations
} else if(cs.setup[0] == 0x80 && cs.setup[3] == 2){
// USB_DT_CONFIG
// struct usb_config_descriptor
char *p = buf64;
*p++ = 9; // bLength
*p++ = 2; // USB_DT_CONFIG
short *lenp = (short*) p;
*(short*)p = 9 + 4*9 + 15*10 + 2*7; // wTotalLength
p += 2;
*p++ = 1; // bNumInterfaces
*p++ = 1; // bConfigurationValue
*p++ = 0; // iConfiguration
*p++ = 0xe0; // bmAttributes
*p++ = 1; // bMaxPower
// interface 0
mkif(&p, 0, 0, 1, 9, 0, 1, 0);
mkep(&p, 0x81, 3, 1);
// interface 0 alt 1
mkif(&p, 0, 1, 1, 9, 0, 2, 0);
mkep(&p, 0x81, 3, 1);
// Binary Object Store Descriptor
*p++ = 5; // bLength
*p++ = 15; // bDescriptorType
*(short*)p = 0x49; // wTotalLength
p += 2;
*p++ = 3; // bNumDeviceCaps
// USB 2.0 Extension Device Capability
*p++ = 7;
*p++ = 16;
*p++ = 2; // bDevCapabilityType
*(int*)p = 6; // bmAttributes
p += 4;
// SuperSpeed USB Device Capability
*p++ = 10;
*p++ = 16;
*p++ = 3; // bDevCapabilityType
*p++ = 0; // bmAttributes
*(short*)p = 0x000e; // wSpeedsSupported
p += 2;
*p++ = 1; // bFunctionalitySupport
*p++ = 4;
*p++ = 231;
*p++ = 0; // ???
// Container ID Device Capability
*p++ = 20;
*p++ = 16;
*p++ = 4;
*p++ = 0;
p += 16;
// SuperSpeedPlus USB Device Capability
*p++ = 28;
*p++ = 16;
*p++ = 10;
*(int*)p = 0x23;
p += 4;
*(short*)p = 0x1100;
p += 2;
*(int*)p = 0x50030;
p += 4;
*(int*)p = 0x500b0;
p += 4;
*(int*)p = 0xa4031;
p += 4;
*(int*)p = 0xa40b1;
p += 4;
p += 3; // ???
// Hub Descriptor
*p++ = 9; // bLength
*p++ = 41; // bDescriptorType
*p++ = 4; // nNbrPorts
*(short*)p = 0xe9; // wHubCharacteristic
p += 2;
*p++ = 50; // bPwrOn2PwrGood
*p++ = 1; // bHubContrCurrent
*p++ = 0; // DeviceRemovable
*p++ = 0xff; // PortPwrCtrlMask
// Device Qualifier
*p++ = 10; // bLength
*p++ = 6; // bDescriptorType
*p++ = 0; // bcdUSB
*p++ = 2;
*p++ = 9; // bDeviceClass
*p++ = 0; // bDeviceSubClass
*p++ = 0; // bDeviceProtocol
*p++ = 64; // bMaxPacketSize0
*p++ = 1; // bNumConfigurations
*p++ = 1; // ???
assert(p - buf64 <= sizeof(buf64));
*lenp = p - buf64;
} else if(cs.setup[0] == 0x80 && cs.setup[3] == 0x0f){
// USB_DT_BOS
// struct usb_bos_descriptor
char *p = buf64;
*p++ = 5; // bLength
*p++ = 15;
*(short*)p = 0x002a; // wTotalLength
p += 2;
*p++ = 3; // bNumDeviceCaps
// usb_ext_cap_descriptor
*p++ = 7; // bLength
*p++ = 16; // bDescriptorType
*p++ = 2; // bDevCapabilityType
*(int*)p = 0x0000f41e; // bmAttributes
p += 4;
// usb_ss_cap_descriptor
*p++ = 10; // bLength
*p++ = 16; // bDescriptorType
*p++ = 3; // bDevCapabilityType
*p++ = 0; // bmAttributes
*(short*)p = 0xe; // wSpeedsSupported
p += 2;
*p++ = 1; // bFunctionalitySupport
*p++ = 10; // bU1devExitLat
*(short*)p = 2047; // bU2DevExitLat
p += 2;
// usb_ssp_cap_descriptor
*p++ = 20; // bLength
*p++ = 16; // bDescriptorType
*p++ = 10; // bDevCapabilityType
*p++ = 0; // bReserved
*(int*)p = 0; // bmAttributes
p += 4;
*(short*)p = 1; // bFunctionalitySupport
p += 2;
p += 2; // wReserved
*(int*)p = 0x000a4030;
p += 4;
*(int*)p = 0x000a40b0;
p += 4;
} else if(cs.setup[0] == 0x80 && cs.setup[3] == 3){
// USB_DT_STRING
char *p = buf64;
*p++ = 6; // length
*p++ = 3; // descriptor type
*p++ = 'a';
*p++ = 'b';
*p++ = 'c';
*p++ = 'd';
} else if(cs.setup[0] == 0xa0){
// usb_hub_descriptor
memset(buf64, 0xff, 32);
buf64[0] = 15; // bDescLength
buf64[1] = 42; // bDescriptorType
buf64[2] = 1; // bNbrPorts
buf64[6] = 8; // bHubContrCurrent
}
} else if(cs.setup[1] == 0 && cs.setup[0] == 0x80){
// USB_REQ_GET_STATUS USB_RT_PORT
// usb_port_status
*(short*)(buf64+0) = 3; // wPortStatus
} else if(cs.setup[1] == 0 && cs.setup[0] == 0xa0){
// USB_REQ_GET_STATUS USB_RT_HUB
// usb_hub_status
memset(buf64, 0xff, 4);
} else if(cs.setup[1] == 0 && cs.setup[0] == 0xa3){
// USB_REQ_GET_STATUS USB_RT_PORT ???
// usb_port_status ???
memset(buf64, 0xff, 8);
} else if(cs.setup[1] == 0 && cs.setup[0] == 0){
// ???
memset(buf64, 0xff, 8);
} else if(cs.setup[1] == 0xfe){
if(ntohl(ibh.ep) == 0){
// US_BULK_GET_MAX_LUN
buf64[0] = 0; // maybe max unit #?
} else {
memcpy(buf64, "USBS", 4);
buf64[4] = lastTag; // make transport.c:1255 happy: bulk_cs_wrap.Tag
}
} else if(ntohl(cs.transfer_flags) == 0x40201 &&
cs.setup[0] == 0 && cs.setup[1] == 0){
// usb_stor_Bulk_transport reading SCSI cmd result
if(CDB[0] == 0x12){
// INQUIRY
buf64[4] = 36 - 5; // response_len
buf64[2] = 14; // scsi_level?
buf64[8] = 0xff; // flags?
buf64[16] = 0xff; // flags?
} else if(CDB[0] == 0x25){
// READ_CAPACITY
*(int*)(buf64+0) = htonl(1024); // lba? capacity?
*(int*)(buf64+4) = htonl(512); // sector size
}
if(sym_all_scsi > 0 || sym_scsi_cmd == CDB[0]){
for(int i = 0; i < 64 && i < translen; i += 8){
*(long*)(buf64 + i) ^= symx();
}
if(CDB[0] == 0x12){
// INQUIRY
buf64[4] = 36 - 5; // response_len
}
}
}
if(cmdno == symcmd || cmdno == symcmd2){
for(int i = 0; i < 64 && i+8 <= sizeof(buf64); i += 8){
*(long*)(buf64 + i) ^= symx();
}
}
write(s1, buf64, translen);
}
} else if(ntohl(ibh.command) == 2){
// USBIP_CMD_UNLINK
// struct usbip_header_cmd_unlink uh;
char buf[sizeof(struct usbip_header_cmd_submit)];
memset(buf, 0, sizeof(buf));
if(readn(s1, buf, sizeof(buf)) < 0)
break;
unsigned int uh = *(int*)buf;;
printf("unlink seq %d\n", ntohl(uh));
struct usbip_header_basic obh;
memset(&obh, 0, sizeof(obh));
obh.command = htonl(4); // USBIP_RET_UNLINK
// obh.seqnum = ibh.seqnum;
obh.seqnum = uh;
obh.devid = ibh.devid;
obh.direction = htonl(!ntohl(ibh.direction));
obh.ep = ibh.ep;
write(s1, &obh, sizeof(obh));
char rsbuf[sizeof(struct usbip_header_cmd_submit)];
memset(rsbuf, 0, sizeof(rsbuf));
write(s1, rsbuf, sizeof(rsbuf));
}
if(cmdno >= 25)
break;
cmdno += 1;
}
usleep(500000);
close(s1);
usleep(500000);
}
next reply other threads:[~2025-01-20 18:01 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-20 17:27 rtm [this message]
2025-01-21 7:01 ` USB hub code can dereference NULL hub and hub->ports Greg KH
2025-01-22 11:37 ` rtm
2025-01-22 15:55 ` Alan Stern
2025-01-22 19:21 ` rtm
2025-01-22 19:26 ` [PATCH] USB: hub: Ignore non-compliant devices with too many configs or interfaces Alan Stern
2025-02-03 15:35 ` Alan Stern
2025-02-03 15:49 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=95564.1737394039@localhost \
--to=rtm@csail.mit.edu \
--cc=linux-usb@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.