From 1a9e5bae109b476f9ee34975242c8938aaac4146 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 6 Jun 2006 17:46:17 +0000 Subject: Fix drm_remove_magic potential memory leak / corruption. Move drm authentication token hashing to new generic hash table implementation. --- linux-core/drm_auth.c | 75 ++++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 55 deletions(-) (limited to 'linux-core/drm_auth.c') diff --git a/linux-core/drm_auth.c b/linux-core/drm_auth.c index 591c33c1..2857c943 100644 --- a/linux-core/drm_auth.c +++ b/linux-core/drm_auth.c @@ -35,20 +35,6 @@ #include "drmP.h" -/** - * Generate a hash key from a magic. - * - * \param magic magic. - * \return hash key. - * - * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be - * a power of 2. - */ -static int drm_hash_magic(drm_magic_t magic) -{ - return magic & (DRM_HASH_SIZE - 1); -} - /** * Find the file with the given magic number. * @@ -63,15 +49,13 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) { drm_file_t *retval = NULL; drm_magic_entry_t *pt; - int hash = drm_hash_magic(magic); + drm_hash_item_t *hash; - down(&dev->struct_sem); - for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { - if (pt->magic == magic) { - retval = pt->priv; - break; - } - } + down(&dev->struct_sem); + if (!drm_ht_find_item(&dev->magiclist, (unsigned long) magic, &hash)) { + pt = list_entry(hash, drm_magic_entry_t, hash_item); + retval = pt->priv; + } up(&dev->struct_sem); return retval; } @@ -90,28 +74,19 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) { - int hash; drm_magic_entry_t *entry; DRM_DEBUG("%d\n", magic); - hash = drm_hash_magic(magic); entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); if (!entry) return -ENOMEM; memset(entry, 0, sizeof(*entry)); - entry->magic = magic; entry->priv = priv; - entry->next = NULL; - - down(&dev->struct_sem); - if (dev->magiclist[hash].tail) { - dev->magiclist[hash].tail->next = entry; - dev->magiclist[hash].tail = entry; - } else { - dev->magiclist[hash].head = entry; - dev->magiclist[hash].tail = entry; - } + entry->hash_item.key = (unsigned long) magic; + down(&dev->struct_sem); + drm_ht_insert_item(&dev->magiclist, &entry->hash_item); + list_add_tail(&entry->head, &dev->magicfree); up(&dev->struct_sem); return 0; @@ -128,34 +103,24 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, */ static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) { - drm_magic_entry_t *prev = NULL; drm_magic_entry_t *pt; - int hash; + drm_hash_item_t *hash; DRM_DEBUG("%d\n", magic); - hash = drm_hash_magic(magic); down(&dev->struct_sem); - for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { - if (pt->magic == magic) { - if (dev->magiclist[hash].head == pt) { - dev->magiclist[hash].head = pt->next; - } - if (dev->magiclist[hash].tail == pt) { - dev->magiclist[hash].tail = prev; - } - if (prev) { - prev->next = pt->next; - } - up(&dev->struct_sem); - return 0; - } - } - up(&dev->struct_sem); + if (drm_ht_find_item(&dev->magiclist, (unsigned long) magic, &hash)) { + up(&dev->struct_sem); + return -EINVAL; + } + pt = list_entry(hash, drm_magic_entry_t, hash_item); + drm_ht_remove_item(&dev->magiclist, hash); + list_del(&pt->head); + up(&dev->struct_sem); drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); - return -EINVAL; + return 0; } /** -- cgit v1.2.3