public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Ben Widawsky <ben@bwidawsk.net>
To: Chris Wilson <chris@chris-wilson.co.uk>
Cc: intel-gfx@lists.freedesktop.org, stable@vger.kernel.org
Subject: Re: [PATCH] drm/i915: Prevent double unref following alloc failure during execbuffer
Date: Wed, 4 Dec 2013 09:23:24 -0800	[thread overview]
Message-ID: <20131204172323.GB2350@bwidawsk.net> (raw)
In-Reply-To: <1386150778-9066-1-git-send-email-chris@chris-wilson.co.uk>

On Wed, Dec 04, 2013 at 09:52:58AM +0000, Chris Wilson wrote:
> Whilst looking up the objects required for an execbuffer, an untimely
> allocation failure in creating the vma results in the object being
> unreferenced from two lists. The ownership during the lookup is meant to
> be moved from the list of objects being looked to the vma, and this
> double unreference upon error results in a use-after-free.
> 
> Fixes regression from
> commit 27173f1f95db5e74ceb35fe9a2f2f348ea11bac9
> Author: Ben Widawsky <ben@bwidawsk.net>
> Date:   Wed Aug 14 11:38:36 2013 +0200
> 
>     drm/i915: Convert execbuf code to use vmas
> 
> Based on the fix by Ben Widawsky.

A note on why this is an improvement over my fix would have been nice. I
had implemented something similar too, but found my eventual patch to be
a little easier to understand.

My real gripe is, I had already sent off my patch to be tested by QA -
and they give me about a 2d turnaround (not including weekends), which
means the soonest I could get this tested and get results is next Wed.

So if there is no improvement, I'd really appreciate this as a cleanup
on top of my patch.

> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Ben Widawsky <ben@bwidawsk.net>
> Cc: stable@vger.kernel.org
> ---
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c | 24 ++++++++++++++++--------
>  1 file changed, 16 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index c7af37187dee..5663b873a1aa 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -94,7 +94,7 @@ eb_lookup_vmas(struct eb_vmas *eb,
>  	struct drm_i915_private *dev_priv = vm->dev->dev_private;
>  	struct drm_i915_gem_object *obj;
>  	struct list_head objects;
> -	int i, ret = 0;
> +	int i, ret;
>  
>  	INIT_LIST_HEAD(&objects);
>  	spin_lock(&file->table_lock);
> @@ -107,7 +107,7 @@ eb_lookup_vmas(struct eb_vmas *eb,
>  			DRM_DEBUG("Invalid object handle %d at index %d\n",
>  				   exec[i].handle, i);
>  			ret = -ENOENT;
> -			goto out;
> +			goto err;
>  		}
>  
>  		if (!list_empty(&obj->obj_exec_link)) {
> @@ -115,7 +115,7 @@ eb_lookup_vmas(struct eb_vmas *eb,
>  			DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n",
>  				   obj, exec[i].handle, i);
>  			ret = -EINVAL;
> -			goto out;
> +			goto err;
>  		}
>  
>  		drm_gem_object_reference(&obj->base);
> @@ -124,7 +124,7 @@ eb_lookup_vmas(struct eb_vmas *eb,
>  	spin_unlock(&file->table_lock);
>  
>  	i = 0;
> -	list_for_each_entry(obj, &objects, obj_exec_link) {
> +	while (!list_empty(&objects)) {
>  		struct i915_vma *vma;
>  		struct i915_address_space *bind_vm = vm;
>  
> @@ -136,6 +136,10 @@ eb_lookup_vmas(struct eb_vmas *eb,
>  		    (i == (args->buffer_count - 1))))
>  			bind_vm = &dev_priv->gtt.base;
>  
> +		obj = list_first_entry(&objects,
> +				       struct drm_i915_gem_object,
> +				       obj_exec_link);
> +
>  		/*
>  		 * NOTE: We can leak any vmas created here when something fails
>  		 * later on. But that's no issue since vma_unbind can deal with
> @@ -148,10 +152,12 @@ eb_lookup_vmas(struct eb_vmas *eb,
>  		if (IS_ERR(vma)) {
>  			DRM_DEBUG("Failed to lookup VMA\n");
>  			ret = PTR_ERR(vma);
> -			goto out;
> +			goto err;
>  		}
>  
> +		/* Transfer ownership from objects to the vma */
>  		list_add_tail(&vma->exec_list, &eb->vmas);
> +		list_del_init(&obj->obj_exec_link);
>  
>  		vma->exec_entry = &exec[i];
>  		if (eb->and < 0) {
> @@ -165,16 +171,18 @@ eb_lookup_vmas(struct eb_vmas *eb,
>  		++i;
>  	}
>  
> +	return 0;
>  
> -out:
> +
> +err:
>  	while (!list_empty(&objects)) {
>  		obj = list_first_entry(&objects,
>  				       struct drm_i915_gem_object,
>  				       obj_exec_link);
>  		list_del_init(&obj->obj_exec_link);
> -		if (ret)
> -			drm_gem_object_unreference(&obj->base);
> +		drm_gem_object_unreference(&obj->base);
>  	}
> +	/* objects already transfered to the vma will be reaped by eb_destroy */
>  	return ret;
>  }
>  
> -- 
> 1.8.5
> 

-- 
Ben Widawsky, Intel Open Source Technology Center

  reply	other threads:[~2013-12-04 17:23 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-04  1:28 [PATCH] drm/i915: Fixed bad refcounting on execbuf failures Ben Widawsky
2013-12-04  9:52 ` [PATCH] drm/i915: Prevent double unref following alloc failure during execbuffer Chris Wilson
2013-12-04 17:23   ` Ben Widawsky [this message]
2013-12-04 17:37     ` Chris Wilson
2013-12-11 21:22       ` [Intel-gfx] " Daniel Vetter

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=20131204172323.GB2350@bwidawsk.net \
    --to=ben@bwidawsk.net \
    --cc=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=stable@vger.kernel.org \
    /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