* [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last
@ 2023-02-14 12:50 Tvrtko Ursulin
2023-02-14 13:59 ` Christian König
2023-02-15 9:57 ` Steven Price
0 siblings, 2 replies; 7+ messages in thread
From: Tvrtko Ursulin @ 2023-02-14 12:50 UTC (permalink / raw)
To: dri-devel
Cc: Rob Clark, lima, Tvrtko Ursulin, nouveau, amd-gfx, Steven Price,
Noralf Trønnes, Ben Skeggs, Daniel Vetter, David Herrmann,
spice-devel, virtualization, Zack Rusin
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Currently drm_gem_handle_create_tail exposes the handle to userspace
before the buffer object constructions is complete. This allowing
of working against a partially constructed object, which may also be in
the process of having its creation fail, can have a range of negative
outcomes.
A lot of those will depend on what the individual drivers are doing in
their obj->funcs->open() callbacks, and also with a common failure mode
being -ENOMEM from drm_vma_node_allow.
We can make sure none of this can happen by allocating a handle last,
although with a downside that more of the function now runs under the
dev->object_name_lock.
Looking into the individual drivers open() hooks, we have
amdgpu_gem_object_open which seems like it could have a potential security
issue without this change.
A couple drivers like qxl_gem_object_open and vmw_gem_object_open
implement no-op hooks so no impact for them.
A bunch of other require a deeper look by individual owners to asses for
impact. Those are lima_gem_object_open, nouveau_gem_object_open,
panfrost_gem_open, radeon_gem_object_open and virtio_gpu_gem_object_open.
Putting aside the risk assesment of the above, some common scenarios to
think about are along these lines:
1)
Userspace closes a handle by speculatively "guessing" it from a second
thread.
This results in an unreachable buffer object so, a memory leak.
2)
Same as 1), but object is in the process of getting closed (failed
creation).
The second thread is then able to re-cycle the handle and idr_remove would
in the first thread would then remove the handle it does not own from the
idr.
3)
Going back to the earlier per driver problem space - individual impact
assesment of allowing a second thread to access and operate on a partially
constructed handle / object. (Can something crash? Leak information?)
In terms of identifying when the problem started I will tag some patches
as references, but not all, if even any, of them actually point to a
broken state. I am just identifying points at which more opportunity for
issues to arise was added.
References: 304eda32920b ("drm/gem: add hooks to notify driver when object handle is created/destroyed")
References: ca481c9b2a3a ("drm/gem: implement vma access management")
References: b39b5394fabc ("drm/gem: Add drm_gem_object_funcs")
Cc: dri-devel@lists.freedesktop.org
Cc: Rob Clark <robdclark@chromium.org>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: David Herrmann <dh.herrmann@gmail.com>
Cc: Noralf Trønnes <noralf@tronnes.org>
Cc: David Airlie <airlied@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: amd-gfx@lists.freedesktop.org
Cc: lima@lists.freedesktop.org
Cc: nouveau@lists.freedesktop.org
Cc: Steven Price <steven.price@arm.com>
Cc: virtualization@lists.linux-foundation.org
Cc: spice-devel@lists.freedesktop.org
Cc: Zack Rusin <zackr@vmware.com>
---
drivers/gpu/drm/drm_gem.c | 48 +++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index aa15c52ae182..e3d897bca0f2 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -356,52 +356,52 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
u32 *handlep)
{
struct drm_device *dev = obj->dev;
- u32 handle;
int ret;
WARN_ON(!mutex_is_locked(&dev->object_name_lock));
if (obj->handle_count++ == 0)
drm_gem_object_get(obj);
+ ret = drm_vma_node_allow(&obj->vma_node, file_priv);
+ if (ret)
+ goto err_put;
+
+ if (obj->funcs->open) {
+ ret = obj->funcs->open(obj, file_priv);
+ if (ret)
+ goto err_revoke;
+ }
+
/*
- * Get the user-visible handle using idr. Preload and perform
- * allocation under our spinlock.
+ * Get the user-visible handle using idr as the _last_ step.
+ * Preload and perform allocation under our spinlock.
*/
idr_preload(GFP_KERNEL);
spin_lock(&file_priv->table_lock);
-
ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
-
spin_unlock(&file_priv->table_lock);
idr_preload_end();
- mutex_unlock(&dev->object_name_lock);
if (ret < 0)
- goto err_unref;
-
- handle = ret;
+ goto err_close;
- ret = drm_vma_node_allow(&obj->vma_node, file_priv);
- if (ret)
- goto err_remove;
+ mutex_unlock(&dev->object_name_lock);
- if (obj->funcs->open) {
- ret = obj->funcs->open(obj, file_priv);
- if (ret)
- goto err_revoke;
- }
+ *handlep = ret;
- *handlep = handle;
return 0;
+err_close:
+ if (obj->funcs->close)
+ obj->funcs->close(obj, file_priv);
err_revoke:
drm_vma_node_revoke(&obj->vma_node, file_priv);
-err_remove:
- spin_lock(&file_priv->table_lock);
- idr_remove(&file_priv->object_idr, handle);
- spin_unlock(&file_priv->table_lock);
-err_unref:
- drm_gem_object_handle_put_unlocked(obj);
+err_put:
+ if (--obj->handle_count == 0)
+ drm_gem_object_put(obj);
+
+ mutex_unlock(&dev->object_name_lock);
+
return ret;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last
2023-02-14 12:50 [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last Tvrtko Ursulin
@ 2023-02-14 13:59 ` Christian König
2023-02-20 9:55 ` Tvrtko Ursulin
2023-02-15 9:57 ` Steven Price
1 sibling, 1 reply; 7+ messages in thread
From: Christian König @ 2023-02-14 13:59 UTC (permalink / raw)
To: Tvrtko Ursulin, dri-devel
Cc: Rob Clark, lima, Tvrtko Ursulin, nouveau, amd-gfx, Steven Price,
Noralf Trønnes, Ben Skeggs, Daniel Vetter, David Herrmann,
spice-devel, virtualization, Zack Rusin
Am 14.02.23 um 13:50 schrieb Tvrtko Ursulin:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> Currently drm_gem_handle_create_tail exposes the handle to userspace
> before the buffer object constructions is complete. This allowing
> of working against a partially constructed object, which may also be in
> the process of having its creation fail, can have a range of negative
> outcomes.
>
> A lot of those will depend on what the individual drivers are doing in
> their obj->funcs->open() callbacks, and also with a common failure mode
> being -ENOMEM from drm_vma_node_allow.
>
> We can make sure none of this can happen by allocating a handle last,
> although with a downside that more of the function now runs under the
> dev->object_name_lock.
>
> Looking into the individual drivers open() hooks, we have
> amdgpu_gem_object_open which seems like it could have a potential security
> issue without this change.
>
> A couple drivers like qxl_gem_object_open and vmw_gem_object_open
> implement no-op hooks so no impact for them.
>
> A bunch of other require a deeper look by individual owners to asses for
> impact. Those are lima_gem_object_open, nouveau_gem_object_open,
> panfrost_gem_open, radeon_gem_object_open and virtio_gpu_gem_object_open.
>
> Putting aside the risk assesment of the above, some common scenarios to
> think about are along these lines:
>
> 1)
> Userspace closes a handle by speculatively "guessing" it from a second
> thread.
>
> This results in an unreachable buffer object so, a memory leak.
>
> 2)
> Same as 1), but object is in the process of getting closed (failed
> creation).
>
> The second thread is then able to re-cycle the handle and idr_remove would
> in the first thread would then remove the handle it does not own from the
> idr.
>
> 3)
> Going back to the earlier per driver problem space - individual impact
> assesment of allowing a second thread to access and operate on a partially
> constructed handle / object. (Can something crash? Leak information?)
>
> In terms of identifying when the problem started I will tag some patches
> as references, but not all, if even any, of them actually point to a
> broken state. I am just identifying points at which more opportunity for
> issues to arise was added.
Yes I've looked into this once as well, but couldn't completely solve it
for some reason.
Give me a day or two to get this tested and all the logic swapped back
into my head again.
Christian.
>
> References: 304eda32920b ("drm/gem: add hooks to notify driver when object handle is created/destroyed")
> References: ca481c9b2a3a ("drm/gem: implement vma access management")
> References: b39b5394fabc ("drm/gem: Add drm_gem_object_funcs")
> Cc: dri-devel@lists.freedesktop.org
> Cc: Rob Clark <robdclark@chromium.org>
> Cc: Ben Skeggs <bskeggs@redhat.com>
> Cc: David Herrmann <dh.herrmann@gmail.com>
> Cc: Noralf Trønnes <noralf@tronnes.org>
> Cc: David Airlie <airlied@gmail.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: amd-gfx@lists.freedesktop.org
> Cc: lima@lists.freedesktop.org
> Cc: nouveau@lists.freedesktop.org
> Cc: Steven Price <steven.price@arm.com>
> Cc: virtualization@lists.linux-foundation.org
> Cc: spice-devel@lists.freedesktop.org
> Cc: Zack Rusin <zackr@vmware.com>
> ---
> drivers/gpu/drm/drm_gem.c | 48 +++++++++++++++++++--------------------
> 1 file changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index aa15c52ae182..e3d897bca0f2 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -356,52 +356,52 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
> u32 *handlep)
> {
> struct drm_device *dev = obj->dev;
> - u32 handle;
> int ret;
>
> WARN_ON(!mutex_is_locked(&dev->object_name_lock));
> if (obj->handle_count++ == 0)
> drm_gem_object_get(obj);
>
> + ret = drm_vma_node_allow(&obj->vma_node, file_priv);
> + if (ret)
> + goto err_put;
> +
> + if (obj->funcs->open) {
> + ret = obj->funcs->open(obj, file_priv);
> + if (ret)
> + goto err_revoke;
> + }
> +
> /*
> - * Get the user-visible handle using idr. Preload and perform
> - * allocation under our spinlock.
> + * Get the user-visible handle using idr as the _last_ step.
> + * Preload and perform allocation under our spinlock.
> */
> idr_preload(GFP_KERNEL);
> spin_lock(&file_priv->table_lock);
> -
> ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
> -
> spin_unlock(&file_priv->table_lock);
> idr_preload_end();
>
> - mutex_unlock(&dev->object_name_lock);
> if (ret < 0)
> - goto err_unref;
> -
> - handle = ret;
> + goto err_close;
>
> - ret = drm_vma_node_allow(&obj->vma_node, file_priv);
> - if (ret)
> - goto err_remove;
> + mutex_unlock(&dev->object_name_lock);
>
> - if (obj->funcs->open) {
> - ret = obj->funcs->open(obj, file_priv);
> - if (ret)
> - goto err_revoke;
> - }
> + *handlep = ret;
>
> - *handlep = handle;
> return 0;
>
> +err_close:
> + if (obj->funcs->close)
> + obj->funcs->close(obj, file_priv);
> err_revoke:
> drm_vma_node_revoke(&obj->vma_node, file_priv);
> -err_remove:
> - spin_lock(&file_priv->table_lock);
> - idr_remove(&file_priv->object_idr, handle);
> - spin_unlock(&file_priv->table_lock);
> -err_unref:
> - drm_gem_object_handle_put_unlocked(obj);
> +err_put:
> + if (--obj->handle_count == 0)
> + drm_gem_object_put(obj);
> +
> + mutex_unlock(&dev->object_name_lock);
> +
> return ret;
> }
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last
2023-02-14 12:50 [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last Tvrtko Ursulin
2023-02-14 13:59 ` Christian König
@ 2023-02-15 9:57 ` Steven Price
1 sibling, 0 replies; 7+ messages in thread
From: Steven Price @ 2023-02-15 9:57 UTC (permalink / raw)
To: Tvrtko Ursulin, dri-devel
Cc: Rob Clark, lima, Tvrtko Ursulin, nouveau, amd-gfx,
virtualization, Noralf Trønnes, Ben Skeggs, Daniel Vetter,
David Herrmann, spice-devel, Zack Rusin
On 14/02/2023 12:50, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> Currently drm_gem_handle_create_tail exposes the handle to userspace
> before the buffer object constructions is complete. This allowing
> of working against a partially constructed object, which may also be in
> the process of having its creation fail, can have a range of negative
> outcomes.
>
> A lot of those will depend on what the individual drivers are doing in
> their obj->funcs->open() callbacks, and also with a common failure mode
> being -ENOMEM from drm_vma_node_allow.
>
> We can make sure none of this can happen by allocating a handle last,
> although with a downside that more of the function now runs under the
> dev->object_name_lock.
>
> Looking into the individual drivers open() hooks, we have
> amdgpu_gem_object_open which seems like it could have a potential security
> issue without this change.
>
> A couple drivers like qxl_gem_object_open and vmw_gem_object_open
> implement no-op hooks so no impact for them.
>
> A bunch of other require a deeper look by individual owners to asses for
> impact. Those are lima_gem_object_open, nouveau_gem_object_open,
> panfrost_gem_open, radeon_gem_object_open and virtio_gpu_gem_object_open.
I've looked over the panfrost code, and I can't see how this could
create a security hole there. It looks like there's a path which can
confuse the shrinker (so objects might not be purged when they could
be[1]) but they would be freed properly in the normal path - so no worse
than user space could already do.
[1] gpu_usecount is incremented in panfrost_lookup_bos() per bo, but not
decremented on failure.
> Putting aside the risk assesment of the above, some common scenarios to
> think about are along these lines:
>
> 1)
> Userspace closes a handle by speculatively "guessing" it from a second
> thread.
>
> This results in an unreachable buffer object so, a memory leak.
>
> 2)
> Same as 1), but object is in the process of getting closed (failed
> creation).
>
> The second thread is then able to re-cycle the handle and idr_remove would
> in the first thread would then remove the handle it does not own from the
> idr.
This, however, looks plausible - and I can see how this could
potentially trigger a security hole in user space.
> 3)
> Going back to the earlier per driver problem space - individual impact
> assesment of allowing a second thread to access and operate on a partially
> constructed handle / object. (Can something crash? Leak information?)
>
> In terms of identifying when the problem started I will tag some patches
> as references, but not all, if even any, of them actually point to a
> broken state. I am just identifying points at which more opportunity for
> issues to arise was added.
>
> References: 304eda32920b ("drm/gem: add hooks to notify driver when object handle is created/destroyed")
> References: ca481c9b2a3a ("drm/gem: implement vma access management")
> References: b39b5394fabc ("drm/gem: Add drm_gem_object_funcs")
> Cc: dri-devel@lists.freedesktop.org
> Cc: Rob Clark <robdclark@chromium.org>
> Cc: Ben Skeggs <bskeggs@redhat.com>
> Cc: David Herrmann <dh.herrmann@gmail.com>
> Cc: Noralf Trønnes <noralf@tronnes.org>
> Cc: David Airlie <airlied@gmail.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: amd-gfx@lists.freedesktop.org
> Cc: lima@lists.freedesktop.org
> Cc: nouveau@lists.freedesktop.org
> Cc: Steven Price <steven.price@arm.com>
> Cc: virtualization@lists.linux-foundation.org
> Cc: spice-devel@lists.freedesktop.org
> Cc: Zack Rusin <zackr@vmware.com>
FWIW I think this makes the code easier to reason about, so
Reviewed-by: Steven Price <steven.price@arm.com>
> ---
> drivers/gpu/drm/drm_gem.c | 48 +++++++++++++++++++--------------------
> 1 file changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index aa15c52ae182..e3d897bca0f2 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -356,52 +356,52 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
> u32 *handlep)
> {
> struct drm_device *dev = obj->dev;
> - u32 handle;
> int ret;
>
> WARN_ON(!mutex_is_locked(&dev->object_name_lock));
> if (obj->handle_count++ == 0)
> drm_gem_object_get(obj);
>
> + ret = drm_vma_node_allow(&obj->vma_node, file_priv);
> + if (ret)
> + goto err_put;
> +
> + if (obj->funcs->open) {
> + ret = obj->funcs->open(obj, file_priv);
> + if (ret)
> + goto err_revoke;
> + }
> +
> /*
> - * Get the user-visible handle using idr. Preload and perform
> - * allocation under our spinlock.
> + * Get the user-visible handle using idr as the _last_ step.
> + * Preload and perform allocation under our spinlock.
> */
> idr_preload(GFP_KERNEL);
> spin_lock(&file_priv->table_lock);
> -
> ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
> -
> spin_unlock(&file_priv->table_lock);
> idr_preload_end();
>
> - mutex_unlock(&dev->object_name_lock);
> if (ret < 0)
> - goto err_unref;
> -
> - handle = ret;
> + goto err_close;
>
> - ret = drm_vma_node_allow(&obj->vma_node, file_priv);
> - if (ret)
> - goto err_remove;
> + mutex_unlock(&dev->object_name_lock);
>
> - if (obj->funcs->open) {
> - ret = obj->funcs->open(obj, file_priv);
> - if (ret)
> - goto err_revoke;
> - }
> + *handlep = ret;
>
> - *handlep = handle;
> return 0;
>
> +err_close:
> + if (obj->funcs->close)
> + obj->funcs->close(obj, file_priv);
> err_revoke:
> drm_vma_node_revoke(&obj->vma_node, file_priv);
> -err_remove:
> - spin_lock(&file_priv->table_lock);
> - idr_remove(&file_priv->object_idr, handle);
> - spin_unlock(&file_priv->table_lock);
> -err_unref:
> - drm_gem_object_handle_put_unlocked(obj);
> +err_put:
> + if (--obj->handle_count == 0)
> + drm_gem_object_put(obj);
> +
> + mutex_unlock(&dev->object_name_lock);
> +
> return ret;
> }
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last
2023-02-14 13:59 ` Christian König
@ 2023-02-20 9:55 ` Tvrtko Ursulin
2023-02-20 10:01 ` Christian König
0 siblings, 1 reply; 7+ messages in thread
From: Tvrtko Ursulin @ 2023-02-20 9:55 UTC (permalink / raw)
To: Christian König, dri-devel
Cc: Rob Clark, lima, Tvrtko Ursulin, nouveau, amd-gfx, Steven Price,
Noralf Trønnes, Ben Skeggs, Daniel Vetter, David Herrmann,
spice-devel, virtualization, Zack Rusin
Hi,
On 14/02/2023 13:59, Christian König wrote:
> Am 14.02.23 um 13:50 schrieb Tvrtko Ursulin:
>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>
>> Currently drm_gem_handle_create_tail exposes the handle to userspace
>> before the buffer object constructions is complete. This allowing
>> of working against a partially constructed object, which may also be in
>> the process of having its creation fail, can have a range of negative
>> outcomes.
>>
>> A lot of those will depend on what the individual drivers are doing in
>> their obj->funcs->open() callbacks, and also with a common failure mode
>> being -ENOMEM from drm_vma_node_allow.
>>
>> We can make sure none of this can happen by allocating a handle last,
>> although with a downside that more of the function now runs under the
>> dev->object_name_lock.
>>
>> Looking into the individual drivers open() hooks, we have
>> amdgpu_gem_object_open which seems like it could have a potential
>> security
>> issue without this change.
>>
>> A couple drivers like qxl_gem_object_open and vmw_gem_object_open
>> implement no-op hooks so no impact for them.
>>
>> A bunch of other require a deeper look by individual owners to asses for
>> impact. Those are lima_gem_object_open, nouveau_gem_object_open,
>> panfrost_gem_open, radeon_gem_object_open and virtio_gpu_gem_object_open.
>>
>> Putting aside the risk assesment of the above, some common scenarios to
>> think about are along these lines:
>>
>> 1)
>> Userspace closes a handle by speculatively "guessing" it from a second
>> thread.
>>
>> This results in an unreachable buffer object so, a memory leak.
>>
>> 2)
>> Same as 1), but object is in the process of getting closed (failed
>> creation).
>>
>> The second thread is then able to re-cycle the handle and idr_remove
>> would
>> in the first thread would then remove the handle it does not own from the
>> idr.
>>
>> 3)
>> Going back to the earlier per driver problem space - individual impact
>> assesment of allowing a second thread to access and operate on a
>> partially
>> constructed handle / object. (Can something crash? Leak information?)
>>
>> In terms of identifying when the problem started I will tag some patches
>> as references, but not all, if even any, of them actually point to a
>> broken state. I am just identifying points at which more opportunity for
>> issues to arise was added.
>
> Yes I've looked into this once as well, but couldn't completely solve it
> for some reason.
>
> Give me a day or two to get this tested and all the logic swapped back
> into my head again.
Managed to recollect what the problem with earlier attempts was?
Regards,
Tvrtko
> Christian.
>
>>
>> References: 304eda32920b ("drm/gem: add hooks to notify driver when
>> object handle is created/destroyed")
>> References: ca481c9b2a3a ("drm/gem: implement vma access management")
>> References: b39b5394fabc ("drm/gem: Add drm_gem_object_funcs")
>> Cc: dri-devel@lists.freedesktop.org
>> Cc: Rob Clark <robdclark@chromium.org>
>> Cc: Ben Skeggs <bskeggs@redhat.com>
>> Cc: David Herrmann <dh.herrmann@gmail.com>
>> Cc: Noralf Trønnes <noralf@tronnes.org>
>> Cc: David Airlie <airlied@gmail.com>
>> Cc: Daniel Vetter <daniel@ffwll.ch>
>> Cc: amd-gfx@lists.freedesktop.org
>> Cc: lima@lists.freedesktop.org
>> Cc: nouveau@lists.freedesktop.org
>> Cc: Steven Price <steven.price@arm.com>
>> Cc: virtualization@lists.linux-foundation.org
>> Cc: spice-devel@lists.freedesktop.org
>> Cc: Zack Rusin <zackr@vmware.com>
>> ---
>> drivers/gpu/drm/drm_gem.c | 48 +++++++++++++++++++--------------------
>> 1 file changed, 24 insertions(+), 24 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
>> index aa15c52ae182..e3d897bca0f2 100644
>> --- a/drivers/gpu/drm/drm_gem.c
>> +++ b/drivers/gpu/drm/drm_gem.c
>> @@ -356,52 +356,52 @@ drm_gem_handle_create_tail(struct drm_file
>> *file_priv,
>> u32 *handlep)
>> {
>> struct drm_device *dev = obj->dev;
>> - u32 handle;
>> int ret;
>> WARN_ON(!mutex_is_locked(&dev->object_name_lock));
>> if (obj->handle_count++ == 0)
>> drm_gem_object_get(obj);
>> + ret = drm_vma_node_allow(&obj->vma_node, file_priv);
>> + if (ret)
>> + goto err_put;
>> +
>> + if (obj->funcs->open) {
>> + ret = obj->funcs->open(obj, file_priv);
>> + if (ret)
>> + goto err_revoke;
>> + }
>> +
>> /*
>> - * Get the user-visible handle using idr. Preload and perform
>> - * allocation under our spinlock.
>> + * Get the user-visible handle using idr as the _last_ step.
>> + * Preload and perform allocation under our spinlock.
>> */
>> idr_preload(GFP_KERNEL);
>> spin_lock(&file_priv->table_lock);
>> -
>> ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
>> -
>> spin_unlock(&file_priv->table_lock);
>> idr_preload_end();
>> - mutex_unlock(&dev->object_name_lock);
>> if (ret < 0)
>> - goto err_unref;
>> -
>> - handle = ret;
>> + goto err_close;
>> - ret = drm_vma_node_allow(&obj->vma_node, file_priv);
>> - if (ret)
>> - goto err_remove;
>> + mutex_unlock(&dev->object_name_lock);
>> - if (obj->funcs->open) {
>> - ret = obj->funcs->open(obj, file_priv);
>> - if (ret)
>> - goto err_revoke;
>> - }
>> + *handlep = ret;
>> - *handlep = handle;
>> return 0;
>> +err_close:
>> + if (obj->funcs->close)
>> + obj->funcs->close(obj, file_priv);
>> err_revoke:
>> drm_vma_node_revoke(&obj->vma_node, file_priv);
>> -err_remove:
>> - spin_lock(&file_priv->table_lock);
>> - idr_remove(&file_priv->object_idr, handle);
>> - spin_unlock(&file_priv->table_lock);
>> -err_unref:
>> - drm_gem_object_handle_put_unlocked(obj);
>> +err_put:
>> + if (--obj->handle_count == 0)
>> + drm_gem_object_put(obj);
>> +
>> + mutex_unlock(&dev->object_name_lock);
>> +
>> return ret;
>> }
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last
2023-02-20 9:55 ` Tvrtko Ursulin
@ 2023-02-20 10:01 ` Christian König
2023-02-20 10:23 ` Tvrtko Ursulin
0 siblings, 1 reply; 7+ messages in thread
From: Christian König @ 2023-02-20 10:01 UTC (permalink / raw)
To: Tvrtko Ursulin, Christian König, dri-devel
Cc: Rob Clark, lima, Tvrtko Ursulin, nouveau, amd-gfx, Steven Price,
Noralf Trønnes, Ben Skeggs, Daniel Vetter, David Herrmann,
spice-devel, virtualization, Zack Rusin
Am 20.02.23 um 10:55 schrieb Tvrtko Ursulin:
>
> Hi,
>
> On 14/02/2023 13:59, Christian König wrote:
>> Am 14.02.23 um 13:50 schrieb Tvrtko Ursulin:
>>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>>
>>> Currently drm_gem_handle_create_tail exposes the handle to userspace
>>> before the buffer object constructions is complete. This allowing
>>> of working against a partially constructed object, which may also be in
>>> the process of having its creation fail, can have a range of negative
>>> outcomes.
>>>
>>> A lot of those will depend on what the individual drivers are doing in
>>> their obj->funcs->open() callbacks, and also with a common failure mode
>>> being -ENOMEM from drm_vma_node_allow.
>>>
>>> We can make sure none of this can happen by allocating a handle last,
>>> although with a downside that more of the function now runs under the
>>> dev->object_name_lock.
>>>
>>> Looking into the individual drivers open() hooks, we have
>>> amdgpu_gem_object_open which seems like it could have a potential
>>> security
>>> issue without this change.
>>>
>>> A couple drivers like qxl_gem_object_open and vmw_gem_object_open
>>> implement no-op hooks so no impact for them.
>>>
>>> A bunch of other require a deeper look by individual owners to asses
>>> for
>>> impact. Those are lima_gem_object_open, nouveau_gem_object_open,
>>> panfrost_gem_open, radeon_gem_object_open and
>>> virtio_gpu_gem_object_open.
>>>
>>> Putting aside the risk assesment of the above, some common scenarios to
>>> think about are along these lines:
>>>
>>> 1)
>>> Userspace closes a handle by speculatively "guessing" it from a second
>>> thread.
>>>
>>> This results in an unreachable buffer object so, a memory leak.
>>>
>>> 2)
>>> Same as 1), but object is in the process of getting closed (failed
>>> creation).
>>>
>>> The second thread is then able to re-cycle the handle and idr_remove
>>> would
>>> in the first thread would then remove the handle it does not own
>>> from the
>>> idr.
>>>
>>> 3)
>>> Going back to the earlier per driver problem space - individual impact
>>> assesment of allowing a second thread to access and operate on a
>>> partially
>>> constructed handle / object. (Can something crash? Leak information?)
>>>
>>> In terms of identifying when the problem started I will tag some
>>> patches
>>> as references, but not all, if even any, of them actually point to a
>>> broken state. I am just identifying points at which more opportunity
>>> for
>>> issues to arise was added.
>>
>> Yes I've looked into this once as well, but couldn't completely solve
>> it for some reason.
>>
>> Give me a day or two to get this tested and all the logic swapped
>> back into my head again.
>
> Managed to recollect what the problem with earlier attempts was?
Nope, that's way to long ago. I can only assume that I ran into problems
with the object_name_lock.
Probably best to double check if that doesn't result in a lock inversion
when somebody grabs the reservation lock in their ->load() callback.
Regards,
Christian.
>
> Regards,
>
> Tvrtko
>
>> Christian.
>>
>>>
>>> References: 304eda32920b ("drm/gem: add hooks to notify driver when
>>> object handle is created/destroyed")
>>> References: ca481c9b2a3a ("drm/gem: implement vma access management")
>>> References: b39b5394fabc ("drm/gem: Add drm_gem_object_funcs")
>>> Cc: dri-devel@lists.freedesktop.org
>>> Cc: Rob Clark <robdclark@chromium.org>
>>> Cc: Ben Skeggs <bskeggs@redhat.com>
>>> Cc: David Herrmann <dh.herrmann@gmail.com>
>>> Cc: Noralf Trønnes <noralf@tronnes.org>
>>> Cc: David Airlie <airlied@gmail.com>
>>> Cc: Daniel Vetter <daniel@ffwll.ch>
>>> Cc: amd-gfx@lists.freedesktop.org
>>> Cc: lima@lists.freedesktop.org
>>> Cc: nouveau@lists.freedesktop.org
>>> Cc: Steven Price <steven.price@arm.com>
>>> Cc: virtualization@lists.linux-foundation.org
>>> Cc: spice-devel@lists.freedesktop.org
>>> Cc: Zack Rusin <zackr@vmware.com>
>>> ---
>>> drivers/gpu/drm/drm_gem.c | 48
>>> +++++++++++++++++++--------------------
>>> 1 file changed, 24 insertions(+), 24 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
>>> index aa15c52ae182..e3d897bca0f2 100644
>>> --- a/drivers/gpu/drm/drm_gem.c
>>> +++ b/drivers/gpu/drm/drm_gem.c
>>> @@ -356,52 +356,52 @@ drm_gem_handle_create_tail(struct drm_file
>>> *file_priv,
>>> u32 *handlep)
>>> {
>>> struct drm_device *dev = obj->dev;
>>> - u32 handle;
>>> int ret;
>>> WARN_ON(!mutex_is_locked(&dev->object_name_lock));
>>> if (obj->handle_count++ == 0)
>>> drm_gem_object_get(obj);
>>> + ret = drm_vma_node_allow(&obj->vma_node, file_priv);
>>> + if (ret)
>>> + goto err_put;
>>> +
>>> + if (obj->funcs->open) {
>>> + ret = obj->funcs->open(obj, file_priv);
>>> + if (ret)
>>> + goto err_revoke;
>>> + }
>>> +
>>> /*
>>> - * Get the user-visible handle using idr. Preload and perform
>>> - * allocation under our spinlock.
>>> + * Get the user-visible handle using idr as the _last_ step.
>>> + * Preload and perform allocation under our spinlock.
>>> */
>>> idr_preload(GFP_KERNEL);
>>> spin_lock(&file_priv->table_lock);
>>> -
>>> ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
>>> -
>>> spin_unlock(&file_priv->table_lock);
>>> idr_preload_end();
>>> - mutex_unlock(&dev->object_name_lock);
>>> if (ret < 0)
>>> - goto err_unref;
>>> -
>>> - handle = ret;
>>> + goto err_close;
>>> - ret = drm_vma_node_allow(&obj->vma_node, file_priv);
>>> - if (ret)
>>> - goto err_remove;
>>> + mutex_unlock(&dev->object_name_lock);
>>> - if (obj->funcs->open) {
>>> - ret = obj->funcs->open(obj, file_priv);
>>> - if (ret)
>>> - goto err_revoke;
>>> - }
>>> + *handlep = ret;
>>> - *handlep = handle;
>>> return 0;
>>> +err_close:
>>> + if (obj->funcs->close)
>>> + obj->funcs->close(obj, file_priv);
>>> err_revoke:
>>> drm_vma_node_revoke(&obj->vma_node, file_priv);
>>> -err_remove:
>>> - spin_lock(&file_priv->table_lock);
>>> - idr_remove(&file_priv->object_idr, handle);
>>> - spin_unlock(&file_priv->table_lock);
>>> -err_unref:
>>> - drm_gem_object_handle_put_unlocked(obj);
>>> +err_put:
>>> + if (--obj->handle_count == 0)
>>> + drm_gem_object_put(obj);
>>> +
>>> + mutex_unlock(&dev->object_name_lock);
>>> +
>>> return ret;
>>> }
>>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last
2023-02-20 10:01 ` Christian König
@ 2023-02-20 10:23 ` Tvrtko Ursulin
2023-02-23 9:17 ` Christian König
0 siblings, 1 reply; 7+ messages in thread
From: Tvrtko Ursulin @ 2023-02-20 10:23 UTC (permalink / raw)
To: Christian König, Christian König, dri-devel
Cc: Rob Clark, lima, Tvrtko Ursulin, nouveau, amd-gfx, Steven Price,
Noralf Trønnes, Ben Skeggs, Daniel Vetter, David Herrmann,
spice-devel, virtualization, Zack Rusin
On 20/02/2023 10:01, Christian König wrote:
> Am 20.02.23 um 10:55 schrieb Tvrtko Ursulin:
>>
>> Hi,
>>
>> On 14/02/2023 13:59, Christian König wrote:
>>> Am 14.02.23 um 13:50 schrieb Tvrtko Ursulin:
>>>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>>>
>>>> Currently drm_gem_handle_create_tail exposes the handle to userspace
>>>> before the buffer object constructions is complete. This allowing
>>>> of working against a partially constructed object, which may also be in
>>>> the process of having its creation fail, can have a range of negative
>>>> outcomes.
>>>>
>>>> A lot of those will depend on what the individual drivers are doing in
>>>> their obj->funcs->open() callbacks, and also with a common failure mode
>>>> being -ENOMEM from drm_vma_node_allow.
>>>>
>>>> We can make sure none of this can happen by allocating a handle last,
>>>> although with a downside that more of the function now runs under the
>>>> dev->object_name_lock.
>>>>
>>>> Looking into the individual drivers open() hooks, we have
>>>> amdgpu_gem_object_open which seems like it could have a potential
>>>> security
>>>> issue without this change.
>>>>
>>>> A couple drivers like qxl_gem_object_open and vmw_gem_object_open
>>>> implement no-op hooks so no impact for them.
>>>>
>>>> A bunch of other require a deeper look by individual owners to asses
>>>> for
>>>> impact. Those are lima_gem_object_open, nouveau_gem_object_open,
>>>> panfrost_gem_open, radeon_gem_object_open and
>>>> virtio_gpu_gem_object_open.
>>>>
>>>> Putting aside the risk assesment of the above, some common scenarios to
>>>> think about are along these lines:
>>>>
>>>> 1)
>>>> Userspace closes a handle by speculatively "guessing" it from a second
>>>> thread.
>>>>
>>>> This results in an unreachable buffer object so, a memory leak.
>>>>
>>>> 2)
>>>> Same as 1), but object is in the process of getting closed (failed
>>>> creation).
>>>>
>>>> The second thread is then able to re-cycle the handle and idr_remove
>>>> would
>>>> in the first thread would then remove the handle it does not own
>>>> from the
>>>> idr.
>>>>
>>>> 3)
>>>> Going back to the earlier per driver problem space - individual impact
>>>> assesment of allowing a second thread to access and operate on a
>>>> partially
>>>> constructed handle / object. (Can something crash? Leak information?)
>>>>
>>>> In terms of identifying when the problem started I will tag some
>>>> patches
>>>> as references, but not all, if even any, of them actually point to a
>>>> broken state. I am just identifying points at which more opportunity
>>>> for
>>>> issues to arise was added.
>>>
>>> Yes I've looked into this once as well, but couldn't completely solve
>>> it for some reason.
>>>
>>> Give me a day or two to get this tested and all the logic swapped
>>> back into my head again.
>>
>> Managed to recollect what the problem with earlier attempts was?
>
> Nope, that's way to long ago. I can only assume that I ran into problems
> with the object_name_lock.
>
> Probably best to double check if that doesn't result in a lock inversion
> when somebody grabs the reservation lock in their ->load() callback.
Hmm I don't immediately follow the connection. But I have only found
radeon_driver_load_kms as using the load callback. Is there any lockdep
enabled CI for that driver which could tell us if there is a problem there?
Regards,
Tvrtko
>
> Regards,
> Christian.
>
>>
>> Regards,
>>
>> Tvrtko
>>
>>> Christian.
>>>
>>>>
>>>> References: 304eda32920b ("drm/gem: add hooks to notify driver when
>>>> object handle is created/destroyed")
>>>> References: ca481c9b2a3a ("drm/gem: implement vma access management")
>>>> References: b39b5394fabc ("drm/gem: Add drm_gem_object_funcs")
>>>> Cc: dri-devel@lists.freedesktop.org
>>>> Cc: Rob Clark <robdclark@chromium.org>
>>>> Cc: Ben Skeggs <bskeggs@redhat.com>
>>>> Cc: David Herrmann <dh.herrmann@gmail.com>
>>>> Cc: Noralf Trønnes <noralf@tronnes.org>
>>>> Cc: David Airlie <airlied@gmail.com>
>>>> Cc: Daniel Vetter <daniel@ffwll.ch>
>>>> Cc: amd-gfx@lists.freedesktop.org
>>>> Cc: lima@lists.freedesktop.org
>>>> Cc: nouveau@lists.freedesktop.org
>>>> Cc: Steven Price <steven.price@arm.com>
>>>> Cc: virtualization@lists.linux-foundation.org
>>>> Cc: spice-devel@lists.freedesktop.org
>>>> Cc: Zack Rusin <zackr@vmware.com>
>>>> ---
>>>> drivers/gpu/drm/drm_gem.c | 48
>>>> +++++++++++++++++++--------------------
>>>> 1 file changed, 24 insertions(+), 24 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
>>>> index aa15c52ae182..e3d897bca0f2 100644
>>>> --- a/drivers/gpu/drm/drm_gem.c
>>>> +++ b/drivers/gpu/drm/drm_gem.c
>>>> @@ -356,52 +356,52 @@ drm_gem_handle_create_tail(struct drm_file
>>>> *file_priv,
>>>> u32 *handlep)
>>>> {
>>>> struct drm_device *dev = obj->dev;
>>>> - u32 handle;
>>>> int ret;
>>>> WARN_ON(!mutex_is_locked(&dev->object_name_lock));
>>>> if (obj->handle_count++ == 0)
>>>> drm_gem_object_get(obj);
>>>> + ret = drm_vma_node_allow(&obj->vma_node, file_priv);
>>>> + if (ret)
>>>> + goto err_put;
>>>> +
>>>> + if (obj->funcs->open) {
>>>> + ret = obj->funcs->open(obj, file_priv);
>>>> + if (ret)
>>>> + goto err_revoke;
>>>> + }
>>>> +
>>>> /*
>>>> - * Get the user-visible handle using idr. Preload and perform
>>>> - * allocation under our spinlock.
>>>> + * Get the user-visible handle using idr as the _last_ step.
>>>> + * Preload and perform allocation under our spinlock.
>>>> */
>>>> idr_preload(GFP_KERNEL);
>>>> spin_lock(&file_priv->table_lock);
>>>> -
>>>> ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
>>>> -
>>>> spin_unlock(&file_priv->table_lock);
>>>> idr_preload_end();
>>>> - mutex_unlock(&dev->object_name_lock);
>>>> if (ret < 0)
>>>> - goto err_unref;
>>>> -
>>>> - handle = ret;
>>>> + goto err_close;
>>>> - ret = drm_vma_node_allow(&obj->vma_node, file_priv);
>>>> - if (ret)
>>>> - goto err_remove;
>>>> + mutex_unlock(&dev->object_name_lock);
>>>> - if (obj->funcs->open) {
>>>> - ret = obj->funcs->open(obj, file_priv);
>>>> - if (ret)
>>>> - goto err_revoke;
>>>> - }
>>>> + *handlep = ret;
>>>> - *handlep = handle;
>>>> return 0;
>>>> +err_close:
>>>> + if (obj->funcs->close)
>>>> + obj->funcs->close(obj, file_priv);
>>>> err_revoke:
>>>> drm_vma_node_revoke(&obj->vma_node, file_priv);
>>>> -err_remove:
>>>> - spin_lock(&file_priv->table_lock);
>>>> - idr_remove(&file_priv->object_idr, handle);
>>>> - spin_unlock(&file_priv->table_lock);
>>>> -err_unref:
>>>> - drm_gem_object_handle_put_unlocked(obj);
>>>> +err_put:
>>>> + if (--obj->handle_count == 0)
>>>> + drm_gem_object_put(obj);
>>>> +
>>>> + mutex_unlock(&dev->object_name_lock);
>>>> +
>>>> return ret;
>>>> }
>>>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last
2023-02-20 10:23 ` Tvrtko Ursulin
@ 2023-02-23 9:17 ` Christian König
0 siblings, 0 replies; 7+ messages in thread
From: Christian König @ 2023-02-23 9:17 UTC (permalink / raw)
To: Tvrtko Ursulin, Christian König, dri-devel
Cc: Rob Clark, lima, Tvrtko Ursulin, nouveau, amd-gfx, Steven Price,
Noralf Trønnes, Ben Skeggs, Daniel Vetter, David Herrmann,
spice-devel, virtualization, Zack Rusin
Am 20.02.23 um 11:23 schrieb Tvrtko Ursulin:
>
> On 20/02/2023 10:01, Christian König wrote:
>> Am 20.02.23 um 10:55 schrieb Tvrtko Ursulin:
>>>
>>> Hi,
>>>
>>> On 14/02/2023 13:59, Christian König wrote:
>>>> Am 14.02.23 um 13:50 schrieb Tvrtko Ursulin:
>>>>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>>>>
>>>>> Currently drm_gem_handle_create_tail exposes the handle to userspace
>>>>> before the buffer object constructions is complete. This allowing
>>>>> of working against a partially constructed object, which may also
>>>>> be in
>>>>> the process of having its creation fail, can have a range of negative
>>>>> outcomes.
>>>>>
>>>>> A lot of those will depend on what the individual drivers are
>>>>> doing in
>>>>> their obj->funcs->open() callbacks, and also with a common failure
>>>>> mode
>>>>> being -ENOMEM from drm_vma_node_allow.
>>>>>
>>>>> We can make sure none of this can happen by allocating a handle last,
>>>>> although with a downside that more of the function now runs under the
>>>>> dev->object_name_lock.
>>>>>
>>>>> Looking into the individual drivers open() hooks, we have
>>>>> amdgpu_gem_object_open which seems like it could have a potential
>>>>> security
>>>>> issue without this change.
>>>>>
>>>>> A couple drivers like qxl_gem_object_open and vmw_gem_object_open
>>>>> implement no-op hooks so no impact for them.
>>>>>
>>>>> A bunch of other require a deeper look by individual owners to
>>>>> asses for
>>>>> impact. Those are lima_gem_object_open, nouveau_gem_object_open,
>>>>> panfrost_gem_open, radeon_gem_object_open and
>>>>> virtio_gpu_gem_object_open.
>>>>>
>>>>> Putting aside the risk assesment of the above, some common
>>>>> scenarios to
>>>>> think about are along these lines:
>>>>>
>>>>> 1)
>>>>> Userspace closes a handle by speculatively "guessing" it from a
>>>>> second
>>>>> thread.
>>>>>
>>>>> This results in an unreachable buffer object so, a memory leak.
>>>>>
>>>>> 2)
>>>>> Same as 1), but object is in the process of getting closed (failed
>>>>> creation).
>>>>>
>>>>> The second thread is then able to re-cycle the handle and
>>>>> idr_remove would
>>>>> in the first thread would then remove the handle it does not own
>>>>> from the
>>>>> idr.
>>>>>
>>>>> 3)
>>>>> Going back to the earlier per driver problem space - individual
>>>>> impact
>>>>> assesment of allowing a second thread to access and operate on a
>>>>> partially
>>>>> constructed handle / object. (Can something crash? Leak information?)
>>>>>
>>>>> In terms of identifying when the problem started I will tag some
>>>>> patches
>>>>> as references, but not all, if even any, of them actually point to a
>>>>> broken state. I am just identifying points at which more
>>>>> opportunity for
>>>>> issues to arise was added.
>>>>
>>>> Yes I've looked into this once as well, but couldn't completely
>>>> solve it for some reason.
>>>>
>>>> Give me a day or two to get this tested and all the logic swapped
>>>> back into my head again.
>>>
>>> Managed to recollect what the problem with earlier attempts was?
>>
>> Nope, that's way to long ago. I can only assume that I ran into
>> problems with the object_name_lock.
>>
>> Probably best to double check if that doesn't result in a lock
>> inversion when somebody grabs the reservation lock in their ->load()
>> callback.
>
> Hmm I don't immediately follow the connection. But I have only found
> radeon_driver_load_kms as using the load callback. Is there any
> lockdep enabled CI for that driver which could tell us if there is a
> problem there?
We don't have CI for radeon and most likely never will, that hw is just
to old. But we also have amdgpu_gem_object_open() and that looks
suspiciously like trouble.
The function makes sure that every BO is registered in the VM house
keeping functions of the drm_file and while doing so grabs a few locks.
I'm not sure what the locking order of those are.
Could be that this will work, could be that it breaks. I will ping
internally today if somebody from my team can take a look at this patch.
Regards,
Christian.
>
> Regards,
>
> Tvrtko
>
>>
>> Regards,
>> Christian.
>>
>>>
>>> Regards,
>>>
>>> Tvrtko
>>>
>>>> Christian.
>>>>
>>>>>
>>>>> References: 304eda32920b ("drm/gem: add hooks to notify driver
>>>>> when object handle is created/destroyed")
>>>>> References: ca481c9b2a3a ("drm/gem: implement vma access management")
>>>>> References: b39b5394fabc ("drm/gem: Add drm_gem_object_funcs")
>>>>> Cc: dri-devel@lists.freedesktop.org
>>>>> Cc: Rob Clark <robdclark@chromium.org>
>>>>> Cc: Ben Skeggs <bskeggs@redhat.com>
>>>>> Cc: David Herrmann <dh.herrmann@gmail.com>
>>>>> Cc: Noralf Trønnes <noralf@tronnes.org>
>>>>> Cc: David Airlie <airlied@gmail.com>
>>>>> Cc: Daniel Vetter <daniel@ffwll.ch>
>>>>> Cc: amd-gfx@lists.freedesktop.org
>>>>> Cc: lima@lists.freedesktop.org
>>>>> Cc: nouveau@lists.freedesktop.org
>>>>> Cc: Steven Price <steven.price@arm.com>
>>>>> Cc: virtualization@lists.linux-foundation.org
>>>>> Cc: spice-devel@lists.freedesktop.org
>>>>> Cc: Zack Rusin <zackr@vmware.com>
>>>>> ---
>>>>> drivers/gpu/drm/drm_gem.c | 48
>>>>> +++++++++++++++++++--------------------
>>>>> 1 file changed, 24 insertions(+), 24 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
>>>>> index aa15c52ae182..e3d897bca0f2 100644
>>>>> --- a/drivers/gpu/drm/drm_gem.c
>>>>> +++ b/drivers/gpu/drm/drm_gem.c
>>>>> @@ -356,52 +356,52 @@ drm_gem_handle_create_tail(struct drm_file
>>>>> *file_priv,
>>>>> u32 *handlep)
>>>>> {
>>>>> struct drm_device *dev = obj->dev;
>>>>> - u32 handle;
>>>>> int ret;
>>>>> WARN_ON(!mutex_is_locked(&dev->object_name_lock));
>>>>> if (obj->handle_count++ == 0)
>>>>> drm_gem_object_get(obj);
>>>>> + ret = drm_vma_node_allow(&obj->vma_node, file_priv);
>>>>> + if (ret)
>>>>> + goto err_put;
>>>>> +
>>>>> + if (obj->funcs->open) {
>>>>> + ret = obj->funcs->open(obj, file_priv);
>>>>> + if (ret)
>>>>> + goto err_revoke;
>>>>> + }
>>>>> +
>>>>> /*
>>>>> - * Get the user-visible handle using idr. Preload and perform
>>>>> - * allocation under our spinlock.
>>>>> + * Get the user-visible handle using idr as the _last_ step.
>>>>> + * Preload and perform allocation under our spinlock.
>>>>> */
>>>>> idr_preload(GFP_KERNEL);
>>>>> spin_lock(&file_priv->table_lock);
>>>>> -
>>>>> ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
>>>>> -
>>>>> spin_unlock(&file_priv->table_lock);
>>>>> idr_preload_end();
>>>>> - mutex_unlock(&dev->object_name_lock);
>>>>> if (ret < 0)
>>>>> - goto err_unref;
>>>>> -
>>>>> - handle = ret;
>>>>> + goto err_close;
>>>>> - ret = drm_vma_node_allow(&obj->vma_node, file_priv);
>>>>> - if (ret)
>>>>> - goto err_remove;
>>>>> + mutex_unlock(&dev->object_name_lock);
>>>>> - if (obj->funcs->open) {
>>>>> - ret = obj->funcs->open(obj, file_priv);
>>>>> - if (ret)
>>>>> - goto err_revoke;
>>>>> - }
>>>>> + *handlep = ret;
>>>>> - *handlep = handle;
>>>>> return 0;
>>>>> +err_close:
>>>>> + if (obj->funcs->close)
>>>>> + obj->funcs->close(obj, file_priv);
>>>>> err_revoke:
>>>>> drm_vma_node_revoke(&obj->vma_node, file_priv);
>>>>> -err_remove:
>>>>> - spin_lock(&file_priv->table_lock);
>>>>> - idr_remove(&file_priv->object_idr, handle);
>>>>> - spin_unlock(&file_priv->table_lock);
>>>>> -err_unref:
>>>>> - drm_gem_object_handle_put_unlocked(obj);
>>>>> +err_put:
>>>>> + if (--obj->handle_count == 0)
>>>>> + drm_gem_object_put(obj);
>>>>> +
>>>>> + mutex_unlock(&dev->object_name_lock);
>>>>> +
>>>>> return ret;
>>>>> }
>>>>
>>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-05-04 12:33 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-14 12:50 [Nouveau] [PATCH] drm/gem: Expose the buffer object handle to userspace last Tvrtko Ursulin
2023-02-14 13:59 ` Christian König
2023-02-20 9:55 ` Tvrtko Ursulin
2023-02-20 10:01 ` Christian König
2023-02-20 10:23 ` Tvrtko Ursulin
2023-02-23 9:17 ` Christian König
2023-02-15 9:57 ` Steven Price
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).