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

Commit 5c198237 authored by Hemant Gupta's avatar Hemant Gupta Committed by Gerrit - the friendly Code Review server
Browse files

Bluetooth: uhid: Prevent deadlock while waiting for response



This patch prevents deadlock between userspace and kernel space uhid
driver by releasing the held mutex(s) before waiting for response for
set/get report. Without this there was potential deadlock in code
that lead to unnecessary wait for 5 seconds for response for set report
to be received from user space which could not come, as mutex was held
leading to blockage of read and further write.

Change-Id: I3f003f33bdf2a0aeb4821598c667cbf61db83b9b
CRs-Fixed: 963213
Signed-off-by: default avatarHemant Gupta <hemantg@codeaurora.org>
parent 1fdcf773
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -159,9 +159,27 @@ static int __uhid_report_queue_and_wait(struct uhid_device *uhid,
	uhid_queue(uhid, ev);
	spin_unlock_irqrestore(&uhid->qlock, flags);

	/*
	 * Assumption: report_lock and devlock are both locked. So unlock
	 * before sleeping.
	 */
	mutex_unlock(&uhid->report_lock);
	mutex_unlock(&uhid->devlock);
	ret = wait_event_interruptible_timeout(uhid->report_wait,
				!uhid->report_running || !uhid->running,
				5 * HZ);
	ret = mutex_lock_interruptible(&uhid->devlock);
	if (ret)
		return ret;
	ret = mutex_lock_interruptible(&uhid->report_lock);
	if (ret) {
		/*
		 * Failed to lock, unlock previous mutex before exiting
		 * this function.
		 */
		mutex_unlock(&uhid->devlock);
		return ret;
	}
	if (!ret || !uhid->running || uhid->report_running)
		ret = -EIO;
	else if (ret < 0)