public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: David Laight <david.laight.linux@gmail.com>
To: Gui-Dong Han <hanguidong02@gmail.com>
Cc: linux@roeck-us.net, linux-hwmon@vger.kernel.org,
	linux-kernel@vger.kernel.org, baijiaju1990@gmail.com,
	Ben Hutchings <ben@decadent.org.uk>,
	stable@vger.kernel.org
Subject: Re: [PATCH] hwmon: (max16065) Use READ/WRITE_ONCE to avoid compiler optimization induced race
Date: Sat, 7 Feb 2026 10:43:08 +0000	[thread overview]
Message-ID: <20260207104308.1bc31102@pumpkin> (raw)
In-Reply-To: <20260203121443.5482-1-hanguidong02@gmail.com>

On Tue,  3 Feb 2026 20:14:43 +0800
Gui-Dong Han <hanguidong02@gmail.com> wrote:

> Simply copying shared data to a local variable cannot prevent data
> races. The compiler is allowed to optimize away the local copy and
> re-read the shared memory, causing a Time-of-Check Time-of-Use (TOCTOU)
> issue if the data changes between the check and the usage.

While the compiler is allowed to do this, is there any indication
that either gcc or clang have ever done it?
ISTR someone saying that they never did - although I thought that
was the original justification for adding ACCESS_ONCE().

READ_ONCE() also includes barriers to guarantee ordering between cpu.
These are empty on x86 but add code to architectures where the cpu
can (IIRC) re-order writes.
This is worst on alpha but affects arm and probably ppc.

For these cases is it enough to add the compile-time barrier() after
reading the variable to a local.
That will also generate better code on x86.

The WRITE_ONCE() aren't needed at all, the compilers definitely
guarantee to do a single memory access for aligned accesses that are
less than the size of a word.

This all stinks of being an AI generated patch.

	David

> 
> To enforce the use of the local variable, use READ_ONCE() when reading
> the shared data and WRITE_ONCE() when updating it. Apply these macros to
> the three identified locations (curr_sense, adc, and fault) where local
> variables are used for error validation, ensuring the value remains
> consistent.
> 
> Reported-by: Ben Hutchings <ben@decadent.org.uk>
> Closes: https://lore.kernel.org/all/6fe17868327207e8b850cf9f88b7dc58b2021f73.camel@decadent.org.uk/
> Fixes: f5bae2642e3d ("hwmon: Driver for MAX16065 System Manager and compatibles")
> Fixes: b8d5acdcf525 ("hwmon: (max16065) Use local variable to avoid TOCTOU")
> Cc: stable@vger.kernel.org
> Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
> ---
>  drivers/hwmon/max16065.c | 26 +++++++++++++-------------
>  1 file changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
> index 4c9e7892a73c..43fbb9b26b10 100644
> --- a/drivers/hwmon/max16065.c
> +++ b/drivers/hwmon/max16065.c
> @@ -151,27 +151,27 @@ static struct max16065_data *max16065_update_device(struct device *dev)
>  		int i;
>  
>  		for (i = 0; i < data->num_adc; i++)
> -			data->adc[i]
> -			  = max16065_read_adc(client, MAX16065_ADC(i));
> +			WRITE_ONCE(data->adc[i],
> +				   max16065_read_adc(client, MAX16065_ADC(i)));
>  
>  		if (data->have_current) {
> -			data->adc[MAX16065_NUM_ADC]
> -			  = max16065_read_adc(client, MAX16065_CSP_ADC);
> -			data->curr_sense
> -			  = i2c_smbus_read_byte_data(client,
> -						     MAX16065_CURR_SENSE);
> +			WRITE_ONCE(data->adc[MAX16065_NUM_ADC],
> +				   max16065_read_adc(client, MAX16065_CSP_ADC));
> +			WRITE_ONCE(data->curr_sense,
> +				   i2c_smbus_read_byte_data(client, MAX16065_CURR_SENSE));
>  		}
>  
>  		for (i = 0; i < 2; i++)
> -			data->fault[i]
> -			  = i2c_smbus_read_byte_data(client, MAX16065_FAULT(i));
> +			WRITE_ONCE(data->fault[i],
> +				   i2c_smbus_read_byte_data(client, MAX16065_FAULT(i)));
>  
>  		/*
>  		 * MAX16067 and MAX16068 have separate undervoltage and
>  		 * overvoltage alarm bits. Squash them together.
>  		 */
>  		if (data->chip == max16067 || data->chip == max16068)
> -			data->fault[0] |= data->fault[1];
> +			WRITE_ONCE(data->fault[0],
> +				   data->fault[0] | data->fault[1]);
>  
>  		data->last_updated = jiffies;
>  		data->valid = true;
> @@ -185,7 +185,7 @@ static ssize_t max16065_alarm_show(struct device *dev,
>  {
>  	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da);
>  	struct max16065_data *data = max16065_update_device(dev);
> -	int val = data->fault[attr2->nr];
> +	int val = READ_ONCE(data->fault[attr2->nr]);
>  
>  	if (val < 0)
>  		return val;
> @@ -203,7 +203,7 @@ static ssize_t max16065_input_show(struct device *dev,
>  {
>  	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
>  	struct max16065_data *data = max16065_update_device(dev);
> -	int adc = data->adc[attr->index];
> +	int adc = READ_ONCE(data->adc[attr->index]);
>  
>  	if (unlikely(adc < 0))
>  		return adc;
> @@ -216,7 +216,7 @@ static ssize_t max16065_current_show(struct device *dev,
>  				     struct device_attribute *da, char *buf)
>  {
>  	struct max16065_data *data = max16065_update_device(dev);
> -	int curr_sense = data->curr_sense;
> +	int curr_sense = READ_ONCE(data->curr_sense);
>  
>  	if (unlikely(curr_sense < 0))
>  		return curr_sense;


  parent reply	other threads:[~2026-02-07 10:43 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-03 12:14 [PATCH] hwmon: (max16065) Use READ/WRITE_ONCE to avoid compiler optimization induced race Gui-Dong Han
2026-02-07  5:31 ` Guenter Roeck
2026-02-07 10:43 ` David Laight [this message]
2026-02-07 11:43   ` Ben Hutchings
2026-02-08 11:48     ` David Laight
2026-02-08 22:33       ` Ben Hutchings
2026-02-09  9:50         ` David Laight
2026-02-07 11:50   ` Gui-Dong Han

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=20260207104308.1bc31102@pumpkin \
    --to=david.laight.linux@gmail.com \
    --cc=baijiaju1990@gmail.com \
    --cc=ben@decadent.org.uk \
    --cc=hanguidong02@gmail.com \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=stable@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox