Commit 598781d71119827b454fd75d46f84755bca6f0c6

Authored by Thomas Hellstrom
Committed by Dave Airlie
1 parent 15b63d3526

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);
... ... @@ -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);