Re: [PATCH] platform/x86: wmi: fix potential null pointer dereferences

From: Mattias Jacobsson
Date: Mon Jan 28 2019 - 09:39:26 EST


Hi,

On 2019-01-27, Andy Shevchenko wrote:
> On Tue, Jan 22, 2019 at 10:04 PM Mattias Jacobsson <2pi@xxxxxx> wrote:
> >
> > In the function wmi_dev_match() there are three variables that
> > potentially can result in a null pointer dereference. Namely:
> > dev/wblock, driver/wmi_driver, and wmi_driver->id_table.
> >
> > Check for NULL and return that the driver can't handle the device if any
> > of these variables would result in a null pointer dereference.
> >
> > The NULL checks are performed prior to running container_of() for the
> > variables dev/wblock and driver/wmi_driver.
> >
> > Fixes: 844af950da94 ("platform/x86: wmi: Turn WMI into a bus driver")
> > Signed-off-by: Mattias Jacobsson <2pi@xxxxxx>
> > ---
> > drivers/platform/x86/wmi.c | 16 ++++++++++++----
> > 1 file changed, 12 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
> > index bea35be68706..c596479e8b13 100644
> > --- a/drivers/platform/x86/wmi.c
> > +++ b/drivers/platform/x86/wmi.c
> > @@ -763,10 +763,18 @@ static void wmi_dev_release(struct device *dev)
> >
> > static int wmi_dev_match(struct device *dev, struct device_driver *driver)
> > {
> > - struct wmi_driver *wmi_driver =
> > - container_of(driver, struct wmi_driver, driver);
>
> AFAIU this is just a pointer arithmetics, no need to move it.

That is my understanding too, it seamed backwards to do the NULL check
afterwards, but we still have access to dev and driver. So why not...

>
> > - struct wmi_block *wblock = dev_to_wblock(dev);
>
> > - const struct wmi_device_id *id = wmi_driver->id_table;
> > + const struct wmi_device_id *id;
> > + struct wmi_block *wblock;
> > + struct wmi_driver *wmi_driver;
> > +
>
> > + if (dev == NULL || driver == NULL)
> > + return 0;
>
> On which circumstances this may ever happen?

Nothing in particular. If there is a bug in the caller of this function,
then that is when this will come into play. See my earlier mail to
Darren too.

>
> > + wblock = dev_to_wblock(dev);
> > + wmi_driver = container_of(driver, struct wmi_driver, driver);
> > +
> > + if (wmi_driver->id_table == NULL)
> > + return 0;
> > + id = wmi_driver->id_table;
> >
> > while (id->guid_string) {
> > uuid_le driver_guid;
> > --
> > 2.20.1
> >
>
>
> --
> With Best Regards,
> Andy Shevchenko

Thanks,
Mattias