diff options
author | Thomas Hellstrom <thomas@tungstengraphics.com> | 2006-08-07 08:22:10 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2006-09-21 15:32:31 -0400 |
commit | 8669cbc5e651bf4effa20e8c244a5a7d67da6fe9 (patch) | |
tree | a97ac359c8041bc39efc0f32cac26772a43a0736 /drivers/char/drm/drm_auth.c | |
parent | 3d45dbd611d1441d667b06acced9fbad3c8fcb1b (diff) |
drm: move drm authentication to new generic hash table.
Fix drm_remove_magic potential memory leak / corruption. Move drm
authentication token hashing to new generic hash table implementation.
Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm/drm_auth.c')
-rw-r--r-- | drivers/char/drm/drm_auth.c | 62 |
1 files changed, 14 insertions, 48 deletions
diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c index 2a37586a7ee8..40cd262ca9e1 100644 --- a/drivers/char/drm/drm_auth.c +++ b/drivers/char/drm/drm_auth.c | |||
@@ -36,20 +36,6 @@ | |||
36 | #include "drmP.h" | 36 | #include "drmP.h" |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * Generate a hash key from a magic. | ||
40 | * | ||
41 | * \param magic magic. | ||
42 | * \return hash key. | ||
43 | * | ||
44 | * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be | ||
45 | * a power of 2. | ||
46 | */ | ||
47 | static int drm_hash_magic(drm_magic_t magic) | ||
48 | { | ||
49 | return magic & (DRM_HASH_SIZE - 1); | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * Find the file with the given magic number. | 39 | * Find the file with the given magic number. |
54 | * | 40 | * |
55 | * \param dev DRM device. | 41 | * \param dev DRM device. |
@@ -63,14 +49,12 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) | |||
63 | { | 49 | { |
64 | drm_file_t *retval = NULL; | 50 | drm_file_t *retval = NULL; |
65 | drm_magic_entry_t *pt; | 51 | drm_magic_entry_t *pt; |
66 | int hash = drm_hash_magic(magic); | 52 | drm_hash_item_t *hash; |
67 | 53 | ||
68 | mutex_lock(&dev->struct_mutex); | 54 | mutex_lock(&dev->struct_mutex); |
69 | for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { | 55 | if (!drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { |
70 | if (pt->magic == magic) { | 56 | pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item); |
71 | retval = pt->priv; | 57 | retval = pt->priv; |
72 | break; | ||
73 | } | ||
74 | } | 58 | } |
75 | mutex_unlock(&dev->struct_mutex); | 59 | mutex_unlock(&dev->struct_mutex); |
76 | return retval; | 60 | return retval; |
@@ -90,28 +74,20 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) | |||
90 | static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, | 74 | static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, |
91 | drm_magic_t magic) | 75 | drm_magic_t magic) |
92 | { | 76 | { |
93 | int hash; | ||
94 | drm_magic_entry_t *entry; | 77 | drm_magic_entry_t *entry; |
95 | 78 | ||
96 | DRM_DEBUG("%d\n", magic); | 79 | DRM_DEBUG("%d\n", magic); |
97 | 80 | ||
98 | hash = drm_hash_magic(magic); | ||
99 | entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); | 81 | entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); |
100 | if (!entry) | 82 | if (!entry) |
101 | return -ENOMEM; | 83 | return -ENOMEM; |
102 | memset(entry, 0, sizeof(*entry)); | 84 | memset(entry, 0, sizeof(*entry)); |
103 | entry->magic = magic; | ||
104 | entry->priv = priv; | 85 | entry->priv = priv; |
105 | entry->next = NULL; | ||
106 | 86 | ||
87 | entry->hash_item.key = (unsigned long)magic; | ||
107 | mutex_lock(&dev->struct_mutex); | 88 | mutex_lock(&dev->struct_mutex); |
108 | if (dev->magiclist[hash].tail) { | 89 | drm_ht_insert_item(&dev->magiclist, &entry->hash_item); |
109 | dev->magiclist[hash].tail->next = entry; | 90 | list_add_tail(&entry->head, &dev->magicfree); |
110 | dev->magiclist[hash].tail = entry; | ||
111 | } else { | ||
112 | dev->magiclist[hash].head = entry; | ||
113 | dev->magiclist[hash].tail = entry; | ||
114 | } | ||
115 | mutex_unlock(&dev->struct_mutex); | 91 | mutex_unlock(&dev->struct_mutex); |
116 | 92 | ||
117 | return 0; | 93 | return 0; |
@@ -128,29 +104,19 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, | |||
128 | */ | 104 | */ |
129 | static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) | 105 | static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) |
130 | { | 106 | { |
131 | drm_magic_entry_t *prev = NULL; | ||
132 | drm_magic_entry_t *pt; | 107 | drm_magic_entry_t *pt; |
133 | int hash; | 108 | drm_hash_item_t *hash; |
134 | 109 | ||
135 | DRM_DEBUG("%d\n", magic); | 110 | DRM_DEBUG("%d\n", magic); |
136 | hash = drm_hash_magic(magic); | ||
137 | 111 | ||
138 | mutex_lock(&dev->struct_mutex); | 112 | mutex_lock(&dev->struct_mutex); |
139 | for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { | 113 | if (drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { |
140 | if (pt->magic == magic) { | 114 | mutex_unlock(&dev->struct_mutex); |
141 | if (dev->magiclist[hash].head == pt) { | 115 | return -EINVAL; |
142 | dev->magiclist[hash].head = pt->next; | ||
143 | } | ||
144 | if (dev->magiclist[hash].tail == pt) { | ||
145 | dev->magiclist[hash].tail = prev; | ||
146 | } | ||
147 | if (prev) { | ||
148 | prev->next = pt->next; | ||
149 | } | ||
150 | mutex_unlock(&dev->struct_mutex); | ||
151 | return 0; | ||
152 | } | ||
153 | } | 116 | } |
117 | pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item); | ||
118 | drm_ht_remove_item(&dev->magiclist, hash); | ||
119 | list_del(&pt->head); | ||
154 | mutex_unlock(&dev->struct_mutex); | 120 | mutex_unlock(&dev->struct_mutex); |
155 | 121 | ||
156 | drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); | 122 | drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); |