summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPalmer Dabbelt <palmer@rivosinc.com>2024-01-10 15:48:16 +0100
committerPalmer Dabbelt <palmer@rivosinc.com>2024-01-11 16:36:25 +0100
commit3a58275099b9cbfb9d86b85824fb3a5de796c815 (patch)
tree1bdd9984dff5134f818a4d63ac2e1dc2aa8821d7
parentMerge patch series "riscv: enable EFFICIENT_UNALIGNED_ACCESS and DCACHE_WORD_... (diff)
parentriscv: Fix relocation_hashtable size (diff)
downloadlinux-3a58275099b9cbfb9d86b85824fb3a5de796c815.tar.xz
linux-3a58275099b9cbfb9d86b85824fb3a5de796c815.zip
Merge patch series "riscv: modules: Fix module loading error handling"
Charlie Jenkins <charlie@rivosinc.com> says: When modules are loaded while there is not ample allocatable memory, there was previously not proper error handling. This series fixes a use-after-free error and a different issue that caused a non graceful exit after memory was not properly allocated. * b4-shazam-merge: riscv: Fix relocation_hashtable size riscv: Correctly free relocation hashtable on error riscv: Fix module loading free order Link: https://lore.kernel.org/r/20240104-module_loading_fix-v3-0-a71f8de6ce0f@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-rw-r--r--arch/riscv/kernel/module.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index 862834bb1d64..c9d59a5448b6 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -723,8 +723,8 @@ static int add_relocation_to_accumulate(struct module *me, int type,
if (!bucket) {
kfree(entry);
- kfree(rel_head);
kfree(rel_head->rel_entry);
+ kfree(rel_head);
return -ENOMEM;
}
@@ -747,6 +747,10 @@ initialize_relocation_hashtable(unsigned int num_relocations,
{
/* Can safely assume that bits is not greater than sizeof(long) */
unsigned long hashtable_size = roundup_pow_of_two(num_relocations);
+ /*
+ * When hashtable_size == 1, hashtable_bits == 0.
+ * This is valid because the hashing algorithm returns 0 in this case.
+ */
unsigned int hashtable_bits = ilog2(hashtable_size);
/*
@@ -760,10 +764,10 @@ initialize_relocation_hashtable(unsigned int num_relocations,
hashtable_size <<= should_double_size;
*relocation_hashtable = kmalloc_array(hashtable_size,
- sizeof(*relocation_hashtable),
+ sizeof(**relocation_hashtable),
GFP_KERNEL);
if (!*relocation_hashtable)
- return -ENOMEM;
+ return 0;
__hash_init(*relocation_hashtable, hashtable_size);
@@ -789,8 +793,8 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
hashtable_bits = initialize_relocation_hashtable(num_relocations,
&relocation_hashtable);
- if (hashtable_bits < 0)
- return hashtable_bits;
+ if (!relocation_hashtable)
+ return -ENOMEM;
INIT_LIST_HEAD(&used_buckets_list);