sys_usbd: Prevent sys_usbd_get_descriptor() from buffer overflow

sys_usbd: Add some more arguments to sys_usbd_attach()'s logging for better debugging
This commit is contained in:
brian218 2023-12-16 21:41:32 +08:00 committed by Elad Ashkenazi
parent 04ef8b8de5
commit d18f929faf
3 changed files with 22 additions and 17 deletions

View File

@ -552,17 +552,15 @@ bool usb_handler_thread::add_ldd(std::string_view product, u16 id_vendor, u16 id
{
if (!dev->open_device())
{
sys_usbd.error("Failed to open device for LDD(VID:0x%04x PID:0x%04x)", dev->device._device.idVendor, dev->device._device.idProduct);
sys_usbd.error("Failed to open USB device(VID=0x%04x, PID=0x%04x) for LDD <%s>", dev->device._device.idVendor, dev->device._device.idProduct, product);
continue;
}
dev->read_descriptors();
dev->assigned_number = dev_counter++; // assign current dev_counter, and atomically increment
sys_usbd.notice("Ldd device matchup for <%s>, assigned as handled_device=0x%x", product, dev->assigned_number);
handled_devices.emplace(dev->assigned_number, std::pair(UsbInternalDevice{0x00, narrow<u8>(dev->assigned_number), 0x02, 0x40}, dev));
send_message(SYS_USBD_ATTACH, dev->assigned_number);
sys_usbd.success("USB device(VID=0x%04x, PID=0x%04x) matches up with LDD <%s>, assigned as handled_device=0x%x", dev->device._device.idVendor, dev->device._device.idProduct, product, dev->assigned_number);
}
}
@ -585,8 +583,8 @@ bool usb_handler_thread::remove_ldd(std::string_view product)
{
if (handled_devices.erase(dev->assigned_number))
{
sys_usbd.notice("Ldd device matchup for <%s>, removed 0x%x from handled_devices", iterator->first, dev->assigned_number);
send_message(SYS_USBD_DETACH, dev->assigned_number);
sys_usbd.success("USB device(VID=0x%04x, PID=0x%04x) matches up with LDD <%s>, unassigned handled_device=0x%x", dev->device._device.idVendor, dev->device._device.idProduct, product, dev->assigned_number);
dev->assigned_number = 0;
}
}
@ -861,8 +859,12 @@ error_code sys_usbd_get_descriptor(ppu_thread& ppu, u32 handle, u32 device_handl
return CELL_EINVAL;
}
u8* ptr = static_cast<u8*>(descriptor.get_ptr());
usbh.handled_devices[device_handle].second->device.write_data(ptr);
if (!descriptor)
{
return CELL_EFAULT;
}
usbh.handled_devices[device_handle].second->device.write_data(reinterpret_cast<u8*>(descriptor.get_ptr()), desc_size);
return CELL_OK;
}
@ -1040,11 +1042,11 @@ error_code sys_usbd_detect_event(ppu_thread& ppu)
return CELL_OK;
}
error_code sys_usbd_attach(ppu_thread& ppu, u32 handle)
error_code sys_usbd_attach(ppu_thread& ppu, u32 handle, u32 unk1, u32 unk2, u32 device_handle)
{
ppu.state += cpu_flag::wait;
sys_usbd.todo("sys_usbd_attach(handle=0x%x)", handle);
sys_usbd.todo("sys_usbd_attach(handle=0x%x, unk1=0x%x, unk2=0x%x, device_handle=0x%x)", handle, unk1, unk2, device_handle);
return CELL_OK;
}

View File

@ -73,7 +73,7 @@ error_code sys_usbd_open_default_pipe(ppu_thread& ppu, u32 handle, u32 device_ha
error_code sys_usbd_close_pipe(ppu_thread& ppu, u32 handle, u32 pipe_handle);
error_code sys_usbd_receive_event(ppu_thread& ppu, u32 handle, vm::ptr<u64> arg1, vm::ptr<u64> arg2, vm::ptr<u64> arg3);
error_code sys_usbd_detect_event(ppu_thread& ppu);
error_code sys_usbd_attach(ppu_thread& ppu, u32 handle);
error_code sys_usbd_attach(ppu_thread& ppu, u32 handle, u32 unk1, u32 unk2, u32 device_handle);
error_code sys_usbd_transfer_data(ppu_thread& ppu, u32 handle, u32 id_pipe, vm::ptr<u8> buf, u32 buf_size, vm::ptr<UsbDeviceRequest> request, u32 type_transfer);
error_code sys_usbd_isochronous_transfer_data(ppu_thread& ppu, u32 handle, u32 id_pipe, vm::ptr<UsbDeviceIsoRequest> iso_request);
error_code sys_usbd_get_transfer_status(ppu_thread& ppu, u32 handle, u32 id_transfer, u32 unk1, vm::ptr<u32> result, vm::ptr<u32> count);

View File

@ -144,6 +144,7 @@ struct UsbDescriptorNode
subnodes.push_back(newnode);
return subnodes.back();
}
u32 get_size() const
{
u32 nodesize = bLength;
@ -153,16 +154,18 @@ struct UsbDescriptorNode
}
return nodesize;
}
void write_data(u8*& ptr)
u32 write_data(u8* ptr, u32 max_size) const
{
ptr[0] = bLength;
ptr[1] = bDescriptorType;
memcpy(ptr + 2, data, bLength - 2);
ptr += bLength;
for (auto& node : subnodes)
u32 size = std::min<u32>(bLength, max_size);
memcpy(ptr, this, size);
for (const auto& node : subnodes)
{
node.write_data(ptr);
const u32 remaining = max_size - size;
if (remaining == 0) break;
size += node.write_data(ptr + size, remaining);
}
return size;
}
};