All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marius Zachmann <mail@mariuszachmann.de>
To: linux-hwmon@vger.kernel.org, Aleksa Savic <savicaleksa83@gmail.com>
Cc: Jonas Malaco <jonas@protocubo.io>,
	Aleksa Savic <savicaleksa83@gmail.com>,
	Jean Delvare <jdelvare@suse.com>,
	Guenter Roeck <linux@roeck-us.net>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/3] hwmon: (corsair-cpro) Protect ccp->wait_input_report with a spinlock
Date: Sat, 04 May 2024 14:14:48 +0200	[thread overview]
Message-ID: <2182068.irdbgypaU6@marius> (raw)
In-Reply-To: <20240504092504.24158-4-savicaleksa83@gmail.com>

On 04.05.24 at 11:25:03 MESZ, Aleksa Savic wrote
> Through hidraw, userspace can cause a status report to be sent
> from the device. The parsing in ccp_raw_event() may happen in
> parallel to a send_usb_cmd() call (which resets the completion
> for tracking the report) if it's running on a different CPU where
> bottom half interrupts are not disabled.
> 
> Add a spinlock around the complete_all() in ccp_raw_event() and
> reinit_completion() in send_usb_cmd() to prevent race issues.
> 
> Fixes: 40c3a4454225 ("hwmon: add Corsair Commander Pro driver")
> Signed-off-by: Aleksa Savic <savicaleksa83@gmail.com>
> ---
>  drivers/hwmon/corsair-cpro.c | 24 +++++++++++++++++++-----
>  1 file changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/hwmon/corsair-cpro.c b/drivers/hwmon/corsair-cpro.c
> index 6ab4d2478b1f..3e63666a61bd 100644
> --- a/drivers/hwmon/corsair-cpro.c
> +++ b/drivers/hwmon/corsair-cpro.c
> @@ -16,6 +16,7 @@
>  #include <linux/module.h>
>  #include <linux/mutex.h>
>  #include <linux/slab.h>
> +#include <linux/spinlock.h>
>  #include <linux/types.h>
>  
>  #define USB_VENDOR_ID_CORSAIR			0x1b1c
> @@ -77,6 +78,8 @@
>  struct ccp_device {
>  	struct hid_device *hdev;
>  	struct device *hwmon_dev;
> +	/* For reinitializing the completion below */
> +	spinlock_t wait_input_report_lock;
>  	struct completion wait_input_report;
>  	struct mutex mutex; /* whenever buffer is used, lock before send_usb_cmd */
>  	u8 *cmd_buffer;
> @@ -118,7 +121,15 @@ static int send_usb_cmd(struct ccp_device *ccp, u8 command, u8 byte1, u8 byte2,
>  	ccp->cmd_buffer[2] = byte2;
>  	ccp->cmd_buffer[3] = byte3;
>  
> +	/*
> +	 * Disable raw event parsing for a moment to safely reinitialize the
> +	 * completion. Reinit is done because hidraw could have triggered
> +	 * the raw event parsing and marked the ccp->wait_input_report
> +	 * completion as done.
> +	 */
> +	spin_lock_bh(&ccp->wait_input_report_lock);
>  	reinit_completion(&ccp->wait_input_report);
> +	spin_unlock_bh(&ccp->wait_input_report_lock);
>  
>  	ret = hid_hw_output_report(ccp->hdev, ccp->cmd_buffer, OUT_BUFFER_SIZE);
>  	if (ret < 0)
> @@ -136,11 +147,12 @@ static int ccp_raw_event(struct hid_device *hdev, struct hid_report *report, u8
>  	struct ccp_device *ccp = hid_get_drvdata(hdev);
>  
>  	/* only copy buffer when requested */
> -	if (completion_done(&ccp->wait_input_report))
> -		return 0;
> -
> -	memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
> -	complete_all(&ccp->wait_input_report);
> +	spin_lock(&ccp->wait_input_report_lock);
> +	if (!completion_done(&ccp->wait_input_report)) {
> +		memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
> +		complete_all(&ccp->wait_input_report);
> +	}
> +	spin_unlock(&ccp->wait_input_report_lock);
>  
>  	return 0;
>  }
> @@ -515,7 +527,9 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
>  
>  	ccp->hdev = hdev;
>  	hid_set_drvdata(hdev, ccp);
> +
>  	mutex_init(&ccp->mutex);
> +	spin_lock_init(&ccp->wait_input_report_lock);
>  	init_completion(&ccp->wait_input_report);
>  
>  	hid_device_io_start(hdev);
> 

Acked-by: Marius Zachmann <mail@mariuszachmann.de>





  reply	other threads:[~2024-05-04 12:14 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-04  9:25 [PATCH 0/3] hwmon: (corsair-cpro) Fix issues when hidraw is used Aleksa Savic
2024-05-04  9:25 ` [PATCH 1/3] hwmon: (corsair-cpro) Use a separate buffer for sending commands Aleksa Savic
2024-05-04 12:14   ` Marius Zachmann
2024-05-04  9:25 ` [PATCH 2/3] hwmon: (corsair-cpro) Use complete_all() instead of complete() in ccp_raw_event() Aleksa Savic
2024-05-04 12:14   ` Marius Zachmann
2024-05-04  9:25 ` [PATCH 3/3] hwmon: (corsair-cpro) Protect ccp->wait_input_report with a spinlock Aleksa Savic
2024-05-04 12:14   ` Marius Zachmann [this message]
2024-05-04 13:37 ` [PATCH 0/3] hwmon: (corsair-cpro) Fix issues when hidraw is used Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2182068.irdbgypaU6@marius \
    --to=mail@mariuszachmann.de \
    --cc=jdelvare@suse.com \
    --cc=jonas@protocubo.io \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=savicaleksa83@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.