fix: use correct RET_UNLINK status codes matching kernel behavior
The CMD_UNLINK handler returned -EINVAL for devid mismatch and -ENOENT for not-found URBs, but the Linux kernel's stub_recv_cmd_unlink() returns status 0 in both cases. Non-standard status codes could confuse the host kernel's vhci_hcd driver. Fixes 64 fuzzer crash artifacts across fuzz_urb_hid and fuzz_urb_cdc targets. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
32daaa5e2f
commit
d5ddb48eff
1 changed files with 7 additions and 2 deletions
|
|
@ -576,6 +576,9 @@ pub async fn handle_urb_loop<T: AsyncReadExt + AsyncWriteExt + Unpin + Send + 's
|
|||
trace!("Got USBIP_CMD_UNLINK for seqnum={unlink_seqnum:10x?}");
|
||||
|
||||
// Validate devid matches the imported device.
|
||||
// On mismatch, respond with status 0 ("not found"), matching
|
||||
// the Linux kernel's stub_recv_cmd_unlink() which returns 0
|
||||
// when the target URB doesn't exist.
|
||||
if header.devid != expected_devid {
|
||||
warn!(
|
||||
"UNLINK devid mismatch: got {:#x}, expected {:#x}",
|
||||
|
|
@ -584,7 +587,7 @@ pub async fn handle_urb_loop<T: AsyncReadExt + AsyncWriteExt + Unpin + Send + 's
|
|||
header.command = USBIP_RET_UNLINK.into();
|
||||
let res = UsbIpResponse::UsbIpRetUnlink {
|
||||
header: header.clone(),
|
||||
status: (-22i32) as u32, // EINVAL
|
||||
status: 0,
|
||||
};
|
||||
match res.to_bytes() {
|
||||
Ok(bytes) => {
|
||||
|
|
@ -618,10 +621,12 @@ pub async fn handle_urb_loop<T: AsyncReadExt + AsyncWriteExt + Unpin + Send + 's
|
|||
// URB already completed and removed from in_flight.
|
||||
// Its RET_SUBMIT is already in the channel, so our
|
||||
// RET_UNLINK will follow it — safe to send now.
|
||||
// Status 0 matches the Linux kernel's stub_recv_cmd_unlink()
|
||||
// behavior when the target URB is not found.
|
||||
trace!("UNLINK: seqnum={unlink_seqnum} not found in-flight (already completed)");
|
||||
let res = UsbIpResponse::UsbIpRetUnlink {
|
||||
header: header.clone(),
|
||||
status: (-2i32) as u32, // ENOENT
|
||||
status: 0,
|
||||
};
|
||||
match res.to_bytes() {
|
||||
Ok(bytes) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue