Discovered by Atuin - Automated Vulnerability Discovery Engine. Validate that the URB payload is long enough for the frame header and the advertised data length before accessing it, so truncated transfers are rejected with -EIO, preventing the driver from reading out-of-bounds and leaking kernel memory to USB devices. Signed-off-by: Tianchu Chen --- drivers/nfc/port100.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c index 00d8ea6dc..7cd439f66 100644 --- a/drivers/nfc/port100.c +++ b/drivers/nfc/port100.c @@ -568,11 +568,17 @@ static void port100_tx_update_payload_len(void *_frame, int len) le16_add_cpu(&frame->datalen, len); } -static bool port100_rx_frame_is_valid(const void *_frame) +static bool port100_rx_frame_is_valid(const void *_frame, size_t len) { u8 checksum; const struct port100_frame *frame = _frame; + if (len < sizeof(*frame)) + return false; + + if (len < (size_t)(le16_to_cpu(frame->datalen)) + sizeof(*frame)) + return false; + if (frame->start_frame != cpu_to_be16(PORT100_FRAME_SOF) || frame->extended_frame != cpu_to_be16(PORT100_FRAME_EXT)) return false; @@ -636,7 +642,7 @@ static void port100_recv_response(struct urb *urb) in_frame = dev->in_urb->transfer_buffer; - if (!port100_rx_frame_is_valid(in_frame)) { + if (!port100_rx_frame_is_valid(in_frame, urb->actual_length)) { nfc_err(&dev->interface->dev, "Received an invalid frame\n"); cmd->status = -EIO; goto sched_wq; -- 2.39.5