From patchwork Thu Dec 7 06:34:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vicki Pfau X-Patchwork-Id: 751487 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=endrift.com header.i=@endrift.com header.b="Zoy9TCBL" X-Greylist: delayed 572 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Wed, 06 Dec 2023 22:44:01 PST Received: from endrift.com (endrift.com [173.255.198.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3BFC0D62 for ; Wed, 6 Dec 2023 22:44:01 -0800 (PST) Received: from nebulosa.vulpes.eutheria.net (71-212-26-68.tukw.qwest.net [71.212.26.68]) by endrift.com (Postfix) with ESMTPSA id 9A132A26E; Wed, 6 Dec 2023 22:34:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=endrift.com; s=2020; t=1701930868; bh=2kBvNVJtVywUoIBHRTvqaNJxMQubVU7/aaghrciAqzA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Zoy9TCBLueVCAUzUu1gVrvNcOStdgB9YGyNrmgBZ2zhcYlgL5mH63A9Dc+jMyIsWH GVPmmkpCxZ3BNq1fwyrDk+30VI4pl+in+skZGZ1HiNkJeVgA3R38zbVZgbv/sO+EqX b4BHrQl+To2lKht1rvO0biq2DAdVPhzGyU2M8IVmv7KLHVCFSYBfoZy4WkDHxnAPHD EeMeQZ8nckDmYbQ5qgjo2RJ4g2SrFQJN2fJp+05yM17IHb5N9xvYn8cpclMO3yHpjs 0nGBkzacUF9j3ykpUos9e6f504a982ej25K58VKCscslIkmZWtqKEGX0M4UQe9eZtx gAn+eKit+Efeg== From: Vicki Pfau To: Dmitry Torokhov , linux-input@vger.kernel.org Cc: Vicki Pfau Subject: [PATCH 1/2] Input: uinput - Allow uinput_request_submit wait interrupting Date: Wed, 6 Dec 2023 22:34:05 -0800 Message-ID: <20231207063406.556770-2-vi@endrift.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231207063406.556770-1-vi@endrift.com> References: <20231207063406.556770-1-vi@endrift.com> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently, uinput_request_submit will only fail if the request wait times out. However, in other places this wait is interruptable, and in this specific location it can lead to issues, such as causing system suspend to hang until the request times out. Since the timeout is so long, this can cause the appearance of a total system freeze. Making the wait interruptable resolves this and possibly further issues. Signed-off-by: Vicki Pfau --- drivers/input/misc/uinput.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index d98212d55108..0330e72798db 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -183,7 +183,11 @@ static int uinput_request_submit(struct uinput_device *udev, if (retval) goto out; - if (!wait_for_completion_timeout(&request->done, 30 * HZ)) { + retval = wait_for_completion_interruptible_timeout(&request->done, 30 * HZ); + if (retval == -ERESTARTSYS) + goto out; + + if (!retval) { retval = -ETIMEDOUT; goto out; } From patchwork Thu Dec 7 06:34:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vicki Pfau X-Patchwork-Id: 751865 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=endrift.com header.i=@endrift.com header.b="QdMVj81P" Received: from endrift.com (endrift.com [173.255.198.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5FB0010C4 for ; Wed, 6 Dec 2023 22:44:01 -0800 (PST) Received: from nebulosa.vulpes.eutheria.net (71-212-26-68.tukw.qwest.net [71.212.26.68]) by endrift.com (Postfix) with ESMTPSA id EC957A2AC; Wed, 6 Dec 2023 22:34:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=endrift.com; s=2020; t=1701930869; bh=lmiCqfNSVoqjQzNW2pRae5gjNIsS0E0cWUeYhrGPa/4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QdMVj81PZxhe1NTKXS3aogktGYlDc32DCMr47FLD7a75ZrvtF1DXGaX1cGIwwd3zp RiKfJVblGphvIU5VAPKPAIeEkDvoB6nNZ/z9KYrsNLp8666gYyCRmmdWTzLzFu62N/ uWKZcaSfYodHtgKCnMsrvJKPTOKSX3BkyxHHThYDKG0St9W/aTKuID46fHQ3J0zxpo XFxlASScFIci1OQ7tdhU5hufjQgL8+eEqRtPX5L+rzUqLOQBJQp1F9LfXB0bDgV4mD hEBXdZkcvDHT0Uo/lI9nhW4CegadQLQLa1tfN5XqQYX0V78nB/tzcilSwBTACiB7jY Sz1w6ZcuzPS3w== From: Vicki Pfau To: Dmitry Torokhov , linux-input@vger.kernel.org Cc: Vicki Pfau Subject: [PATCH 2/2] Input: uinput - Release mutex while unregistering input device Date: Wed, 6 Dec 2023 22:34:06 -0800 Message-ID: <20231207063406.556770-3-vi@endrift.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231207063406.556770-1-vi@endrift.com> References: <20231207063406.556770-1-vi@endrift.com> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Any pending requests may be holding a mutex from its own subsystem, e.g. evdev, while waiting to be able to claim the uinput device mutex. However, unregistering the device may try to claim that mutex, leading to a deadlock. To prevent this from happening, we need to temporarily give up the lock before calling input_unregister_device. Fixes: e8b95728f724 ("Input: uinput - avoid FF flush when destroying device") Signed-off-by: Vicki Pfau --- drivers/input/misc/uinput.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 0330e72798db..ac6e5baa2093 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -296,17 +296,34 @@ static void uinput_destroy_device(struct uinput_device *udev) udev->state = UIST_NEW_DEVICE; if (dev) { + udev->dev = NULL; name = dev->name; phys = dev->phys; if (old_state == UIST_CREATED) { uinput_flush_requests(udev); + + /* + * Any pending requests may be holding a mutex from its + * own subsystem, e.g. evdev, while waiting to be able + * to claim the uinput device mutex. However, + * unregistering the device may try to claim that + * mutex, leading to a deadlock. To prevent this from + * happening, we need to temporarily give up the lock. + * + * Since this function is only called immediately + * before the caller exits the critical section without + * doing any further operations on the device, this + * is safe and we can immediately reclaim the mutex + * when done so the unlock is still balanced. + */ + mutex_unlock(&udev->mutex); input_unregister_device(dev); + mutex_lock(&udev->mutex); } else { input_free_device(dev); } kfree(name); kfree(phys); - udev->dev = NULL; } } @@ -745,7 +762,16 @@ static int uinput_release(struct inode *inode, struct file *file) { struct uinput_device *udev = file->private_data; + int retval; + + retval = mutex_lock_interruptible(&udev->mutex); + if (retval) + return retval; + uinput_destroy_device(udev); + + mutex_unlock(&udev->mutex); + kfree(udev); return 0;