public inbox for linux-pm@vger.kernel.org
 help / color / mirror / Atom feed
* [bug report] thermal: Add cooling device's statistics in sysfs
@ 2022-10-14 14:08 Dan Carpenter
  2022-10-14 14:30 ` Dan Carpenter
  2022-10-17  5:57 ` Viresh Kumar
  0 siblings, 2 replies; 8+ messages in thread
From: Dan Carpenter @ 2022-10-14 14:08 UTC (permalink / raw)
  To: viresh.kumar; +Cc: linux-pm

Hello Viresh Kumar,

The patch 8ea229511e06: "thermal: Add cooling device's statistics in
sysfs" from Apr 2, 2018, leads to the following Smatch static checker
warning:

	drivers/thermal/thermal_sysfs.c:656 thermal_cooling_device_stats_update()
	warn: potential integer overflow from user 'stats->state * stats->max_states + new_state'

drivers/thermal/thermal_sysfs.c
    642 void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
    643                                          unsigned long new_state)
    644 {
    645         struct cooling_dev_stats *stats = cdev->stats;
    646 
    647         if (!stats)
    648                 return;
    649 
    650         spin_lock(&stats->lock);
    651 
    652         if (stats->state == new_state)
    653                 goto unlock;
    654 
    655         update_time_in_state(stats);
--> 656         stats->trans_table[stats->state * stats->max_states + new_state]++;
                                                                      ^^^^^^^^^
The new state value comes from the user via sysfs.  It is <= LONG_MAX
but otherwise there is no limit on its value.  Presumably only the
admin can write to this file so the security impact of this buffer
overflow is not as bad as it could have been.

    657         stats->state = new_state;
    658         stats->total_trans++;
    659 
    660 unlock:
    661         spin_unlock(&stats->lock);
    662 }

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [bug report] thermal: Add cooling device's statistics in sysfs
  2022-10-14 14:08 [bug report] thermal: Add cooling device's statistics in sysfs Dan Carpenter
@ 2022-10-14 14:30 ` Dan Carpenter
  2022-10-17  9:38   ` Viresh Kumar
  2022-10-17  5:57 ` Viresh Kumar
  1 sibling, 1 reply; 8+ messages in thread
From: Dan Carpenter @ 2022-10-14 14:30 UTC (permalink / raw)
  To: viresh.kumar; +Cc: linux-pm

On Fri, Oct 14, 2022 at 05:08:04PM +0300, Dan Carpenter wrote:
> Hello Viresh Kumar,
> 
> The patch 8ea229511e06: "thermal: Add cooling device's statistics in
> sysfs" from Apr 2, 2018, leads to the following Smatch static checker
> warning:
> 
> 	drivers/thermal/thermal_sysfs.c:656 thermal_cooling_device_stats_update()
> 	warn: potential integer overflow from user 'stats->state * stats->max_states + new_state'
> 
> drivers/thermal/thermal_sysfs.c
>     642 void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
>     643                                          unsigned long new_state)
>     644 {
>     645         struct cooling_dev_stats *stats = cdev->stats;
>     646 
>     647         if (!stats)
>     648                 return;
>     649 
>     650         spin_lock(&stats->lock);
>     651 
>     652         if (stats->state == new_state)
>     653                 goto unlock;
>     654 
>     655         update_time_in_state(stats);
> --> 656         stats->trans_table[stats->state * stats->max_states + new_state]++;
>                                                                       ^^^^^^^^^
> The new state value comes from the user via sysfs.  It is <= LONG_MAX
> but otherwise there is no limit on its value.  Presumably only the
> admin can write to this file so the security impact of this buffer
> overflow is not as bad as it could have been.
> 

(There are some drivers which might cap new_state.  I only looked at
tc654_set_cur_state() and it doesn't cap the value.  It's always going
to be safer to do the bounds checking in a central place).

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [bug report] thermal: Add cooling device's statistics in sysfs
  2022-10-14 14:08 [bug report] thermal: Add cooling device's statistics in sysfs Dan Carpenter
  2022-10-14 14:30 ` Dan Carpenter
@ 2022-10-17  5:57 ` Viresh Kumar
  2022-10-17  7:09   ` Dan Carpenter
  1 sibling, 1 reply; 8+ messages in thread
From: Viresh Kumar @ 2022-10-17  5:57 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: linux-pm

On 14-10-22, 17:08, Dan Carpenter wrote:
> Hello Viresh Kumar,
> 
> The patch 8ea229511e06: "thermal: Add cooling device's statistics in
> sysfs" from Apr 2, 2018, leads to the following Smatch static checker
> warning:
> 
> 	drivers/thermal/thermal_sysfs.c:656 thermal_cooling_device_stats_update()
> 	warn: potential integer overflow from user 'stats->state * stats->max_states + new_state'
> 
> drivers/thermal/thermal_sysfs.c
>     642 void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
>     643                                          unsigned long new_state)
>     644 {
>     645         struct cooling_dev_stats *stats = cdev->stats;
>     646 
>     647         if (!stats)
>     648                 return;
>     649 
>     650         spin_lock(&stats->lock);
>     651 
>     652         if (stats->state == new_state)
>     653                 goto unlock;
>     654 
>     655         update_time_in_state(stats);
> --> 656         stats->trans_table[stats->state * stats->max_states + new_state]++;
>                                                                       ^^^^^^^^^
> The new state value comes from the user via sysfs.  It is <= LONG_MAX
> but otherwise there is no limit on its value.

This routine gets called after cdev->ops->set_cur_state() has returned
successfully. That callback does the verification of this value, based
on what's the maximum value allowed and hence the size of the array
here.

I don't think we will have any issue here unless the cooling driver is
buggy and isn't checking the state properly.

> Presumably only the
> admin can write to this file so the security impact of this buffer
> overflow is not as bad as it could have been.

-- 
viresh

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [bug report] thermal: Add cooling device's statistics in sysfs
  2022-10-17  5:57 ` Viresh Kumar
@ 2022-10-17  7:09   ` Dan Carpenter
  2022-10-17  7:10     ` Viresh Kumar
  0 siblings, 1 reply; 8+ messages in thread
From: Dan Carpenter @ 2022-10-17  7:09 UTC (permalink / raw)
  To: Viresh Kumar; +Cc: linux-pm

On Mon, Oct 17, 2022 at 11:27:35AM +0530, Viresh Kumar wrote:
> On 14-10-22, 17:08, Dan Carpenter wrote:
> > Hello Viresh Kumar,
> > 
> > The patch 8ea229511e06: "thermal: Add cooling device's statistics in
> > sysfs" from Apr 2, 2018, leads to the following Smatch static checker
> > warning:
> > 
> > 	drivers/thermal/thermal_sysfs.c:656 thermal_cooling_device_stats_update()
> > 	warn: potential integer overflow from user 'stats->state * stats->max_states + new_state'
> > 
> > drivers/thermal/thermal_sysfs.c
> >     642 void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
> >     643                                          unsigned long new_state)
> >     644 {
> >     645         struct cooling_dev_stats *stats = cdev->stats;
> >     646 
> >     647         if (!stats)
> >     648                 return;
> >     649 
> >     650         spin_lock(&stats->lock);
> >     651 
> >     652         if (stats->state == new_state)
> >     653                 goto unlock;
> >     654 
> >     655         update_time_in_state(stats);
> > --> 656         stats->trans_table[stats->state * stats->max_states + new_state]++;
> >                                                                       ^^^^^^^^^
> > The new state value comes from the user via sysfs.  It is <= LONG_MAX
> > but otherwise there is no limit on its value.
> 
> This routine gets called after cdev->ops->set_cur_state() has returned
> successfully. That callback does the verification of this value, based
> on what's the maximum value allowed and hence the size of the array
> here.
> 
> I don't think we will have any issue here unless the cooling driver is
> buggy and isn't checking the state properly.
> 

I only looked at the 1 example I posted, but so far as I can see from a
sample size of 1 they are all buggy.  100% buggy.

This strategy of relying on the drivers to do it correctly was doomed
from the get go.

regards,
dan carpenter



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [bug report] thermal: Add cooling device's statistics in sysfs
  2022-10-17  7:09   ` Dan Carpenter
@ 2022-10-17  7:10     ` Viresh Kumar
  0 siblings, 0 replies; 8+ messages in thread
From: Viresh Kumar @ 2022-10-17  7:10 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: linux-pm

On 17-10-22, 10:09, Dan Carpenter wrote:
> I only looked at the 1 example I posted, but so far as I can see from a
> sample size of 1 they are all buggy.  100% buggy.
> 
> This strategy of relying on the drivers to do it correctly was doomed
> from the get go.

Yeah, I realized that too after sending you the email. I am working on
a patch to fix it.

-- 
viresh

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [bug report] thermal: Add cooling device's statistics in sysfs
  2022-10-14 14:30 ` Dan Carpenter
@ 2022-10-17  9:38   ` Viresh Kumar
  2022-10-17 13:19     ` Dan Carpenter
  0 siblings, 1 reply; 8+ messages in thread
From: Viresh Kumar @ 2022-10-17  9:38 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: linux-pm

On 14-10-22, 17:30, Dan Carpenter wrote:
> (There are some drivers which might cap new_state.  I only looked at
> tc654_set_cur_state() and it doesn't cap the value.  It's always going
> to be safer to do the bounds checking in a central place).

I agree that it is better to do it at central place.

But, tc654_set_cur_state() seems to be doing it just fine:

static int tc654_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
	struct tc654_data *data = tc654_update_client(cdev->devdata);

	if (IS_ERR(data))
		return PTR_ERR(data);

	return _set_pwm(data, clamp_val(state, 0, TC654_MAX_COOLING_STATE));
}

-- 
viresh

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [bug report] thermal: Add cooling device's statistics in sysfs
  2022-10-17  9:38   ` Viresh Kumar
@ 2022-10-17 13:19     ` Dan Carpenter
  2022-10-18  4:02       ` Viresh Kumar
  0 siblings, 1 reply; 8+ messages in thread
From: Dan Carpenter @ 2022-10-17 13:19 UTC (permalink / raw)
  To: Viresh Kumar; +Cc: linux-pm

On Mon, Oct 17, 2022 at 03:08:29PM +0530, Viresh Kumar wrote:
> On 14-10-22, 17:30, Dan Carpenter wrote:
> > (There are some drivers which might cap new_state.  I only looked at
> > tc654_set_cur_state() and it doesn't cap the value.  It's always going
> > to be safer to do the bounds checking in a central place).
> 
> I agree that it is better to do it at central place.
> 
> But, tc654_set_cur_state() seems to be doing it just fine:
> 
> static int tc654_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
> {
> 	struct tc654_data *data = tc654_update_client(cdev->devdata);
> 
> 	if (IS_ERR(data))
> 		return PTR_ERR(data);
> 
> 	return _set_pwm(data, clamp_val(state, 0, TC654_MAX_COOLING_STATE));

Ideally it would return -EINVAL for invalid state values instead of
clamping it to a valid range.

I feel like -EINVAL is generally a better API.  But also if we're
relying it to check and return an error code then obviously that's not
what it does.

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [bug report] thermal: Add cooling device's statistics in sysfs
  2022-10-17 13:19     ` Dan Carpenter
@ 2022-10-18  4:02       ` Viresh Kumar
  0 siblings, 0 replies; 8+ messages in thread
From: Viresh Kumar @ 2022-10-18  4:02 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: linux-pm

On 17-10-22, 16:19, Dan Carpenter wrote:
> On Mon, Oct 17, 2022 at 03:08:29PM +0530, Viresh Kumar wrote:
> > On 14-10-22, 17:30, Dan Carpenter wrote:
> > > (There are some drivers which might cap new_state.  I only looked at
> > > tc654_set_cur_state() and it doesn't cap the value.  It's always going
> > > to be safer to do the bounds checking in a central place).
> > 
> > I agree that it is better to do it at central place.
> > 
> > But, tc654_set_cur_state() seems to be doing it just fine:
> > 
> > static int tc654_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
> > {
> > 	struct tc654_data *data = tc654_update_client(cdev->devdata);
> > 
> > 	if (IS_ERR(data))
> > 		return PTR_ERR(data);
> > 
> > 	return _set_pwm(data, clamp_val(state, 0, TC654_MAX_COOLING_STATE));
> 
> Ideally it would return -EINVAL for invalid state values instead of
> clamping it to a valid range.
> 
> I feel like -EINVAL is generally a better API.  But also if we're
> relying it to check and return an error code then obviously that's not
> what it does.

Right. Hope the patches I sent fixes this, can you have a look at them
too ?

-- 
viresh

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-10-18  4:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-14 14:08 [bug report] thermal: Add cooling device's statistics in sysfs Dan Carpenter
2022-10-14 14:30 ` Dan Carpenter
2022-10-17  9:38   ` Viresh Kumar
2022-10-17 13:19     ` Dan Carpenter
2022-10-18  4:02       ` Viresh Kumar
2022-10-17  5:57 ` Viresh Kumar
2022-10-17  7:09   ` Dan Carpenter
2022-10-17  7:10     ` Viresh Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox