public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: Varad Gautam <varadgautam@google.com>
Cc: Zhang Rui <rui.zhang@intel.com>,
	linux-kernel@vger.kernel.org,
	"Rafael J . Wysocki" <rafael@kernel.org>,
	Daniel Lezcano <daniel.lezcano@linaro.org>,
	Amit Kucheria <amitk@kernel.org>,
	linux-pm@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH] thermal: sysfs: Perform bounds check when storing thermal states
Date: Wed, 6 Jul 2022 12:21:26 +0200	[thread overview]
Message-ID: <YsViJpAnkqW1QTwW@kroah.com> (raw)
In-Reply-To: <CAOLDJOJLvSUMqF37H13aiH59Pm4_t6esRxy7Ej3Grhr4fmSGQA@mail.gmail.com>

On Wed, Jul 06, 2022 at 12:01:19PM +0200, Varad Gautam wrote:
> On Wed, Jul 6, 2022 at 11:21 AM Greg KH <gregkh@linuxfoundation.org> wrote:
> >
> > On Wed, Jul 06, 2022 at 04:51:59PM +0800, Zhang Rui wrote:
> > > On Wed, 2022-07-06 at 09:16 +0200, Varad Gautam wrote:
> > > > On Wed, Jul 6, 2022 at 8:45 AM Greg KH <gregkh@linuxfoundation.org>
> > > > wrote:
> > > > >
> > > > > On Tue, Jul 05, 2022 at 11:02:50PM +0200, Varad Gautam wrote:
> > > > > > On Tue, Jul 5, 2022 at 6:18 PM Greg KH <
> > > > > > gregkh@linuxfoundation.org> wrote:
> > > > > > >
> > > > > > > On Tue, Jul 05, 2022 at 03:00:02PM +0000, Varad Gautam wrote:
> > > > > > > > Check that a user-provided thermal state is within the
> > > > > > > > maximum
> > > > > > > > thermal states supported by a given driver before attempting
> > > > > > > > to
> > > > > > > > apply it. This prevents a subsequent OOB access in
> > > > > > > > thermal_cooling_device_stats_update() while performing
> > > > > > > > state-transition accounting on drivers that do not have this
> > > > > > > > check
> > > > > > > > in their set_cur_state() handle.
> > > > > > > >
> > > > > > > > Signed-off-by: Varad Gautam <varadgautam@google.com>
> > > > > > > > Cc: stable@vger.kernel.org
> > > > > > > > ---
> > > > > > > >  drivers/thermal/thermal_sysfs.c | 12 +++++++++++-
> > > > > > > >  1 file changed, 11 insertions(+), 1 deletion(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/thermal/thermal_sysfs.c
> > > > > > > > b/drivers/thermal/thermal_sysfs.c
> > > > > > > > index 1c4aac8464a7..0c6b0223b133 100644
> > > > > > > > --- a/drivers/thermal/thermal_sysfs.c
> > > > > > > > +++ b/drivers/thermal/thermal_sysfs.c
> > > > > > > > @@ -607,7 +607,7 @@ cur_state_store(struct device *dev,
> > > > > > > > struct device_attribute *attr,
> > > > > > > >               const char *buf, size_t count)
> > > > > > > >  {
> > > > > > > >       struct thermal_cooling_device *cdev =
> > > > > > > > to_cooling_device(dev);
> > > > > > > > -     unsigned long state;
> > > > > > > > +     unsigned long state, max_state;
> > > > > > > >       int result;
> > > > > > > >
> > > > > > > >       if (sscanf(buf, "%ld\n", &state) != 1)
> > > > > > > > @@ -618,10 +618,20 @@ cur_state_store(struct device *dev,
> > > > > > > > struct device_attribute *attr,
> > > > > > > >
> > > > > > > >       mutex_lock(&cdev->lock);
> > > > > > > >
> > > > > > > > +     result = cdev->ops->get_max_state(cdev, &max_state);
> > > > > > > > +     if (result)
> > > > > > > > +             goto unlock;
> > > > > > > > +
> > > > > > > > +     if (state > max_state) {
> > > > > > > > +             result = -EINVAL;
> > > > > > > > +             goto unlock;
> > > > > > > > +     }
> > > > > > > > +
> > > > > > > >       result = cdev->ops->set_cur_state(cdev, state);
> > > > > > >
> > > > > > > Why doesn't set_cur_state() check the max state before setting
> > > > > > > it?  Why
> > > > > > > are the callers forced to always check it before?  That feels
> > > > > > > wrong...
> > > > > > >
> > > > > >
> > > > > > The problem lies in thermal_cooling_device_stats_update(), not
> > > > > > set_cur_state().
> > > > > >
> > > > > > If ->set_cur_state() doesn't error out on invalid state,
> > > > > > thermal_cooling_device_stats_update() does a:
> > > > > >
> > > > > > stats->trans_table[stats->state * stats->max_states +
> > > > > > new_state]++;
> > > > > >
> > > > > > stats->trans_table reserves space depending on max_states, but
> > > > > > we'd end up
> > > > > > reading/writing outside it. cur_state_store() can prevent this
> > > > > > regardless of
> > > > > > the driver's ->set_cur_state() implementation.
> > > > >
> > > > > Why wouldn't cur_state_store() check for an out-of-bounds condition
> > > > > by
> > > > > calling get_max_state() and then return an error if it is invalid,
> > > > > preventing thermal_cooling_device_stats_update() from ever being
> > > > > called?
> > > > >
> > > >
> > > > That's what this patch does, it adds the out-of-bounds check.
> > >
> > > No, I think Greg' question is
> > > why cdev->ops->set_cur_state() return 0 when setting a cooling state
> > > that exceeds the maximum cooling state?
> >
> > Yes, that is what I am asking, it should not allow a state to be
> > exceeded.
> >
> 
> Indeed, it is upto the driver to return !0 from cdev->ops->set_cur_state()
> when setting state > max - and it is a driver bug for not doing so.
> 
> But a buggy driver should not lead to cur_state_store() performing an OOB
> access.

Agreed, which is why the code that does the access should check before
it does so.  Right now you are relying on the sysfs code to do so, which
seems very wrong.

thanks,

greg k-h

  reply	other threads:[~2022-07-06 10:22 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-05 15:00 [PATCH] thermal: sysfs: Perform bounds check when storing thermal states Varad Gautam
2022-07-05 16:18 ` Greg KH
2022-07-05 21:02   ` Varad Gautam
2022-07-06  6:45     ` Greg KH
2022-07-06  7:16       ` Varad Gautam
2022-07-06  8:51         ` Zhang Rui
2022-07-06  9:21           ` Greg KH
2022-07-06 10:01             ` Varad Gautam
2022-07-06 10:21               ` Greg KH [this message]
2022-07-06 12:30                 ` Varad Gautam
2022-07-06 12:51                   ` Greg KH

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=YsViJpAnkqW1QTwW@kroah.com \
    --to=gregkh@linuxfoundation.org \
    --cc=amitk@kernel.org \
    --cc=daniel.lezcano@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rafael@kernel.org \
    --cc=rui.zhang@intel.com \
    --cc=stable@vger.kernel.org \
    --cc=varadgautam@google.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox