With commit 69bec7259853 ("USB: core: let USB device know device node"),
the port1 argument of usb_alloc_dev() gets overwritten as follows:
... usb_alloc_dev(..., unsigned port1)
{
...
if (!parent->parent) {
port1 = usb_hcd_find_raw_port_number(..., port1);
}
...
}
Later on, this now overwritten port1 gets assigned to ->portnum:
dev->portnum = port1;
However, since xhci_find_raw_port_number() isn't idempotent, the
aforementioned commit causes a number of KASAN splats like the following:
BUG: KASAN: slab-out-of-bounds in xhci_find_raw_port_number+0x98/0x170
at addr ffff8801d9311670
Read of size 8 by task kworker/2:1/87
[...]
Workqueue: usb_hub_wq hub_event
0000000000000188 000000005814b877 ffff8800cba17588 ffffffff8191447e
0000000041b58ab3 ffffffff82a03209 ffffffff819143a2 ffffffff82a252f4
ffff8801d93115e0 0000000000000188 ffff8801d9311628 ffff8800cba17588
Call Trace:
[<ffffffff8191447e>] dump_stack+0xdc/0x15e
[<ffffffff819143a2>] ? _atomic_dec_and_lock+0xa2/0xa2
[<ffffffff814e2cd1>] ? print_section+0x61/0xb0
[<ffffffff814e4939>] print_trailer+0x179/0x2c0
[<ffffffff814f0d84>] object_err+0x34/0x40
[<ffffffff814f4388>] kasan_report_error+0x2f8/0x8b0
[<ffffffff814eb91e>] ? __slab_alloc+0x5e/0x90
[<ffffffff812178c0>] ? __lock_is_held+0x90/0x130
[<ffffffff814f5091>] kasan_report+0x71/0xa0
[<ffffffff814ec082>] ? kmem_cache_alloc_trace+0x212/0x560
[<ffffffff81d99468>] ? xhci_find_raw_port_number+0x98/0x170
[<ffffffff814f33d4>] __asan_load8+0x64/0x70
[<ffffffff81d99468>] xhci_find_raw_port_number+0x98/0x170
[<ffffffff81db0105>] xhci_setup_addressable_virt_dev+0x235/0xa10
[<ffffffff81d9ea51>] xhci_setup_device+0x3c1/0x1430
[<ffffffff8121cddd>] ? trace_hardirqs_on+0xd/0x10
[<ffffffff81d9fac0>] ? xhci_setup_device+0x1430/0x1430
[<ffffffff81d9fad3>] xhci_address_device+0x13/0x20
[<ffffffff81d2081a>] hub_port_init+0x55a/0x1550
[<ffffffff81d28705>] hub_event+0xef5/0x24d0
[<ffffffff81d27810>] ? hub_port_debounce+0x2f0/0x2f0
[<ffffffff8195e1ee>] ? debug_object_deactivate+0x1be/0x270
[<ffffffff81210203>] ? print_rt_rq+0x53/0x2d0
[<ffffffff8121657d>] ? trace_hardirqs_off+0xd/0x10
[<ffffffff8226acfb>] ? _raw_spin_unlock_irqrestore+0x5b/0x60
[<ffffffff81250000>] ? irq_domain_set_hwirq_and_chip+0x30/0xb0
[<ffffffff81256339>] ? debug_lockdep_rcu_enabled+0x39/0x40
[<ffffffff812178c0>] ? __lock_is_held+0x90/0x130
[<ffffffff81196877>] process_one_work+0x567/0xec0
[...]
Afterwards, xhci reports some functional errors:
xhci_hcd 0000:00:14.0: ERROR: unexpected setup address command completion
code 0x11.
xhci_hcd 0000:00:14.0: ERROR: unexpected setup address command completion
code 0x11.
usb 4-3: device not accepting address 2, error -22
Fix this by not overwriting the port1 argument in usb_alloc_dev(), but
storing the raw port number as required by OF in an additional variable,
raw_port.
Fixes: 69bec7259853 ("USB: core: let USB device know device node")
Signed-off-by: Nicolai Stange <[email protected]>
---
Applicable to linux-next-20160317
drivers/usb/core/usb.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index ffa5cf1..6b4fc16 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -424,6 +424,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
struct usb_device *dev;
struct usb_hcd *usb_hcd = bus_to_hcd(bus);
unsigned root_hub = 0;
+ unsigned raw_port;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
@@ -498,11 +499,11 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
if (!parent->parent) {
/* device under root hub's port */
- port1 = usb_hcd_find_raw_port_number(usb_hcd,
+ raw_port = usb_hcd_find_raw_port_number(usb_hcd,
port1);
}
dev->dev.of_node = usb_of_get_child_node(parent->dev.of_node,
- port1);
+ raw_port);
/* hub driver sets up TT records */
}
--
2.7.2
Hi Nicolai,
[auto build test WARNING on next-20160317]
[cannot apply to v4.5-rc7 v4.5-rc6 v4.5-rc5 v4.5]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Nicolai-Stange/usb-core-usb_alloc_dev-fix-setting-of-portnum/20160318-062419
config: i386-randconfig-x017-201611 (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
drivers/usb/core/usb.c: In function 'usb_alloc_dev':
>> drivers/usb/core/usb.c:505:22: warning: 'raw_port' may be used uninitialized in this function [-Wmaybe-uninitialized]
dev->dev.of_node = usb_of_get_child_node(parent->dev.of_node,
^
vim +/raw_port +505 drivers/usb/core/usb.c
4a0cd967 Sarah Sharp 2009-09-04 489 if (port1 < 15)
7206b001 Sarah Sharp 2009-04-27 490 dev->route = parent->route +
7206b001 Sarah Sharp 2009-04-27 491 (port1 << ((parent->level - 1)*4));
4a0cd967 Sarah Sharp 2009-09-04 492 else
4a0cd967 Sarah Sharp 2009-09-04 493 dev->route = parent->route +
4a0cd967 Sarah Sharp 2009-09-04 494 (15 << ((parent->level - 1)*4));
7206b001 Sarah Sharp 2009-04-27 495 }
^1da177e Linus Torvalds 2005-04-16 496
^1da177e Linus Torvalds 2005-04-16 497 dev->dev.parent = &parent->dev;
0031a06e Kay Sievers 2008-05-02 498 dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
^1da177e Linus Torvalds 2005-04-16 499
69bec725 Peter Chen 2016-02-19 500 if (!parent->parent) {
69bec725 Peter Chen 2016-02-19 501 /* device under root hub's port */
23f4c0b9 Nicolai Stange 2016-03-17 502 raw_port = usb_hcd_find_raw_port_number(usb_hcd,
69bec725 Peter Chen 2016-02-19 503 port1);
69bec725 Peter Chen 2016-02-19 504 }
69bec725 Peter Chen 2016-02-19 @505 dev->dev.of_node = usb_of_get_child_node(parent->dev.of_node,
23f4c0b9 Nicolai Stange 2016-03-17 506 raw_port);
69bec725 Peter Chen 2016-02-19 507
^1da177e Linus Torvalds 2005-04-16 508 /* hub driver sets up TT records */
^1da177e Linus Torvalds 2005-04-16 509 }
^1da177e Linus Torvalds 2005-04-16 510
12c3da34 Alan Stern 2005-11-23 511 dev->portnum = port1;
^1da177e Linus Torvalds 2005-04-16 512 dev->bus = bus;
^1da177e Linus Torvalds 2005-04-16 513 dev->parent = parent;
:::::: The code at line 505 was first introduced by commit
:::::: 69bec725985324e79b1c47ea287815ac4ddb0521 USB: core: let USB device know device node
:::::: TO: Peter Chen <[email protected]>
:::::: CC: Greg Kroah-Hartman <[email protected]>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Please drop in favour of v2 where the issue reported by the kbuild test
robot has been fixed.
Thanks and sorry,
Nicolai