Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb/usbip: fix wrong data added to platform device

.data of platform_device_info will be copied into .platform_data of
struct device via platform_device_add_data.

However, vhcis[i] contains a spinlock, is dynamically allocated and
used by other code, so it is not meant to be copied. The workaround
was to use void *vhci as an agent, but it was removed in the commit
suggested below.

This patch adds back the workaround and changes the way of using
platform_data accordingly.

Reported-by: syzbot+e0dbc33630a092ccf033@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/00000000000029242706077f3145@google.com/
Reported-by: syzbot+6867a9777f4b8dc4e256@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/0000000000007634c1060793197c@google.com/
Fixes: b8aaf639b403 ("usbip: Use platform_device_register_full()")
Tested-by: syzbot+6867a9777f4b8dc4e256@syzkaller.appspotmail.com
Link: https://lore.kernel.org/r/0000000000007ac87d0607979b6b@google.com/
Signed-off-by: Hongren Zheng <i@zenithal.me>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Shuah Khan <skhan@linuxfoundation.org>
Link: https://lore.kernel.org/r/ZSpHPCaQ5DDA9Ysl@Sun
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Hongren Zheng and committed by
Greg Kroah-Hartman
17d6b82d d0d27ef8

+8 -7
+8 -7
drivers/usb/usbip/vhci_hcd.c
··· 1139 1139 1140 1140 static int vhci_setup(struct usb_hcd *hcd) 1141 1141 { 1142 - struct vhci *vhci = dev_get_platdata(hcd->self.controller); 1142 + struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller)); 1143 1143 1144 1144 if (usb_hcd_is_primary_hcd(hcd)) { 1145 1145 vhci->vhci_hcd_hs = hcd_to_vhci_hcd(hcd); ··· 1257 1257 /* FIXME: suspend/resume */ 1258 1258 static int vhci_bus_suspend(struct usb_hcd *hcd) 1259 1259 { 1260 - struct vhci *vhci = dev_get_platdata(hcd->self.controller); 1260 + struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller)); 1261 1261 unsigned long flags; 1262 1262 1263 1263 dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); ··· 1271 1271 1272 1272 static int vhci_bus_resume(struct usb_hcd *hcd) 1273 1273 { 1274 - struct vhci *vhci = dev_get_platdata(hcd->self.controller); 1274 + struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller)); 1275 1275 int rc = 0; 1276 1276 unsigned long flags; 1277 1277 ··· 1338 1338 1339 1339 static int vhci_hcd_probe(struct platform_device *pdev) 1340 1340 { 1341 - struct vhci *vhci = dev_get_platdata(&pdev->dev); 1341 + struct vhci *vhci = *((void **)dev_get_platdata(&pdev->dev)); 1342 1342 struct usb_hcd *hcd_hs; 1343 1343 struct usb_hcd *hcd_ss; 1344 1344 int ret; ··· 1396 1396 1397 1397 static void vhci_hcd_remove(struct platform_device *pdev) 1398 1398 { 1399 - struct vhci *vhci = dev_get_platdata(&pdev->dev); 1399 + struct vhci *vhci = *((void **)dev_get_platdata(&pdev->dev)); 1400 1400 1401 1401 /* 1402 1402 * Disconnects the root hub, ··· 1431 1431 if (!hcd) 1432 1432 return 0; 1433 1433 1434 - vhci = dev_get_platdata(hcd->self.controller); 1434 + vhci = *((void **)dev_get_platdata(hcd->self.controller)); 1435 1435 1436 1436 spin_lock_irqsave(&vhci->lock, flags); 1437 1437 ··· 1522 1522 goto err_driver_register; 1523 1523 1524 1524 for (i = 0; i < vhci_num_controllers; i++) { 1525 + void *vhci = &vhcis[i]; 1525 1526 struct platform_device_info pdevinfo = { 1526 1527 .name = driver_name, 1527 1528 .id = i, 1528 - .data = &vhcis[i], 1529 + .data = &vhci, 1529 1530 .size_data = sizeof(void *), 1530 1531 }; 1531 1532