From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: "HE WEI (ギカク)" <skyexpoc@gmail.com>
Cc: Israel Cepeda <israel.a.cepeda.lopez@intel.com>,
Hans de Goede <hansg@kernel.org>,
Andi Shyti <andi.shyti@kernel.org>,
Sakari Ailus <sakari.ailus@linux.intel.com>,
linux-usb@vger.kernel.org, linux-i2c@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 0/3] usbio: fix two out-of-bounds accesses and a hang
Date: Sun, 26 Jul 2026 13:09:54 +0200 [thread overview]
Message-ID: <2026072622-refusing-smasher-6eed@gregkh> (raw)
In-Reply-To: <20260726080129.44969-1-skyexpoc@gmail.com>
On Sun, Jul 26, 2026 at 04:59:10PM +0900, HE WEI (ギカク) wrote:
> This is variant analysis around 8c6314489550 ("usb: misc: usbio: bound
> bulk IN response length to the received transfer"), which fixed a slab
> out-of-bounds read in usbio_bulk_msg(). Re-reading that function,
> usbio_ctrl_msg() and the I2C client built on top of them turned up three
> further issues.
>
> Patch 1 fixes the length checks in usbio_ctrl_msg() and
> usbio_bulk_msg(). They are computed as "<buf>_len - sizeof(*pkt)", u16
> minus size_t, which wraps for any endpoint smaller than the protocol
> header. usb_parse_endpoint() only clamps wMaxPacketSize downwards, so
> a device can advertise 1 and turn the check off entirely; the first I2C
> transfer then overflows a one byte slab object. The overflow completes
> before usb_bulk_msg() is reached, so it does not depend on the host
> controller accepting the transfer. Fixed by validating the three
> lengths once in usbio_probe(), which is the only place that assigns
> them.
>
> Patch 2 is the equivalent arithmetic in i2c-usbio.c, where the overhead
> is 10 rather than 5. The interesting value there is exactly 10: the
> chunk size is then 0 and the split loop in usbio_i2c_read() never
> advances, so a device that keeps answering keeps the loop alive
> uninterruptibly while holding usbio->bulk_mutex. That is a hang rather
> than memory corruption, and patch 1 does not address it. This is also
> the one patch in the series with a behaviour change -- a bridge whose
> bulk wMaxPacketSize is below 11 no longer gets an I2C adapter -- and the
> commit message spells out why such an adapter could never have
> completed a transfer in the first place.
>
> Patch 3 is a different bug from the two above, and the one that affects
> existing hardware. usbio_ctrl_msg() and usbio_bulk_msg() hex dump the
> reply with "%*phN" using a length the device supplied and that has not
> been validated yet. hex_string() caps the field width at 64, not at
> the buffer size, so the dump reads up to byte 67 of ctrlbuf and byte 68
> of rxbuf: out of bounds for every low, full and high speed ep0 packet
> size and for the bulk sizes these bridges actually use. It needs no
> malformed descriptor at all, only the dev_dbg() calls enabled.
>
> The new probe checks do not reject any supported bridge: the low, full
> and high speed devices this driver binds to have an ep0 packet size of
> at least 8, and they use bulk endpoints of 64, or 63 via
> USBIO_QUIRK_BULK_MAXP_63.
>
> What was verified, and what was not:
>
> - All three build cleanly with x86_64 gcc 14.2.0 at W=1, with
> CONFIG_DYNAMIC_DEBUG both disabled and enabled.
>
> - The out-of-bounds accesses in patches 1 and 3, and the
> non-terminating loop in patch 2, reproduce against a userspace model
> that copies the struct definitions from usbio.h and the checks and
> stores from usbio.c and i2c-usbio.c verbatim, with only
> devm_kzalloc(), usb_bulk_msg() and usb_control_msg() replaced; the
> memory errors are reported by AddressSanitizer. The same source
> built with the patches applied is clean, and both a normal device
> (ep0 64, bulk 64/64) and the USBIO_QUIRK_BULK_MAXP_63 path still
> work.
>
> - The decision space was swept exhaustively, endpoint sizes 0..2048
> against caller lengths 0..4101: the mainline bulk check can be
> bypassed for exactly 0..4 and the control check for exactly 0..3.
> After patch 1 no accepted endpoint size admits an overflow, and no
> size that could carry a payload byte is rejected.
>
> - I have not run any of this on hardware or on dummy_hcd. The
> reachability arguments are read from usbcore and from
> lib/vsprintf.c, not observed at runtime. I am happy to build a
> raw-gadget reproducer if that would help review.
>
> Patches 1 and 3 touch drivers/usb/misc/usbio.c and patch 2 touches
> drivers/i2c/busses/i2c-usbio.c; MAINTAINERS lists all three files under
> the same INTEL USBIO entry, so they are sent as one series. They apply
> to mainline 3dab139d4795, to usb-next and to usb-testing.
>
> HE WEI (ギカク) (3):
> usb: misc: usbio: reject endpoints smaller than the packet header
> i2c: usbio: reject bridges with undersized transfer buffers
> usb: misc: usbio: bound the debug hex dumps by the received length
>
> drivers/i2c/busses/i2c-usbio.c | 14 ++++++++++++
> drivers/usb/misc/usbio.c | 50 ++++++++++++++++++++++++++++++++++++++----
> 2 files changed, 60 insertions(+), 4 deletions(-)
As you obviously used a LLM for these, why did it not properly tag the
changes with an "Assisted-by:" tag? That is required.
thanks,
greg k-h
next prev parent reply other threads:[~2026-07-26 11:11 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-26 7:59 [PATCH 0/3] usbio: fix two out-of-bounds accesses and a hang HE WEI (ギカク)
2026-07-26 7:59 ` [PATCH 1/3] usb: misc: usbio: reject endpoints smaller than the packet header HE WEI (ギカク)
2026-07-26 7:59 ` [PATCH 2/3] i2c: usbio: reject bridges with undersized transfer buffers HE WEI (ギカク)
2026-07-26 7:59 ` [PATCH 3/3] usb: misc: usbio: bound the debug hex dumps by the received length HE WEI (ギカク)
2026-07-26 11:09 ` Greg Kroah-Hartman [this message]
2026-07-26 11:32 ` [PATCH 0/3] usbio: fix two out-of-bounds accesses and a hang skyexpoc
2026-07-26 11:43 ` Greg Kroah-Hartman
2026-07-26 11:59 ` HE WEI(ギカク)
2026-07-26 12:18 ` Greg Kroah-Hartman
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=2026072622-refusing-smasher-6eed@gregkh \
--to=gregkh@linuxfoundation.org \
--cc=andi.shyti@kernel.org \
--cc=hansg@kernel.org \
--cc=israel.a.cepeda.lopez@intel.com \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=sakari.ailus@linux.intel.com \
--cc=skyexpoc@gmail.com \
/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.