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

Commit bd1d89b3 authored by Ido Shayevitz's avatar Ido Shayevitz
Browse files

usb: gadget: mbim: protect packets queue corruption



The f_mbim usb function driver maintain a packets queue sent from the
host as encapsulated commands which need to be read by the QBI using the
mbim_read fops.

In case of excessive messages arriving from the host we end up with simple
race condition between the queue writer and queue reader which end up in
corruption of the queue and packet loss.

Simply add a missing lock protection upon reading (deleting) a packet from
queue.

CRs-Fixed: 576720
Change-Id: I8aff04745f02cbefd3d6b83d944cad9aa1726ebf
Signed-off-by: default avatarIdo Shayevitz <idos@codeaurora.org>
parent 2c8ba2e7
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1695,8 +1695,10 @@ mbim_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
		return -EIO;
	}

	spin_lock(&dev->lock);
	while (list_empty(&dev->cpkt_req_q)) {
		pr_debug("Requests list is empty. Wait.\n");
		spin_unlock(&dev->lock);
		ret = wait_event_interruptible(dev->read_wq,
			!list_empty(&dev->cpkt_req_q));
		if (ret < 0) {
@@ -1705,11 +1707,13 @@ mbim_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
			return -ERESTARTSYS;
		}
		pr_debug("Received request packet\n");
		spin_lock(&dev->lock);
	}

	cpkt = list_first_entry(&dev->cpkt_req_q, struct ctrl_pkt,
							list);
	if (cpkt->len > count) {
		spin_unlock(&dev->lock);
		mbim_unlock(&dev->read_excl);
		pr_err("cpkt size too big:%d > buf size:%d\n",
				cpkt->len, count);
@@ -1719,6 +1723,7 @@ mbim_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
	pr_debug("cpkt size:%d\n", cpkt->len);

	list_del(&cpkt->list);
	spin_unlock(&dev->lock);
	mbim_unlock(&dev->read_excl);

	ret = copy_to_user(buf, cpkt->buf, cpkt->len);