From: Dan Carpenter <dan.carpenter@oracle.com>
To: Emil Velikov <emil.l.velikov@gmail.com>
Cc: David Airlie <airlied@linux.ie>,
kernel-janitors@vger.kernel.org,
ML dri-devel <dri-devel@lists.freedesktop.org>,
Thomas Zimmermann <tzimmermann@suse.de>
Subject: Re: [PATCH] drm/gem: Fix a leak in drm_gem_objects_lookup()
Date: Mon, 23 Mar 2020 12:13:33 +0000 [thread overview]
Message-ID: <20200323121333.GF26299@kadam> (raw)
In-Reply-To: <CACvgo51xwgF2hJPOESWGpJ16WittQSVixdd+62KwFsZaHO-Dpg@mail.gmail.com>
On Mon, Mar 23, 2020 at 11:13:22AM +0000, Emil Velikov wrote:
> Hi Dan,
>
> On Fri, 20 Mar 2020 at 13:23, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> >
> > If the "handles" allocation or the copy_from_user() fails then we leak
> > "objs". It's supposed to be freed in panfrost_job_cleanup().
> >
> > Fixes: c117aa4d8701 ("drm: Add a drm_gem_objects_lookup helper")
> > Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> > ---
> > drivers/gpu/drm/drm_gem.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> > index a9e4a610445a..f28724f2eb69 100644
> > --- a/drivers/gpu/drm/drm_gem.c
> > +++ b/drivers/gpu/drm/drm_gem.c
> > @@ -710,6 +710,8 @@ int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
> > if (!objs)
> > return -ENOMEM;
> >
> > + *objs_out = objs;
> > +
> > handles = kvmalloc_array(count, sizeof(u32), GFP_KERNEL);
> > if (!handles) {
> > ret = -ENOMEM;
> > @@ -723,8 +725,6 @@ int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
> > }
> >
> > ret = objects_lookup(filp, handles, count, objs);
> > - *objs_out = objs;
> > -
> > out:
> > kvfree(handles);
> > return ret;
>
> It seems that this will return error to the caller, mangle the output
> pointer and effectively still leak the objs.
The patch works.
This is "one function frees everything" style error handling. It gets
passed back to panfrost_ioctl_submit() which calls panfrost_job_put()
which calls panfrost_job_cleanup() which frees it.
It's a horrible way to do error handling but this was the only actual
bug I could see with the approach.
> Better option IMHO is to:
> - move the __user/copy_from_user into the caller
> Removes a silly kvmalloc_array(1,...) in ~90+ users and drops the "out" label.
> Extra bonus, this is the only instance in drm_gem with __user -
> consistency is nice.
> - add "err" or similar label, where the objs is freed before returning an error.
Those sound like good ideas. Also we could use kvcalloc() instead of
kvmalloc_array() with __GFP_ZERO. But it's too much for me to do...
I'm mostly focused on static analysis warnings.
regards,
dan carpenter
WARNING: multiple messages have this Message-ID (diff)
From: Dan Carpenter <dan.carpenter@oracle.com>
To: Emil Velikov <emil.l.velikov@gmail.com>
Cc: David Airlie <airlied@linux.ie>,
kernel-janitors@vger.kernel.org,
ML dri-devel <dri-devel@lists.freedesktop.org>,
Thomas Zimmermann <tzimmermann@suse.de>
Subject: Re: [PATCH] drm/gem: Fix a leak in drm_gem_objects_lookup()
Date: Mon, 23 Mar 2020 15:13:33 +0300 [thread overview]
Message-ID: <20200323121333.GF26299@kadam> (raw)
In-Reply-To: <CACvgo51xwgF2hJPOESWGpJ16WittQSVixdd+62KwFsZaHO-Dpg@mail.gmail.com>
On Mon, Mar 23, 2020 at 11:13:22AM +0000, Emil Velikov wrote:
> Hi Dan,
>
> On Fri, 20 Mar 2020 at 13:23, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> >
> > If the "handles" allocation or the copy_from_user() fails then we leak
> > "objs". It's supposed to be freed in panfrost_job_cleanup().
> >
> > Fixes: c117aa4d8701 ("drm: Add a drm_gem_objects_lookup helper")
> > Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> > ---
> > drivers/gpu/drm/drm_gem.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> > index a9e4a610445a..f28724f2eb69 100644
> > --- a/drivers/gpu/drm/drm_gem.c
> > +++ b/drivers/gpu/drm/drm_gem.c
> > @@ -710,6 +710,8 @@ int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
> > if (!objs)
> > return -ENOMEM;
> >
> > + *objs_out = objs;
> > +
> > handles = kvmalloc_array(count, sizeof(u32), GFP_KERNEL);
> > if (!handles) {
> > ret = -ENOMEM;
> > @@ -723,8 +725,6 @@ int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
> > }
> >
> > ret = objects_lookup(filp, handles, count, objs);
> > - *objs_out = objs;
> > -
> > out:
> > kvfree(handles);
> > return ret;
>
> It seems that this will return error to the caller, mangle the output
> pointer and effectively still leak the objs.
The patch works.
This is "one function frees everything" style error handling. It gets
passed back to panfrost_ioctl_submit() which calls panfrost_job_put()
which calls panfrost_job_cleanup() which frees it.
It's a horrible way to do error handling but this was the only actual
bug I could see with the approach.
> Better option IMHO is to:
> - move the __user/copy_from_user into the caller
> Removes a silly kvmalloc_array(1,...) in ~90+ users and drops the "out" label.
> Extra bonus, this is the only instance in drm_gem with __user -
> consistency is nice.
> - add "err" or similar label, where the objs is freed before returning an error.
Those sound like good ideas. Also we could use kvcalloc() instead of
kvmalloc_array() with __GFP_ZERO. But it's too much for me to do...
I'm mostly focused on static analysis warnings.
regards,
dan carpenter
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2020-03-23 12:13 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-20 13:23 [PATCH] drm/gem: Fix a leak in drm_gem_objects_lookup() Dan Carpenter
2020-03-20 13:23 ` Dan Carpenter
2020-03-23 11:13 ` Emil Velikov
2020-03-23 11:13 ` Emil Velikov
2020-03-23 12:13 ` Dan Carpenter [this message]
2020-03-23 12:13 ` Dan Carpenter
2020-05-17 20:48 ` Emil Velikov
2020-05-17 20:48 ` Emil Velikov
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=20200323121333.GF26299@kadam \
--to=dan.carpenter@oracle.com \
--cc=airlied@linux.ie \
--cc=dri-devel@lists.freedesktop.org \
--cc=emil.l.velikov@gmail.com \
--cc=kernel-janitors@vger.kernel.org \
--cc=tzimmermann@suse.de \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.