diff options
author | Ilia Mirkin <[email protected]> | 2014-03-05 22:25:55 -0500 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2014-03-09 01:31:59 -0500 |
commit | 507f0230d4ca2238c818006499e21abb4c133203 (patch) | |
tree | 275952fc89d630d424006ff46d2ca70d8c0d1f7a /src/gallium/drivers/nouveau/nv50 | |
parent | 5bf90cb521d1d6f26684b1ce9d0811c636b6abb1 (diff) |
nouveau: fix fence waiting logic in screen destroy
nouveau_fence_wait has the expectation that an external entity is
holding onto the fence being waited on, not that it is merely held onto
by the current pointer. Fixes a use-after-free in nouveau_fence_wait
when used on the screen's current fence.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75279
Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Christoph Bumiller <[email protected]>
Cc: "9.2 10.0 10.1" <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/nv50')
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_screen.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index ab0d63ea5f3..e8c7fe3cc24 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -294,8 +294,15 @@ nv50_screen_destroy(struct pipe_screen *pscreen) return; if (screen->base.fence.current) { - nouveau_fence_wait(screen->base.fence.current); - nouveau_fence_ref (NULL, &screen->base.fence.current); + struct nouveau_fence *current = NULL; + + /* nouveau_fence_wait will create a new current fence, so wait on the + * _current_ one, and remove both. + */ + nouveau_fence_ref(screen->base.fence.current, ¤t); + nouveau_fence_wait(current); + nouveau_fence_ref(NULL, ¤t); + nouveau_fence_ref(NULL, &screen->base.fence.current); } if (screen->base.pushbuf) screen->base.pushbuf->user_priv = NULL; |