Commit 598781d71119827b454fd75d46f84755bca6f0c6
Committed by
Dave Airlie
1 parent
15b63d3526
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
drm: Fix authentication kernel crash
If the master tries to authenticate a client using drm_authmagic and that client has already closed its drm file descriptor, either wilfully or because it was terminated, the call to drm_authmagic will dereference a stale pointer into kmalloc'ed memory and corrupt it. Typically this results in a hard system hang. This patch fixes that problem by removing any authentication tokens (struct drm_magic_entry) open for a file descriptor when that file descriptor is closed. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
Showing 3 changed files with 11 additions and 1 deletions Side-by-side Diff
drivers/gpu/drm/drm_auth.c
... | ... | @@ -101,7 +101,7 @@ |
101 | 101 | * Searches and unlinks the entry in drm_device::magiclist with the magic |
102 | 102 | * number hash key, while holding the drm_device::struct_mutex lock. |
103 | 103 | */ |
104 | -static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) | |
104 | +int drm_remove_magic(struct drm_master *master, drm_magic_t magic) | |
105 | 105 | { |
106 | 106 | struct drm_magic_entry *pt; |
107 | 107 | struct drm_hash_item *hash; |
... | ... | @@ -136,6 +136,8 @@ |
136 | 136 | * If there is a magic number in drm_file::magic then use it, otherwise |
137 | 137 | * searches an unique non-zero magic number and add it associating it with \p |
138 | 138 | * file_priv. |
139 | + * This ioctl needs protection by the drm_global_mutex, which protects | |
140 | + * struct drm_file::magic and struct drm_magic_entry::priv. | |
139 | 141 | */ |
140 | 142 | int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) |
141 | 143 | { |
... | ... | @@ -173,6 +175,8 @@ |
173 | 175 | * \return zero if authentication successed, or a negative number otherwise. |
174 | 176 | * |
175 | 177 | * Checks if \p file_priv is associated with the magic number passed in \arg. |
178 | + * This ioctl needs protection by the drm_global_mutex, which protects | |
179 | + * struct drm_file::magic and struct drm_magic_entry::priv. | |
176 | 180 | */ |
177 | 181 | int drm_authmagic(struct drm_device *dev, void *data, |
178 | 182 | struct drm_file *file_priv) |
drivers/gpu/drm/drm_fops.c
... | ... | @@ -487,6 +487,11 @@ |
487 | 487 | (long)old_encode_dev(file_priv->minor->device), |
488 | 488 | dev->open_count); |
489 | 489 | |
490 | + /* Release any auth tokens that might point to this file_priv, | |
491 | + (do that under the drm_global_mutex) */ | |
492 | + if (file_priv->magic) | |
493 | + (void) drm_remove_magic(file_priv->master, file_priv->magic); | |
494 | + | |
490 | 495 | /* if the master has gone away we can't do anything with the lock */ |
491 | 496 | if (file_priv->minor->master) |
492 | 497 | drm_master_release(dev, filp); |
include/drm/drmP.h
... | ... | @@ -1328,6 +1328,7 @@ |
1328 | 1328 | struct drm_file *file_priv); |
1329 | 1329 | extern int drm_authmagic(struct drm_device *dev, void *data, |
1330 | 1330 | struct drm_file *file_priv); |
1331 | +extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic); | |
1331 | 1332 | |
1332 | 1333 | /* Cache management (drm_cache.c) */ |
1333 | 1334 | void drm_clflush_pages(struct page *pages[], unsigned long num_pages); |