Unverified Commit 3a582750 authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

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: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parents 17f2c308 a35551c7
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -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);