Author: tfaber
Date: Thu Jan 16 10:29:51 2014
New Revision: 61643
URL:
http://svn.reactos.org/svn/reactos?rev=61643&view=rev
Log:
[CDMAKE]
- When deleting a directory entry, also remove it from the hash table. This prevents use
after free in the case of a hash collision
CORE-7774 #resolve
Modified:
trunk/reactos/tools/cdmake/dirhash.c
Modified: trunk/reactos/tools/cdmake/dirhash.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cdmake/dirhash.c?rev…
==============================================================================
--- trunk/reactos/tools/cdmake/dirhash.c [iso-8859-1] (original)
+++ trunk/reactos/tools/cdmake/dirhash.c [iso-8859-1] Thu Jan 16 10:29:51 2014
@@ -10,7 +10,7 @@
{
unsigned int val = 5381;
int i = 0;
-
+
for (i = 0; name[i]; i++)
{
val = (33 * val) + name[i];
@@ -63,6 +63,19 @@
while (de && strcmp(de->normalized_name, norm))
de = de->next;
return de;
+}
+
+static void
+delete_entry_by_normname(struct target_dir_hash *dh, const char *norm)
+{
+ unsigned int hashcode;
+ struct target_dir_entry **ent;
+ hashcode = djb_hash(norm);
+ ent = &dh->buckets[hashcode % NUM_DIR_HASH_BUCKETS];
+ while (*ent && strcmp((*ent)->normalized_name, norm))
+ ent = &(*ent)->next;
+ if (*ent)
+ *ent = (*ent)->next;
}
void normalize_dirname(char *filename)
@@ -147,9 +160,9 @@
}
struct target_dir_entry *
-dir_hash_next_dir(struct target_dir_hash *dh, struct target_dir_traversal *t)
-{
- if (t->i == -1)
+dir_hash_next_dir(struct target_dir_hash *dh, struct target_dir_traversal *t)
+{
+ if (t->i == -1)
return NULL;
if (!t->it)
{
@@ -177,14 +190,16 @@
}
}
-void dir_hash_destroy_dir(struct target_dir_entry *de)
+static void
+dir_hash_destroy_dir(struct target_dir_hash *dh, struct target_dir_entry *de)
{
struct target_file *tf;
struct target_dir_entry *te;
+ unsigned int hashcode;
while ((te = de->child))
{
de->child = te->next;
- dir_hash_destroy_dir(te);
+ dir_hash_destroy_dir(dh, te);
free(te);
}
while ((tf = de->head))
@@ -194,11 +209,12 @@
free(tf->target_name);
free(tf);
}
+ delete_entry_by_normname(dh, de->normalized_name);
free(de->normalized_name);
free(de->case_name);
}
void dir_hash_destroy(struct target_dir_hash *dh)
{
- dir_hash_destroy_dir(&dh->root);
-}
+ dir_hash_destroy_dir(dh, &dh->root);
+}