usbip: usbip_host: fix NULL-ptr deref and use-after-free errors
usbip_host updates device status without holding lock from stub probe, disconnect and rebind code paths. When multiple requests to import a device are received, these unprotected code paths step all over each other and drive fails with NULL-ptr deref and use-after-free errors. The driver uses a table lock to protect the busid array for adding and deleting busids to the table. However, the probe, disconnect and rebind paths get the busid table entry and update the status without holding the busid table lock. Add a new finer grain lock to protect the busid entry. This new lock will be held to search and update the busid entry fields from get_busid_idx(), add_match_busid() and del_match_busid(). match_busid_show() does the same to access the busid entry fields. get_busid_priv() changed to return the pointer to the busid entry holding the busid lock. stub_probe(), stub_disconnect() and stub_device_rebind() call put_busid_priv() to release the busid lock before returning. This changes fixes the unprotected code paths eliminating the race conditions in updating the busid entries. Reported-by: Jakub Jirasek Signed-off-by: Shuah Khan (Samsung OSG) <shuah@kernel.org> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
7510df3f29
commit
22076557b0
@@ -73,6 +73,7 @@ struct bus_id_priv {
|
||||
struct stub_device *sdev;
|
||||
struct usb_device *udev;
|
||||
char shutdown_busid;
|
||||
spinlock_t busid_lock;
|
||||
};
|
||||
|
||||
/* stub_priv is allocated from stub_priv_cache */
|
||||
@@ -83,6 +84,7 @@ extern struct usb_device_driver stub_driver;
|
||||
|
||||
/* stub_main.c */
|
||||
struct bus_id_priv *get_busid_priv(const char *busid);
|
||||
void put_busid_priv(struct bus_id_priv *bid);
|
||||
int del_match_busid(char *busid);
|
||||
void stub_device_cleanup_urbs(struct stub_device *sdev);
|
||||
|
||||
|
Reference in New Issue
Block a user