All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: Sam Sun <samsun1006219@gmail.com>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org,
	 Greg KH <gregkh@linuxfoundation.org>,
	swboyd@chromium.org, ricardo@marliere.net,  hkallweit1@gmail.com,
	heikki.krogerus@linux.intel.com,  mathias.nyman@linux.intel.com,
	royluo@google.com,  syzkaller-bugs@googlegroups.com,
	xrivendell7@gmail.com
Subject: Re: [Linux kernel bug] general protection fault in disable_store
Date: Fri, 12 Apr 2024 21:08:12 +0800	[thread overview]
Message-ID: <CAEkJfYORHKO16xT3DCS04JFzkquz6oZ5CdC2USJ5-c0WihAMXg@mail.gmail.com> (raw)
In-Reply-To: <92fe8e95-bc01-4d7d-9678-8cfc55cc4a7b@rowland.harvard.edu>

On Thu, Apr 11, 2024 at 11:24 PM Alan Stern <stern@rowland.harvard.edu> wrote:
>
> On Thu, Apr 11, 2024 at 02:52:27PM +0800, Sam Sun wrote:
> > Dear developers and maintainers,
> >
> > We encountered a general protection fault in function disable_store.
> > It is tested against the latest upstream linux (tag 6.9-rc3). C repro
> > and kernel config are attached to this email. Kernel crash log is
> > listed below.
> > ```
> > general protection fault, probably for non-canonical address
> > 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN
> > KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
> > CPU: 1 PID: 9459 Comm: syz-executor414 Not tainted 6.7.0-rc7 #2
> > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
> > RIP: 0010:disable_store+0xd0/0x3d0 drivers/usb/core/port.c:88
> > Code: 02 00 00 4c 8b 75 40 4d 8d be 58 ff ff ff 4c 89 ff e8 a4 20 fa
> > ff 48 89 c2 48 89 c5 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> 3c
> > 02 00 0f 85 b0 02 00 00 48 8b 45 00 48 8d bb 34 05 00 00 48
> > RSP: 0018:ffffc90006e3fc08 EFLAGS: 00010246
> > RAX: dffffc0000000000 RBX: ffff88801d4d4008 RCX: ffffffff86706be8
> > RDX: 0000000000000000 RSI: ffffffff86706c4d RDI: 0000000000000005
> > RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000
> > R10: 0000000000000000 R11: 0000000000000000 R12: 1ffff92000dc7f85
> > R13: ffff88810f4bfb18 R14: ffff88801d4d10a8 R15: ffff88801d4d1000
> > FS:  00007fa0af71b640(0000) GS:ffff888135c00000(0000) knlGS:0000000000000000
> > CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > CR2: 00007fa0af71a4b8 CR3: 0000000022f5f000 CR4: 0000000000750ef0
> > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> > DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> > PKRU: 55555554
>
> > ----------------
> > Code disassembly (best guess):
> >    0:    02 00                    add    (%rax),%al
> >    2:    00 4c 8b 75              add    %cl,0x75(%rbx,%rcx,4)
> >    6:    40                       rex
> >    7:    4d 8d be 58 ff ff ff     lea    -0xa8(%r14),%r15
> >    e:    4c 89 ff                 mov    %r15,%rdi
> >   11:    e8 a4 20 fa ff           call   0xfffa20ba
> >   16:    48 89 c2                 mov    %rax,%rdx
> >   19:    48 89 c5                 mov    %rax,%rbp
> >   1c:    48 b8 00 00 00 00 00     movabs $0xdffffc0000000000,%rax
> >   23:    fc ff df
> >   26:    48 c1 ea 03              shr    $0x3,%rdx
> > * 2a:    80 3c 02 00              cmpb   $0x0,(%rdx,%rax,1) <--
> > trapping instruction
> >   2e:    0f 85 b0 02 00 00        jne    0x2e4
> >   34:    48 8b 45 00              mov    0x0(%rbp),%rax
> >   38:    48 8d bb 34 05 00 00     lea    0x534(%rbx),%rdi
> >   3f:    48                       rex.W
> > ```
> > We analyzed the root cause of this bug. When calling disable_store()
> > in drivers/usb/core/port.c, if function authorized_store() is calling
> > usb_deauthorized_device() concurrently, the usb_interface will be
> > removed by usb_disable_device. However, in function disable_store,
> > usb_hub_to_struct_hub() would try to deref interface, causing
> > nullptr-deref. We also tested other functions in
> > drivers/usb/core/port.c. So far we haven't found a similar problem.
>
> I don't see how this explanation could be correct.  disable_store() is a
> sysfs attribute file for the port device, so when it is called the port
> device structure must still be registered.  The interface structure
> doesn't get removed until after usb_disable_device() calls device_del(),
> which won't return until hub_disconnect() returns, which won't happen
> until after the port devices are unregistered, which doesn't happen
> until disable_store() calls sysfs_break_active_protection(), which is
> after the call to usb_hub_to_struct_hub().
>
> Can you do a little extra debugging to find out exactly which C
> statement causes the trap?  The disassembly above indicates the trap
> happens during a compare against 0 inside disable_store() -- not inside
> usb_hub_to_struct_hub().  Can you figure out which comparison that is?
>

Sorry for the mistake I made when debugging this bug. Now I have more
information about it. Disassembly of function disable_store() in the
latest upstream kernel is listed below.
```
Dump of assembler code for function disable_store:
   ...
   0xffffffff86e907eb <+187>:   lea    -0x8(%r14),%r12
   0xffffffff86e907ef <+191>:   mov    (%rbx),%rax
   0xffffffff86e907f2 <+194>:   mov    %rax,0x20(%rsp)
   0xffffffff86e907f7 <+199>:   lea    -0xa8(%rax),%rdi
   0xffffffff86e907fe <+206>:   mov    %rdi,0x18(%rsp)
   0xffffffff86e90803 <+211>:   call   0xffffffff86e20220
<usb_hub_to_struct_hub>
   0xffffffff86e90808 <+216>:   mov    %rax,%rbx
   0xffffffff86e9080b <+219>:   shr    $0x3,%rax
   0xffffffff86e9080f <+223>:   movabs $0xdffffc0000000000,%rcx
   0xffffffff86e90819 <+233>:   cmpb   $0x0,(%rax,%rcx,1)
   0xffffffff86e9081d <+237>:   je     0xffffffff86e90827 <disable_store+247>
   0xffffffff86e9081f <+239>:   mov    %rbx,%rdi
   0xffffffff86e90822 <+242>:   call   0xffffffff81eeb0b0
<__asan_report_load8_noabort>
   0xffffffff86e90827 <+247>:   lea    0x60(%rsp),%rsi
   ...
```
The cmpb in disable_store()<+233> is generated by KASAN to check the
shadow memory status. If equals 0, which means the load 8 is valid,
pass the KASAN check. However, this time rax is 0, so it first
triggers general protection fault, since 0xdffffc0000000000 is not a
valid address. rax contains the return address of function
usb_hub_to_struct_hub(), in this case is a NULL.

In function usb_hub_to_struct_hub(), I checked hdev and its sub
domains, and they are not NULL. Is it possible that
usb_deauthorized_device() set
hdev->actconfig->interface[0]->dev.driver_data to NULL? I cannot
confirm that since every time I try to breakpoint the code it crashes
differently.

If there is any other thing I could help, please let me know.

Best,
Yue


> Alan Stern
>
> > If you have any questions, please contact us.
> >
> > Reported by Yue Sun <samsun1006219@gmail.com>
> > Reported by xingwei lee <xrivendell7@gmail.com>
> >
> > Best Regards,
> > Yue

  reply	other threads:[~2024-04-12 13:08 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-11  6:52 [Linux kernel bug] general protection fault in disable_store Sam Sun
2024-04-11  6:58 ` Greg KH
2024-04-11  7:19   ` Sam Sun
2024-04-11 15:24 ` Alan Stern
2024-04-12 13:08   ` Sam Sun [this message]
2024-04-12 14:40     ` Alan Stern
2024-04-12 16:26       ` Sam Sun
2024-04-12 18:11         ` Alan Stern
2024-04-12 18:32           ` Alan Stern
2024-04-13  5:08           ` Sam Sun
2024-04-15 14:47             ` Alan Stern
2024-04-16  9:05               ` Sam Sun
2024-04-16 16:35                 ` Alan Stern
2024-04-17  7:39                   ` Sam Sun
2024-04-17 14:23                     ` Alan Stern

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=CAEkJfYORHKO16xT3DCS04JFzkquz6oZ5CdC2USJ5-c0WihAMXg@mail.gmail.com \
    --to=samsun1006219@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=hkallweit1@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@linux.intel.com \
    --cc=ricardo@marliere.net \
    --cc=royluo@google.com \
    --cc=stern@rowland.harvard.edu \
    --cc=swboyd@chromium.org \
    --cc=syzkaller-bugs@googlegroups.com \
    --cc=xrivendell7@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.