Received: by 2002:a25:31c3:0:0:0:0:0 with SMTP id x186csp4474696ybx; Mon, 4 Nov 2019 14:02:59 -0800 (PST) X-Google-Smtp-Source: APXvYqwoXjoa04Y6ILqPXTKbM5s7NKfxLqovmBgEw1ntZUvmLmS98rUDh+IC55F4xoSxVfnxKkEo X-Received: by 2002:a17:906:fc6:: with SMTP id c6mr3829742ejk.153.1572904979816; Mon, 04 Nov 2019 14:02:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1572904979; cv=none; d=google.com; s=arc-20160816; b=nY2NWP6Uvw1tK3+mS+/60tPq1/JGRg0EpwWCKANWsO58+QhE9HD2hrjjJd41uev9l2 9v2k6OYxtxL2+5mKqrgxmo5EFJ0CqbLPjphYx8FW4c7KVvwdVC1+szZY+dPrBmBYXbC0 elWuhnPC4prd+6EDWmbbtsZ2U39hqQBQF3UkrUk2Ai/4tjJ2AdEfLtxLCJfeKIU4w2oZ 89KOzp2da3w+ySSyvkLD4Vxk5G6MkA1ePZKNfrAjJzzWgS9g/VZFjb8oP8bg9fif3Xhs 96SXC7Z4bWzkDWUTq36W2vZCrU/8/v5iuuT71OdnLh6LAF5ZDMYnjU2PsbPVQPIfF6zn MeYA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=fzbYekeDeCBIq8fWrO2L7IqcNaD8gjI3dyPB0R8cfSU=; b=juqXDSeMeSDbwr6wUJR5fQz9iZM3Aqv0Fp02+WMET1Re+xiaEOm1P84pGeLA1H8JrV LysRsWNxgvNebzx4Wjddcm89WrA0BryzWoid82DbQazNrvN+6pinMVj8PpSWMENrxCWS Xw7G1VC0itWUTowEFVVqw+GsDX1nu5aF4boQAv+b46sFywWjEiuWzuww583cKo2HeLnf uZ4DyRxsqRMdUkMbxInFuYc9ciaQbPo/wTKfndLyCty0Ccg8CdmtNnRCohsxhaoZ23ZO CPVlxyUaWG8l91Z2Xru0vu0dLmEb1+DSKnAblYarJXylylRc8xe52bGpi+s4E7iEQMED OcfA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=MJxlGlEm; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id uz29si12799721ejb.68.2019.11.04.14.02.36; Mon, 04 Nov 2019 14:02:59 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=MJxlGlEm; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388934AbfKDWBB (ORCPT + 99 others); Mon, 4 Nov 2019 17:01:01 -0500 Received: from mail.kernel.org ([198.145.29.99]:58332 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388890AbfKDWAi (ORCPT ); Mon, 4 Nov 2019 17:00:38 -0500 Received: from localhost (6.204-14-84.ripe.coltfrance.com [84.14.204.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D5E01222C6; Mon, 4 Nov 2019 22:00:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1572904837; bh=UVWN1IQsnHONNGn6shfGmJKv7yWKE5L+vnchf3/8s1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MJxlGlEmVjrDSFV8cysDcqMaGwRTyn8b+WX2P0LSG7fvH0bNDcAKggKfrgMw9fsMT fsmjiAs4JIpQLH7bmy1NcUXWwiZvVrPRSfliTDb3KdNUczzt/csb044Q287bLJNh0E xf+iT2Db17b+NJ1oyBwig03W463/SPZveYWAjzoU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Simon Gene Gottlieb , Rodrigo Rivas Costa , Jiri Kosina , Sasha Levin Subject: [PATCH 4.19 036/149] HID: steam: fix deadlock with input devices. Date: Mon, 4 Nov 2019 22:43:49 +0100 Message-Id: <20191104212138.296974518@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191104212126.090054740@linuxfoundation.org> References: <20191104212126.090054740@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rodrigo Rivas Costa [ Upstream commit 6b538cc21334b83f09b25dec4aa2d2726bf07ed0 ] When using this driver with the wireless dongle and some usermode program that monitors every input device (acpid, for example), while another usermode client opens and closes the low-level device repeadedly, the system eventually deadlocks. The reason is that steam_input_register_device() must not be called with the mutex held, because the input subsystem has its own synchronization that clashes with this one: it is possible that steam_input_open() is called before input_register_device() returns, and since steam_input_open() needs to lock the mutex, it deadlocks. However we must hold the mutex when calling any function that sends commands to the controller. If not, random commands end up falling fail. Reported-by: Simon Gene Gottlieb Signed-off-by: Rodrigo Rivas Costa Tested-by: Simon Gene Gottlieb Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-steam.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c index 8141cadfca0e3..8dae0f9b819e0 100644 --- a/drivers/hid/hid-steam.c +++ b/drivers/hid/hid-steam.c @@ -499,6 +499,7 @@ static void steam_battery_unregister(struct steam_device *steam) static int steam_register(struct steam_device *steam) { int ret; + bool client_opened; /* * This function can be called several times in a row with the @@ -511,9 +512,11 @@ static int steam_register(struct steam_device *steam) * Unlikely, but getting the serial could fail, and it is not so * important, so make up a serial number and go on. */ + mutex_lock(&steam->mutex); if (steam_get_serial(steam) < 0) strlcpy(steam->serial_no, "XXXXXXXXXX", sizeof(steam->serial_no)); + mutex_unlock(&steam->mutex); hid_info(steam->hdev, "Steam Controller '%s' connected", steam->serial_no); @@ -528,13 +531,15 @@ static int steam_register(struct steam_device *steam) } mutex_lock(&steam->mutex); - if (!steam->client_opened) { + client_opened = steam->client_opened; + if (!client_opened) steam_set_lizard_mode(steam, lizard_mode); + mutex_unlock(&steam->mutex); + + if (!client_opened) ret = steam_input_register(steam); - } else { + else ret = 0; - } - mutex_unlock(&steam->mutex); return ret; } @@ -630,14 +635,21 @@ static void steam_client_ll_close(struct hid_device *hdev) { struct steam_device *steam = hdev->driver_data; + unsigned long flags; + bool connected; + + spin_lock_irqsave(&steam->lock, flags); + connected = steam->connected; + spin_unlock_irqrestore(&steam->lock, flags); + mutex_lock(&steam->mutex); steam->client_opened = false; + if (connected) + steam_set_lizard_mode(steam, lizard_mode); mutex_unlock(&steam->mutex); - if (steam->connected) { - steam_set_lizard_mode(steam, lizard_mode); + if (connected) steam_input_register(steam); - } } static int steam_client_ll_raw_request(struct hid_device *hdev, -- 2.20.1