From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
To: Alan Stern <stern@rowland.harvard.edu>, Kees Cook <kees@kernel.org>
Cc: Jiri Kosina <jikos@kernel.org>,
Benjamin Tissoires <bentiss@kernel.org>,
<linux-usb@vger.kernel.org>, <linux-input@vger.kernel.org>,
<syzkaller-bugs@googlegroups.com>, <linux-kernel@vger.kernel.org>,
<syzbot+c52569baf0c843f35495@syzkaller.appspotmail.com>,
<linux-hardening@vger.kernel.org>
Subject: Re: [PATCH] HID: usbhid: fix recurrent out-of-bounds bug in usbhid_parse()
Date: Tue, 28 Jan 2025 05:45:21 -0800 [thread overview]
Message-ID: <807cfa6f-5863-4fe4-8294-76d5cdbc3aac@fintech.ru> (raw)
In-Reply-To: <d1ad84e3-7da9-4dc8-a095-b9fbe191eb56@rowland.harvard.edu>
Hello,
On 6/4/24 10:45, Alan Stern wrote:
> On Tue, Jun 04, 2024 at 10:21:15AM -0700, Kees Cook wrote:
>> On Tue, Jun 04, 2024 at 10:09:43AM -0700, Nikita Zhandarovich wrote:
>>> Hi,
>>>
>>> On 6/4/24 07:15, Jiri Kosina wrote:
>>>> On Tue, 4 Jun 2024, Kees Cook wrote:
>>>>
>>>>> This isn't the right solution. The problem is that hid_class_descriptor
>>>>> is a flexible array but was sized as a single element fake flexible
>>>>> array:
>>>>>
>>>>> struct hid_descriptor {
>>>>> __u8 bLength;
>>>>> __u8 bDescriptorType;
>>>>> __le16 bcdHID;
>>>>> __u8 bCountryCode;
>>>>> __u8 bNumDescriptors;
>>>>>
>>>>> struct hid_class_descriptor desc[1];
>>>>> } __attribute__ ((packed));
>>>>>
>>>>> This likely needs to be:
>>>>>
>>>>> struct hid_class_descriptor desc[] __counted_by(bNumDescriptors);
>>>>>
>>>>> And then check for any sizeof() uses of the struct that might have changed.
Alan, I finally got around to preparing a revised version of the
required patch and encountered a few issues. I could use some advice in
this matter...
If we change 'struct hid_descriptor' as you suggested, which does make
sense, most occurrences of that type are easy enough to fix.
1) usbhid_parse() starts working properly if there are more than 1
descriptors, sizeof(struct hid_descriptor) may be turned into something
crude but straightforward like sizeof(struct hid_descriptor) +
sizeof(struct hid_class_descriptor).
2) 'hid_descriptor' in drivers/hid/hid-hyperv.c remains innocuous as
well as only 1 descriptor expected there. My impression is only some
small changes are needed there.
However, the issue that stumps me is the following: static struct
hid_descriptor hidg_desc in drivers/usb/gadget/function/f_hid.c relies
on a static nature of that one descriptor. hidg_desc ends up being used
elsewhere, in other static structures. Basically, using __counted_by
requires a lot of changes, as I see it, out of scope of merely closing
an UBSAN error.
Is this approach still worthy pursuing or should I look into some neater
solution?
Best regards,
Nikita
>>>>
>>>> Ah, you are of course right, not sure what I was thinking. Thanks a lot
>>>> for catching my brainfart.
>>>>
>>>> I am dropping the patch for now; Nikita, will you please send a refreshed
>>>> one?
>>>>
>>>
>>> Thanks for catching my mistake.
>>>
>>> I'll gladly send a revised version, hoping to do it very soon.
>>
>> I spent a little more time looking at this, and I'm not sure I
>> understand where the actual space for the descriptors comes from?
>> There's interface->extra that is being parsed, and effectively
>> hid_descriptor is being mapped into it, but it uses "sizeof(struct
>> hid_descriptor)" for the limit.
>
> That's a lower limit, not an upper limit. The hid_descriptor must
> include at least one hid_class_descriptor, but it can include more.
> That's what the min_t() calculation of num_descriptors is meant to
> figure out.
>
>> Is more than 1 descriptor expected to
>> work correctly?
>
> More than one hid_class_descriptor -- yes.
>
>> Or is the limit being ignored? I'm a bit confused by
>> this code...
>
> Does this explain it?
>
> Alan Stern
next prev parent reply other threads:[~2025-01-28 13:45 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-24 12:01 [PATCH] HID: usbhid: fix recurrent out-of-bounds bug in usbhid_parse() Nikita Zhandarovich
2024-06-04 8:15 ` Jiri Kosina
2024-06-04 14:11 ` Kees Cook
2024-06-04 14:15 ` Jiri Kosina
2024-06-04 17:09 ` Nikita Zhandarovich
2024-06-04 17:21 ` Kees Cook
2024-06-04 17:45 ` Alan Stern
2025-01-28 13:45 ` Nikita Zhandarovich [this message]
2025-01-28 17:00 ` Alan Stern
2025-01-29 1:53 ` Kees Cook
2025-01-29 19:21 ` Terry Junge
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=807cfa6f-5863-4fe4-8294-76d5cdbc3aac@fintech.ru \
--to=n.zhandarovich@fintech.ru \
--cc=bentiss@kernel.org \
--cc=jikos@kernel.org \
--cc=kees@kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=stern@rowland.harvard.edu \
--cc=syzbot+c52569baf0c843f35495@syzkaller.appspotmail.com \
--cc=syzkaller-bugs@googlegroups.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.