lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 15 Apr 2021 10:56:12 +0200
From:   Ulf Hansson <ulf.hansson@...aro.org>
To:     Stephen Boyd <swboyd@...omium.org>
Cc:     Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
        linux-mmc <linux-mmc@...r.kernel.org>,
        Matthias Schiffer <matthias.schiffer@...tq-group.com>,
        Sujit Kautkar <sujitka@...omium.org>,
        Zubin Mithra <zsm@...omium.org>
Subject: Re: [PATCH] mmc: core: Don't allocate IDA for OF aliases

On Tue, 13 Apr 2021 at 02:36, Stephen Boyd <swboyd@...omium.org> wrote:
>
> There's a chance that the IDA allocated in mmc_alloc_host() is not freed
> for some time because it's freed as part of a class' release function
> (see mmc_host_classdev_release() where the IDA is freed). If another
> thread is holding a reference to the class, then only once all balancing
> device_put() calls (in turn calling kobject_put()) have been made will
> the IDA be released and usable again.
>
> Normally this isn't a problem because the kobject is released before
> anything else that may want to use the same number tries to again, but
> with CONFIG_DEBUG_KOBJECT_RELEASE=y and OF aliases it becomes pretty
> easy to try to allocate an alias from the IDA twice while the first time
> it was allocated is still pending a call to ida_simple_remove(). It's
> also possible to trigger it by using CONFIG_DEBUG_KOBJECT_RELEASE and
> probe defering a driver at boot that calls mmc_alloc_host() before
> trying to get resources that may defer likes clks or regulators.

Thanks for a very nice description of the problem.

>
> Instead of allocating from the IDA in this scenario, let's just skip it
> if we know this is an OF alias. The number is already "claimed" and
> devices that aren't using OF aliases won't try to use the claimed
> numbers anyway (see mmc_first_nonreserved_index()). This should avoid
> any issues with mmc_alloc_host() returning failures from the
> ida_simple_get() in the case that we're using an OF alias.

At first glance, this seems like a good idea, but I am not completely
sure, yet. See more below.

>
> Cc: Matthias Schiffer <matthias.schiffer@...tq-group.com>
> Cc: Sujit Kautkar <sujitka@...omium.org>
> Reported-by: Zubin Mithra <zsm@...omium.org>
> Fixes: fa2d0aa96941 ("mmc: core: Allow setting slot index via device tree alias")
> Signed-off-by: Stephen Boyd <swboyd@...omium.org>
> ---
>  drivers/mmc/core/host.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index 9b89a91b6b47..137b4a769f62 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -39,7 +39,8 @@ static void mmc_host_classdev_release(struct device *dev)
>  {
>         struct mmc_host *host = cls_dev_to_mmc_host(dev);
>         wakeup_source_unregister(host->ws);
> -       ida_simple_remove(&mmc_host_ida, host->index);
> +       if (of_alias_get_id(host->parent->of_node, "mmc") < 0)
> +               ida_simple_remove(&mmc_host_ida, host->index);
>         kfree(host);
>  }
>
> @@ -444,7 +445,7 @@ static int mmc_first_nonreserved_index(void)
>   */
>  struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
>  {
> -       int err;
> +       int index;
>         struct mmc_host *host;
>         int alias_id, min_idx, max_idx;
>
> @@ -457,20 +458,19 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
>
>         alias_id = of_alias_get_id(dev->of_node, "mmc");
>         if (alias_id >= 0) {
> -               min_idx = alias_id;
> -               max_idx = alias_id + 1;
> +               index = alias_id;
>         } else {
>                 min_idx = mmc_first_nonreserved_index();
>                 max_idx = 0;
> -       }
>
> -       err = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL);
> -       if (err < 0) {
> -               kfree(host);
> -               return NULL;
> +               index = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL);
> +               if (index < 0) {
> +                       kfree(host);
> +                       return NULL;
> +               }

This means that a DTB that is screwed up in a way that it has two mmc
aliases with the same index, would be allowed to use the same index.

What will happen when we continue the probe sequence in such a case?

>         }
>
> -       host->index = err;
> +       host->index = index;
>
>         dev_set_name(&host->class_dev, "mmc%d", host->index);
>         host->ws = wakeup_source_register(NULL, dev_name(&host->class_dev));

Another concern that could potentially be a problem, is that the
"thread" that holds the reference that prevents ida from being
removed, how would that react to a new mmc device to become
re-registered with the same index?

I wonder if we perhaps should return -EPROBE_DEFER instead, when
ida_simple_get() fails?

Kind regards
Uffe

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ