Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db90e7a1 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: fix concurrent buffer access in the hub driver



This patch (as849) fixes a bug in the USB hub driver.  A single
pre-allocated buffer is used for all port status reads, but nothing
guarantees exclusive use of the buffer.  A mutex is added to provide
this guarantee.

Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent af59cf40
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ struct usb_hub {
		struct usb_hub_status	hub;
		struct usb_port_status	port;
	}			*status;	/* buffer for status reports */
	struct mutex		status_mutex;	/* for the status buffer */

	int			error;		/* last reported error */
	int			nerrors;	/* track consecutive errors */
@@ -535,6 +536,7 @@ static int hub_hub_status(struct usb_hub *hub,
{
	int ret;

	mutex_lock(&hub->status_mutex);
	ret = get_hub_status(hub->hdev, &hub->status->hub);
	if (ret < 0)
		dev_err (hub->intfdev,
@@ -544,6 +546,7 @@ static int hub_hub_status(struct usb_hub *hub,
		*change = le16_to_cpu(hub->status->hub.wHubChange); 
		ret = 0;
	}
	mutex_unlock(&hub->status_mutex);
	return ret;
}

@@ -617,6 +620,7 @@ static int hub_configure(struct usb_hub *hub,
		ret = -ENOMEM;
		goto fail;
	}
	mutex_init(&hub->status_mutex);

	hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
	if (!hub->descriptor) {
@@ -1396,6 +1400,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
{
	int ret;

	mutex_lock(&hub->status_mutex);
	ret = get_port_status(hub->hdev, port1, &hub->status->port);
	if (ret < 4) {
		dev_err (hub->intfdev,
@@ -1407,6 +1412,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
		*change = le16_to_cpu(hub->status->port.wPortChange); 
		ret = 0;
	}
	mutex_unlock(&hub->status_mutex);
	return ret;
}