[Crash-utility] [PATCH v5 6/6] Refactor SYMNAME_HASH_INDEX macro to be a function

Tao Liu ltao at redhat.com
Mon Oct 11 14:13:21 UTC 2021


SYMNAME_HASH_INDEX is used as the index of symname hash table. It will
be out of range if SYMNAME_HASH_INDEX is negative. This patch avoids
the risk by changing the marco into a function, and casting and calculating
the numbers as unsigned.

Suggested-by: Lianbo Jiang <lijiang at redhat.com>
Suggested-by: Philipp Rudo <prudo at redhat.com>
Signed-off-by: Tao Liu <ltao at redhat.com>
---
 defs.h    |  2 --
 symbols.c | 31 +++++++++++++++++++++++--------
 2 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/defs.h b/defs.h
index bbdca79..8b356d5 100644
--- a/defs.h
+++ b/defs.h
@@ -2728,8 +2728,6 @@ struct downsized {
         (((vaddr) >> machdep->pageshift) % SYMVAL_HASH)
 
 #define SYMNAME_HASH (512)
-#define SYMNAME_HASH_INDEX(name) \
- ((name[0] ^ (name[strlen(name)-1] * name[strlen(name)/2])) % SYMNAME_HASH)
 
 #define PATCH_KERNEL_SYMBOLS_START  ((char *)(1))
 #define PATCH_KERNEL_SYMBOLS_STOP   ((char *)(2))
diff --git a/symbols.c b/symbols.c
index b62be1b..fc0e9f6 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1127,6 +1127,21 @@ symname_hash_init(void)
 		st->__per_cpu_end = sp->value;
 }
 
+static unsigned int
+symname_hash_index(char *name)
+{
+	unsigned int len, value;
+	unsigned char *array = (unsigned char *)name;
+
+	len = strlen(name);
+	if (!len)
+		error(FATAL, "The length of the symbol name is zero!\n");
+
+	value = array[len - 1] * array[len / 2];
+
+	return (array[0] ^ value) % SYMNAME_HASH;
+}
+
 /*
  *  Install a single static kernel symbol into the symname_hash.
  */
@@ -1134,9 +1149,9 @@ static void
 symname_hash_install(struct syment *spn)
 {
 	struct syment *sp;
-        int index;
+	unsigned int index;
 
-        index = SYMNAME_HASH_INDEX(spn->name);
+	index = symname_hash_index(spn->name);
 	spn->cnt = 1;
 
         if ((sp = st->symname_hash[index]) == NULL) 
@@ -1164,12 +1179,12 @@ static void
 mod_symname_hash_install(struct syment *spn)
 {
 	struct syment *sp, *tmp;
-	int index;
+	unsigned int index;
 
 	if (!spn)
 		return;
 
-	index = SYMNAME_HASH_INDEX(spn->name);
+	index = symname_hash_index(spn->name);
 
 	sp = st->mod_symname_hash[index];
 
@@ -1204,12 +1219,12 @@ static void
 mod_symname_hash_remove(struct syment *spn)
 {
 	struct syment *sp;
-	int index;
+	unsigned int index;
 
 	if (!spn)
 		return;
 
-	index = SYMNAME_HASH_INDEX(spn->name);
+	index = symname_hash_index(spn->name);
 
 	if (st->mod_symname_hash[index] == spn)
 		st->mod_symname_hash[index] = spn->name_hash_next;
@@ -1246,7 +1261,7 @@ symname_hash_search(struct syment *table[], char *name)
 {
 	struct syment *sp;
 
-	sp = table[SYMNAME_HASH_INDEX(name)];
+	sp = table[symname_hash_index(name)];
 
 	while (sp) {
 		if (STREQ(sp->name, name)) 
@@ -4589,7 +4604,7 @@ symbol_search(char *s)
                         return(sp);
         }
 
-	sp = st->mod_symname_hash[SYMNAME_HASH_INDEX(s)];
+	sp = st->mod_symname_hash[symname_hash_index(s)];
 	while (sp) {
 		if (skip_symbols(sp, s)) {
 			sp = sp->name_hash_next;
-- 
2.29.2




More information about the Crash-utility mailing list