Re: [PATCH v2] ovl: fix possible use after free on redirect dir lookup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jan 18, 2017 at 12:38 PM, Miklos Szeredi <miklos@xxxxxxxxxx> wrote:
> Amir,
>
> Thanks for spotting this bug and for the patch.
>
> I simplified it a bit (appended)
>

Simpler indeed.

> I don't think it's justified to copy the string just for the sake of an
> assertation, so got rid of that.  Also tweaked the breakout condition to make
> things clearer.
>

I agree that copying the string is an overkill, but if this bug has
taught us anything
is that the assertion was not sufficient, so I don't think we should
leave no assert
at all. please see my suggested assert below (with which I tested your patch).

> Only compile tested.  Please let me know if this works or not.
>

It works.

> Thanks,
> Miklos
>
> ---
> From: Amir Goldstein <amir73il@xxxxxxxxx>
> Subject: ovl: fix possible use after free on redirect dir lookup
>
> ovl_lookup_layer() iterates on path elements of d->name.name
> but also frees and allocates a new pointer for d->name.name.
>
> For the case of lookup in upper layer, the initial d->name.name
> pointer is stable (dentry->d_name), but for lower layers, the
> initial d->name.name can be d->redirect, which can be freed during
> iteration.
>
> [SzM]
> Keep the count of remaining characters in the redirect path and calculate
> the current position from that.  This works becuase only the prefix is
> modified, the ending always stays the same.
>
> Fixes: 02b69b284cd7 ("ovl: lookup redirects")
> Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
> Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx>
> ---
>  fs/overlayfs/namei.c |   25 ++++++++++++++-----------
>  1 file changed, 14 insertions(+), 11 deletions(-)
> --- a/fs/overlayfs/namei.c
> +++ b/fs/overlayfs/namei.c
> @@ -154,29 +154,32 @@ static int ovl_lookup_single(struct dent
>  static int ovl_lookup_layer(struct dentry *base, struct ovl_lookup_data *d,
>                             struct dentry **ret)
>  {
> -       const char *s = d->name.name;
> +       /* Counting down from the end, since the prefix can change */
> +       size_t rem = d->name.len;
>         struct dentry *dentry = NULL;
>         int err;
>
> -       if (*s != '/')
> +       if (d->name.name[0] != '/')
>                 return ovl_lookup_single(base, d, d->name.name, d->name.len,
>                                          0, "", ret);
>
> -       while (*s++ == '/' && !IS_ERR_OR_NULL(base) && d_can_lookup(base)) {
> +       rem--;
> +       while (!IS_ERR_OR_NULL(base) && d_can_lookup(base)) {
> +               const char *s = d->name.name + d->name.len - rem;
>                 const char *next = strchrnul(s, '/');
> -               size_t slen = strlen(s);
> +               size_t thislen = next - s;
> +               bool end = !next[0];
>
> -               if (WARN_ON(slen > d->name.len) ||
> -                   WARN_ON(strcmp(d->name.name + d->name.len - slen, s)))
> -                       return -EIO;
> -
> -               err = ovl_lookup_single(base, d, s, next - s,
> -                                       d->name.len - slen, next, &base);


+               /* Verify we did not go off the rails */
+               if (WARN_ON(s[-1] != '/'))
+                       return -EIO;
+

> +               err = ovl_lookup_single(base, d, s, thislen,
> +                                       d->name.len - rem, next, &base);
>                 dput(dentry);
>                 if (err)
>                         return err;
>                 dentry = base;
> -               s = next;
> +               if (end)
> +                       break;
> +
> +               rem -= thislen + 1;
>         }
>         *ret = dentry;
>         return 0;
--
To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux