diff options
Diffstat (limited to 'kernel/module/main.c')
| -rw-r--r-- | kernel/module/main.c | 1091 | 
1 files changed, 612 insertions, 479 deletions
diff --git a/kernel/module/main.c b/kernel/module/main.c index d3be89de706d..4e2cf784cf8c 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -2,6 +2,7 @@  /*   * Copyright (C) 2002 Richard Henderson   * Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM. + * Copyright (C) 2023 Luis Chamberlain <mcgrof@kernel.org>   */  #define INCLUDE_VERMAGIC @@ -55,6 +56,7 @@  #include <linux/dynamic_debug.h>  #include <linux/audit.h>  #include <linux/cfi.h> +#include <linux/debugfs.h>  #include <uapi/linux/module.h>  #include "internal.h" @@ -80,12 +82,6 @@ struct mod_tree_root mod_tree __cacheline_aligned = {  	.addr_min = -1UL,  }; -#ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC -struct mod_tree_root mod_data_tree __cacheline_aligned = { -	.addr_min = -1UL, -}; -#endif -  struct symsearch {  	const struct kernel_symbol *start, *stop;  	const s32 *crcs; @@ -93,14 +89,24 @@ struct symsearch {  };  /* - * Bounds of module text, for speeding up __module_address. + * Bounds of module memory, for speeding up __module_address.   * Protected by module_mutex.   */ -static void __mod_update_bounds(void *base, unsigned int size, struct mod_tree_root *tree) +static void __mod_update_bounds(enum mod_mem_type type __maybe_unused, void *base, +				unsigned int size, struct mod_tree_root *tree)  {  	unsigned long min = (unsigned long)base;  	unsigned long max = min + size; +#ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC +	if (mod_mem_type_is_core_data(type)) { +		if (min < tree->data_addr_min) +			tree->data_addr_min = min; +		if (max > tree->data_addr_max) +			tree->data_addr_max = max; +		return; +	} +#endif  	if (min < tree->addr_min)  		tree->addr_min = min;  	if (max > tree->addr_max) @@ -109,12 +115,12 @@ static void __mod_update_bounds(void *base, unsigned int size, struct mod_tree_r  static void mod_update_bounds(struct module *mod)  { -	__mod_update_bounds(mod->core_layout.base, mod->core_layout.size, &mod_tree); -	if (mod->init_layout.size) -		__mod_update_bounds(mod->init_layout.base, mod->init_layout.size, &mod_tree); -#ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC -	__mod_update_bounds(mod->data_layout.base, mod->data_layout.size, &mod_data_tree); -#endif +	for_each_mod_mem_type(type) { +		struct module_memory *mod_mem = &mod->mem[type]; + +		if (mod_mem->size) +			__mod_update_bounds(type, mod_mem->base, mod_mem->size, &mod_tree); +	}  }  /* Block module loading/unloading? */ @@ -559,10 +565,8 @@ static int already_uses(struct module *a, struct module *b)  	struct module_use *use;  	list_for_each_entry(use, &b->source_list, source_list) { -		if (use->source == a) { -			pr_debug("%s uses %s!\n", a->name, b->name); +		if (use->source == a)  			return 1; -		}  	}  	pr_debug("%s does not use %s!\n", a->name, b->name);  	return 0; @@ -926,7 +930,13 @@ struct module_attribute module_uevent =  static ssize_t show_coresize(struct module_attribute *mattr,  			     struct module_kobject *mk, char *buffer)  { -	return sprintf(buffer, "%u\n", mk->mod->core_layout.size); +	unsigned int size = mk->mod->mem[MOD_TEXT].size; + +	if (!IS_ENABLED(CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC)) { +		for_class_mod_mem_type(type, core_data) +			size += mk->mod->mem[type].size; +	} +	return sprintf(buffer, "%u\n", size);  }  static struct module_attribute modinfo_coresize = @@ -936,7 +946,11 @@ static struct module_attribute modinfo_coresize =  static ssize_t show_datasize(struct module_attribute *mattr,  			     struct module_kobject *mk, char *buffer)  { -	return sprintf(buffer, "%u\n", mk->mod->data_layout.size); +	unsigned int size = 0; + +	for_class_mod_mem_type(type, core_data) +		size += mk->mod->mem[type].size; +	return sprintf(buffer, "%u\n", size);  }  static struct module_attribute modinfo_datasize = @@ -946,7 +960,11 @@ static struct module_attribute modinfo_datasize =  static ssize_t show_initsize(struct module_attribute *mattr,  			     struct module_kobject *mk, char *buffer)  { -	return sprintf(buffer, "%u\n", mk->mod->init_layout.size); +	unsigned int size = 0; + +	for_class_mod_mem_type(type, init) +		size += mk->mod->mem[type].size; +	return sprintf(buffer, "%u\n", size);  }  static struct module_attribute modinfo_initsize = @@ -998,9 +1016,55 @@ int try_to_force_load(struct module *mod, const char *reason)  #endif  } -static char *get_modinfo(const struct load_info *info, const char *tag); +/* Parse tag=value strings from .modinfo section */ +char *module_next_tag_pair(char *string, unsigned long *secsize) +{ +	/* Skip non-zero chars */ +	while (string[0]) { +		string++; +		if ((*secsize)-- <= 1) +			return NULL; +	} + +	/* Skip any zero padding. */ +	while (!string[0]) { +		string++; +		if ((*secsize)-- <= 1) +			return NULL; +	} +	return string; +} +  static char *get_next_modinfo(const struct load_info *info, const char *tag, -			      char *prev); +			      char *prev) +{ +	char *p; +	unsigned int taglen = strlen(tag); +	Elf_Shdr *infosec = &info->sechdrs[info->index.info]; +	unsigned long size = infosec->sh_size; + +	/* +	 * get_modinfo() calls made before rewrite_section_headers() +	 * must use sh_offset, as sh_addr isn't set! +	 */ +	char *modinfo = (char *)info->hdr + infosec->sh_offset; + +	if (prev) { +		size -= prev - modinfo; +		modinfo = module_next_tag_pair(prev, &size); +	} + +	for (p = modinfo; p; p = module_next_tag_pair(p, &size)) { +		if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') +			return p + taglen + 1; +	} +	return NULL; +} + +static char *get_modinfo(const struct load_info *info, const char *tag) +{ +	return get_next_modinfo(info, tag, NULL); +}  static int verify_namespace_is_imported(const struct load_info *info,  					const struct kernel_symbol *sym, @@ -1011,12 +1075,9 @@ static int verify_namespace_is_imported(const struct load_info *info,  	namespace = kernel_symbol_namespace(sym);  	if (namespace && namespace[0]) { -		imported_namespace = get_modinfo(info, "import_ns"); -		while (imported_namespace) { +		for_each_modinfo_entry(imported_namespace, info, "import_ns") {  			if (strcmp(namespace, imported_namespace) == 0)  				return 0; -			imported_namespace = get_next_modinfo( -				info, "import_ns", imported_namespace);  		}  #ifdef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS  		pr_warn( @@ -1143,6 +1204,46 @@ void __weak module_arch_freeing_init(struct module *mod)  {  } +static bool mod_mem_use_vmalloc(enum mod_mem_type type) +{ +	return IS_ENABLED(CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC) && +		mod_mem_type_is_core_data(type); +} + +static void *module_memory_alloc(unsigned int size, enum mod_mem_type type) +{ +	if (mod_mem_use_vmalloc(type)) +		return vzalloc(size); +	return module_alloc(size); +} + +static void module_memory_free(void *ptr, enum mod_mem_type type) +{ +	if (mod_mem_use_vmalloc(type)) +		vfree(ptr); +	else +		module_memfree(ptr); +} + +static void free_mod_mem(struct module *mod) +{ +	for_each_mod_mem_type(type) { +		struct module_memory *mod_mem = &mod->mem[type]; + +		if (type == MOD_DATA) +			continue; + +		/* Free lock-classes; relies on the preceding sync_rcu(). */ +		lockdep_free_key_range(mod_mem->base, mod_mem->size); +		if (mod_mem->size) +			module_memory_free(mod_mem->base, type); +	} + +	/* MOD_DATA hosts mod, so free it at last */ +	lockdep_free_key_range(mod->mem[MOD_DATA].base, mod->mem[MOD_DATA].size); +	module_memory_free(mod->mem[MOD_DATA].base, MOD_DATA); +} +  /* Free a module, remove from lists, etc. */  static void free_module(struct module *mod)  { @@ -1158,9 +1259,6 @@ static void free_module(struct module *mod)  	mod->state = MODULE_STATE_UNFORMED;  	mutex_unlock(&module_mutex); -	/* Remove dynamic debug info */ -	ddebug_remove_module(mod->name); -  	/* Arch-specific cleanup. */  	module_arch_cleanup(mod); @@ -1189,18 +1287,10 @@ static void free_module(struct module *mod)  	/* This may be empty, but that's OK */  	module_arch_freeing_init(mod); -	module_memfree(mod->init_layout.base);  	kfree(mod->args);  	percpu_modfree(mod); -	/* Free lock-classes; relies on the preceding sync_rcu(). */ -	lockdep_free_key_range(mod->data_layout.base, mod->data_layout.size); - -	/* Finally, free the core (containing the module structure) */ -	module_memfree(mod->core_layout.base); -#ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC -	vfree(mod->data_layout.base); -#endif +	free_mod_mem(mod);  }  void *__symbol_get(const char *symbol) @@ -1303,8 +1393,8 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)  		case SHN_ABS:  			/* Don't need to do anything */ -			pr_debug("Absolute symbol: 0x%08lx\n", -			       (long)sym[i].st_value); +			pr_debug("Absolute symbol: 0x%08lx %s\n", +				 (long)sym[i].st_value, name);  			break;  		case SHN_LIVEPATCH: @@ -1387,16 +1477,18 @@ unsigned int __weak arch_mod_section_prepend(struct module *mod,  	return 0;  } -/* Update size with this section: return offset. */ -long module_get_offset(struct module *mod, unsigned int *size, -		       Elf_Shdr *sechdr, unsigned int section) +long module_get_offset_and_type(struct module *mod, enum mod_mem_type type, +				Elf_Shdr *sechdr, unsigned int section)  { -	long ret; +	long offset; +	long mask = ((unsigned long)(type) & SH_ENTSIZE_TYPE_MASK) << SH_ENTSIZE_TYPE_SHIFT; -	*size += arch_mod_section_prepend(mod, section); -	ret = ALIGN(*size, sechdr->sh_addralign ?: 1); -	*size = ret + sechdr->sh_size; -	return ret; +	mod->mem[type].size += arch_mod_section_prepend(mod, section); +	offset = ALIGN(mod->mem[type].size, sechdr->sh_addralign ?: 1); +	mod->mem[type].size = offset + sechdr->sh_size; + +	WARN_ON_ONCE(offset & mask); +	return offset | mask;  }  static bool module_init_layout_section(const char *sname) @@ -1408,15 +1500,11 @@ static bool module_init_layout_section(const char *sname)  	return module_init_section(sname);  } -/* - * Lay out the SHF_ALLOC sections in a way not dissimilar to how ld - * might -- code, read-only data, read-write data, small data.  Tally - * sizes, and place the offsets into sh_entsize fields: high bit means it - * belongs in init. - */ -static void layout_sections(struct module *mod, struct load_info *info) +static void __layout_sections(struct module *mod, struct load_info *info, bool is_init)  { -	static unsigned long const masks[][2] = { +	unsigned int m, i; + +	static const unsigned long masks[][2] = {  		/*  		 * NOTE: all executable code must be the first section  		 * in this array; otherwise modify the text_size @@ -1428,85 +1516,64 @@ static void layout_sections(struct module *mod, struct load_info *info)  		{ SHF_WRITE | SHF_ALLOC, ARCH_SHF_SMALL },  		{ ARCH_SHF_SMALL | SHF_ALLOC, 0 }  	}; -	unsigned int m, i; - -	for (i = 0; i < info->hdr->e_shnum; i++) -		info->sechdrs[i].sh_entsize = ~0UL; +	static const int core_m_to_mem_type[] = { +		MOD_TEXT, +		MOD_RODATA, +		MOD_RO_AFTER_INIT, +		MOD_DATA, +		MOD_DATA, +	}; +	static const int init_m_to_mem_type[] = { +		MOD_INIT_TEXT, +		MOD_INIT_RODATA, +		MOD_INVALID, +		MOD_INIT_DATA, +		MOD_INIT_DATA, +	}; -	pr_debug("Core section allocation order:\n");  	for (m = 0; m < ARRAY_SIZE(masks); ++m) { +		enum mod_mem_type type = is_init ? init_m_to_mem_type[m] : core_m_to_mem_type[m]; +  		for (i = 0; i < info->hdr->e_shnum; ++i) {  			Elf_Shdr *s = &info->sechdrs[i];  			const char *sname = info->secstrings + s->sh_name; -			unsigned int *sizep;  			if ((s->sh_flags & masks[m][0]) != masks[m][0]  			    || (s->sh_flags & masks[m][1])  			    || s->sh_entsize != ~0UL -			    || module_init_layout_section(sname)) +			    || is_init != module_init_layout_section(sname))  				continue; -			sizep = m ? &mod->data_layout.size : &mod->core_layout.size; -			s->sh_entsize = module_get_offset(mod, sizep, s, i); -			pr_debug("\t%s\n", sname); -		} -		switch (m) { -		case 0: /* executable */ -			mod->core_layout.size = strict_align(mod->core_layout.size); -			mod->core_layout.text_size = mod->core_layout.size; -			break; -		case 1: /* RO: text and ro-data */ -			mod->data_layout.size = strict_align(mod->data_layout.size); -			mod->data_layout.ro_size = mod->data_layout.size; -			break; -		case 2: /* RO after init */ -			mod->data_layout.size = strict_align(mod->data_layout.size); -			mod->data_layout.ro_after_init_size = mod->data_layout.size; -			break; -		case 4: /* whole core */ -			mod->data_layout.size = strict_align(mod->data_layout.size); -			break; -		} -	} - -	pr_debug("Init section allocation order:\n"); -	for (m = 0; m < ARRAY_SIZE(masks); ++m) { -		for (i = 0; i < info->hdr->e_shnum; ++i) { -			Elf_Shdr *s = &info->sechdrs[i]; -			const char *sname = info->secstrings + s->sh_name; -			if ((s->sh_flags & masks[m][0]) != masks[m][0] -			    || (s->sh_flags & masks[m][1]) -			    || s->sh_entsize != ~0UL -			    || !module_init_layout_section(sname)) +			if (WARN_ON_ONCE(type == MOD_INVALID))  				continue; -			s->sh_entsize = (module_get_offset(mod, &mod->init_layout.size, s, i) -					 | INIT_OFFSET_MASK); + +			s->sh_entsize = module_get_offset_and_type(mod, type, s, i);  			pr_debug("\t%s\n", sname);  		} -		switch (m) { -		case 0: /* executable */ -			mod->init_layout.size = strict_align(mod->init_layout.size); -			mod->init_layout.text_size = mod->init_layout.size; -			break; -		case 1: /* RO: text and ro-data */ -			mod->init_layout.size = strict_align(mod->init_layout.size); -			mod->init_layout.ro_size = mod->init_layout.size; -			break; -		case 2: -			/* -			 * RO after init doesn't apply to init_layout (only -			 * core_layout), so it just takes the value of ro_size. -			 */ -			mod->init_layout.ro_after_init_size = mod->init_layout.ro_size; -			break; -		case 4: /* whole init */ -			mod->init_layout.size = strict_align(mod->init_layout.size); -			break; -		}  	}  } -static void set_license(struct module *mod, const char *license) +/* + * Lay out the SHF_ALLOC sections in a way not dissimilar to how ld + * might -- code, read-only data, read-write data, small data.  Tally + * sizes, and place the offsets into sh_entsize fields: high bit means it + * belongs in init. + */ +static void layout_sections(struct module *mod, struct load_info *info) +{ +	unsigned int i; + +	for (i = 0; i < info->hdr->e_shnum; i++) +		info->sechdrs[i].sh_entsize = ~0UL; + +	pr_debug("Core section allocation order for %s:\n", mod->name); +	__layout_sections(mod, info, false); + +	pr_debug("Init section allocation order for %s:\n", mod->name); +	__layout_sections(mod, info, true); +} + +static void module_license_taint_check(struct module *mod, const char *license)  {  	if (!license)  		license = "unspecified"; @@ -1520,56 +1587,6 @@ static void set_license(struct module *mod, const char *license)  	}  } -/* Parse tag=value strings from .modinfo section */ -static char *next_string(char *string, unsigned long *secsize) -{ -	/* Skip non-zero chars */ -	while (string[0]) { -		string++; -		if ((*secsize)-- <= 1) -			return NULL; -	} - -	/* Skip any zero padding. */ -	while (!string[0]) { -		string++; -		if ((*secsize)-- <= 1) -			return NULL; -	} -	return string; -} - -static char *get_next_modinfo(const struct load_info *info, const char *tag, -			      char *prev) -{ -	char *p; -	unsigned int taglen = strlen(tag); -	Elf_Shdr *infosec = &info->sechdrs[info->index.info]; -	unsigned long size = infosec->sh_size; - -	/* -	 * get_modinfo() calls made before rewrite_section_headers() -	 * must use sh_offset, as sh_addr isn't set! -	 */ -	char *modinfo = (char *)info->hdr + infosec->sh_offset; - -	if (prev) { -		size -= prev - modinfo; -		modinfo = next_string(prev, &size); -	} - -	for (p = modinfo; p; p = next_string(p, &size)) { -		if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') -			return p + taglen + 1; -	} -	return NULL; -} - -static char *get_modinfo(const struct load_info *info, const char *tag) -{ -	return get_next_modinfo(info, tag, NULL); -} -  static void setup_modinfo(struct module *mod, struct load_info *info)  {  	struct module_attribute *attr; @@ -1592,19 +1609,6 @@ static void free_modinfo(struct module *mod)  	}  } -static void dynamic_debug_setup(struct module *mod, struct _ddebug_info *dyndbg) -{ -	if (!dyndbg->num_descs) -		return; -	ddebug_add_module(dyndbg, mod->name); -} - -static void dynamic_debug_remove(struct module *mod, struct _ddebug_info *dyndbg) -{ -	if (dyndbg->num_descs) -		ddebug_remove_module(mod->name); -} -  void * __weak module_alloc(unsigned long size)  {  	return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END, @@ -1642,16 +1646,33 @@ static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr)  }  /* - * Sanity checks against invalid binaries, wrong arch, weird elf version. + * Check userspace passed ELF module against our expectations, and cache + * useful variables for further processing as we go.   * - * Also do basic validity checks against section offsets and sizes, the + * This does basic validity checks against section offsets and sizes, the   * section name string table, and the indices used for it (sh_name). + * + * As a last step, since we're already checking the ELF sections we cache + * useful variables which will be used later for our convenience: + * + * 	o pointers to section headers + * 	o cache the modinfo symbol section + * 	o cache the string symbol section + * 	o cache the module section + * + * As a last step we set info->mod to the temporary copy of the module in + * info->hdr. The final one will be allocated in move_module(). Any + * modifications we make to our copy of the module will be carried over + * to the final minted module.   */ -static int elf_validity_check(struct load_info *info) +static int elf_validity_cache_copy(struct load_info *info, int flags)  {  	unsigned int i;  	Elf_Shdr *shdr, *strhdr;  	int err; +	unsigned int num_mod_secs = 0, mod_idx; +	unsigned int num_info_secs = 0, info_idx; +	unsigned int num_sym_secs = 0, sym_idx;  	if (info->len < sizeof(*(info->hdr))) {  		pr_err("Invalid ELF header len %lu\n", info->len); @@ -1755,6 +1776,8 @@ static int elf_validity_check(struct load_info *info)  				       info->hdr->e_shnum);  				goto no_exec;  			} +			num_sym_secs++; +			sym_idx = i;  			fallthrough;  		default:  			err = validate_section_offset(info, shdr); @@ -1763,6 +1786,15 @@ static int elf_validity_check(struct load_info *info)  					i, shdr->sh_type);  				return err;  			} +			if (strcmp(info->secstrings + shdr->sh_name, +				   ".gnu.linkonce.this_module") == 0) { +				num_mod_secs++; +				mod_idx = i; +			} else if (strcmp(info->secstrings + shdr->sh_name, +				   ".modinfo") == 0) { +				num_info_secs++; +				info_idx = i; +			}  			if (shdr->sh_flags & SHF_ALLOC) {  				if (shdr->sh_name >= strhdr->sh_size) { @@ -1775,6 +1807,91 @@ static int elf_validity_check(struct load_info *info)  		}  	} +	if (num_info_secs > 1) { +		pr_err("Only one .modinfo section must exist.\n"); +		goto no_exec; +	} else if (num_info_secs == 1) { +		/* Try to find a name early so we can log errors with a module name */ +		info->index.info = info_idx; +		info->name = get_modinfo(info, "name"); +	} + +	if (num_sym_secs != 1) { +		pr_warn("%s: module has no symbols (stripped?)\n", +			info->name ?: "(missing .modinfo section or name field)"); +		goto no_exec; +	} + +	/* Sets internal symbols and strings. */ +	info->index.sym = sym_idx; +	shdr = &info->sechdrs[sym_idx]; +	info->index.str = shdr->sh_link; +	info->strtab = (char *)info->hdr + info->sechdrs[info->index.str].sh_offset; + +	/* +	 * The ".gnu.linkonce.this_module" ELF section is special. It is +	 * what modpost uses to refer to __this_module and let's use rely +	 * on THIS_MODULE to point to &__this_module properly. The kernel's +	 * modpost declares it on each modules's *.mod.c file. If the struct +	 * module of the kernel changes a full kernel rebuild is required. +	 * +	 * We have a few expectaions for this special section, the following +	 * code validates all this for us: +	 * +	 *   o Only one section must exist +	 *   o We expect the kernel to always have to allocate it: SHF_ALLOC +	 *   o The section size must match the kernel's run time's struct module +	 *     size +	 */ +	if (num_mod_secs != 1) { +		pr_err("module %s: Only one .gnu.linkonce.this_module section must exist.\n", +		       info->name ?: "(missing .modinfo section or name field)"); +		goto no_exec; +	} + +	shdr = &info->sechdrs[mod_idx]; + +	/* +	 * This is already implied on the switch above, however let's be +	 * pedantic about it. +	 */ +	if (shdr->sh_type == SHT_NOBITS) { +		pr_err("module %s: .gnu.linkonce.this_module section must have a size set\n", +		       info->name ?: "(missing .modinfo section or name field)"); +		goto no_exec; +	} + +	if (!(shdr->sh_flags & SHF_ALLOC)) { +		pr_err("module %s: .gnu.linkonce.this_module must occupy memory during process execution\n", +		       info->name ?: "(missing .modinfo section or name field)"); +		goto no_exec; +	} + +	if (shdr->sh_size != sizeof(struct module)) { +		pr_err("module %s: .gnu.linkonce.this_module section size must match the kernel's built struct module size at run time\n", +		       info->name ?: "(missing .modinfo section or name field)"); +		goto no_exec; +	} + +	info->index.mod = mod_idx; + +	/* This is temporary: point mod into copy of data. */ +	info->mod = (void *)info->hdr + shdr->sh_offset; + +	/* +	 * If we didn't load the .modinfo 'name' field earlier, fall back to +	 * on-disk struct mod 'name' field. +	 */ +	if (!info->name) +		info->name = info->mod->name; + +	if (flags & MODULE_INIT_IGNORE_MODVERSIONS) +		info->index.vers = 0; /* Pretend no __versions section! */ +	else +		info->index.vers = find_sec(info, "__versions"); + +	info->index.pcpu = find_pcpusec(info); +  	return 0;  no_exec: @@ -1804,12 +1921,8 @@ static int check_modinfo_livepatch(struct module *mod, struct load_info *info)  		/* Nothing more to do */  		return 0; -	if (set_livepatch_module(mod)) { -		add_taint_module(mod, TAINT_LIVEPATCH, LOCKDEP_STILL_OK); -		pr_notice_once("%s: tainting kernel with TAINT_LIVEPATCH\n", -				mod->name); +	if (set_livepatch_module(mod))  		return 0; -	}  	pr_err("%s: module is marked as livepatch module, but livepatch support is disabled",  	       mod->name); @@ -1892,63 +2005,71 @@ static int rewrite_section_headers(struct load_info *info, int flags)  }  /* - * Set up our basic convenience variables (pointers to section headers, - * search for module section index etc), and do some basic section - * verification. - * - * Set info->mod to the temporary copy of the module in info->hdr. The final one - * will be allocated in move_module(). - */ -static int setup_load_info(struct load_info *info, int flags) + * These calls taint the kernel depending certain module circumstances */ +static void module_augment_kernel_taints(struct module *mod, struct load_info *info)  { -	unsigned int i; +	int prev_taint = test_taint(TAINT_PROPRIETARY_MODULE); -	/* Try to find a name early so we can log errors with a module name */ -	info->index.info = find_sec(info, ".modinfo"); -	if (info->index.info) -		info->name = get_modinfo(info, "name"); +	if (!get_modinfo(info, "intree")) { +		if (!test_taint(TAINT_OOT_MODULE)) +			pr_warn("%s: loading out-of-tree module taints kernel.\n", +				mod->name); +		add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); +	} -	/* Find internal symbols and strings. */ -	for (i = 1; i < info->hdr->e_shnum; i++) { -		if (info->sechdrs[i].sh_type == SHT_SYMTAB) { -			info->index.sym = i; -			info->index.str = info->sechdrs[i].sh_link; -			info->strtab = (char *)info->hdr -				+ info->sechdrs[info->index.str].sh_offset; -			break; -		} +	check_modinfo_retpoline(mod, info); + +	if (get_modinfo(info, "staging")) { +		add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK); +		pr_warn("%s: module is from the staging directory, the quality " +			"is unknown, you have been warned.\n", mod->name);  	} -	if (info->index.sym == 0) { -		pr_warn("%s: module has no symbols (stripped?)\n", -			info->name ?: "(missing .modinfo section or name field)"); -		return -ENOEXEC; +	if (is_livepatch_module(mod)) { +		add_taint_module(mod, TAINT_LIVEPATCH, LOCKDEP_STILL_OK); +		pr_notice_once("%s: tainting kernel with TAINT_LIVEPATCH\n", +				mod->name);  	} -	info->index.mod = find_sec(info, ".gnu.linkonce.this_module"); -	if (!info->index.mod) { -		pr_warn("%s: No module found in object\n", -			info->name ?: "(missing .modinfo section or name field)"); -		return -ENOEXEC; +	module_license_taint_check(mod, get_modinfo(info, "license")); + +	if (get_modinfo(info, "test")) { +		if (!test_taint(TAINT_TEST)) +			pr_warn("%s: loading test module taints kernel.\n", +				mod->name); +		add_taint_module(mod, TAINT_TEST, LOCKDEP_STILL_OK);  	} -	/* This is temporary: point mod into copy of data. */ -	info->mod = (void *)info->hdr + info->sechdrs[info->index.mod].sh_offset; +#ifdef CONFIG_MODULE_SIG +	mod->sig_ok = info->sig_ok; +	if (!mod->sig_ok) { +		pr_notice_once("%s: module verification failed: signature " +			       "and/or required key missing - tainting " +			       "kernel\n", mod->name); +		add_taint_module(mod, TAINT_UNSIGNED_MODULE, LOCKDEP_STILL_OK); +	} +#endif  	/* -	 * If we didn't load the .modinfo 'name' field earlier, fall back to -	 * on-disk struct mod 'name' field. +	 * ndiswrapper is under GPL by itself, but loads proprietary modules. +	 * Don't use add_taint_module(), as it would prevent ndiswrapper from +	 * using GPL-only symbols it needs.  	 */ -	if (!info->name) -		info->name = info->mod->name; +	if (strcmp(mod->name, "ndiswrapper") == 0) +		add_taint(TAINT_PROPRIETARY_MODULE, LOCKDEP_NOW_UNRELIABLE); -	if (flags & MODULE_INIT_IGNORE_MODVERSIONS) -		info->index.vers = 0; /* Pretend no __versions section! */ -	else -		info->index.vers = find_sec(info, "__versions"); +	/* driverloader was caught wrongly pretending to be under GPL */ +	if (strcmp(mod->name, "driverloader") == 0) +		add_taint_module(mod, TAINT_PROPRIETARY_MODULE, +				 LOCKDEP_NOW_UNRELIABLE); -	info->index.pcpu = find_pcpusec(info); +	/* lve claims to be GPL but upstream won't provide source */ +	if (strcmp(mod->name, "lve") == 0) +		add_taint_module(mod, TAINT_PROPRIETARY_MODULE, +				 LOCKDEP_NOW_UNRELIABLE); + +	if (!prev_taint && test_taint(TAINT_PROPRIETARY_MODULE)) +		pr_warn("%s: module license taints kernel.\n", mod->name); -	return 0;  }  static int check_modinfo(struct module *mod, struct load_info *info, int flags) @@ -1970,35 +2091,10 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)  		return -ENOEXEC;  	} -	if (!get_modinfo(info, "intree")) { -		if (!test_taint(TAINT_OOT_MODULE)) -			pr_warn("%s: loading out-of-tree module taints kernel.\n", -				mod->name); -		add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); -	} - -	check_modinfo_retpoline(mod, info); - -	if (get_modinfo(info, "staging")) { -		add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK); -		pr_warn("%s: module is from the staging directory, the quality " -			"is unknown, you have been warned.\n", mod->name); -	} -  	err = check_modinfo_livepatch(mod, info);  	if (err)  		return err; -	/* Set up license info based on the info section */ -	set_license(mod, get_modinfo(info, "license")); - -	if (get_modinfo(info, "test")) { -		if (!test_taint(TAINT_TEST)) -			pr_warn("%s: loading test module taints kernel.\n", -				mod->name); -		add_taint_module(mod, TAINT_TEST, LOCKDEP_STILL_OK); -	} -  	return 0;  } @@ -2110,10 +2206,14 @@ static int find_module_sections(struct module *mod, struct load_info *info)  	if (section_addr(info, "__obsparm"))  		pr_warn("%s: Ignoring obsolete parameters\n", mod->name); -	info->dyndbg.descs = section_objs(info, "__dyndbg", -					sizeof(*info->dyndbg.descs), &info->dyndbg.num_descs); -	info->dyndbg.classes = section_objs(info, "__dyndbg_classes", -					sizeof(*info->dyndbg.classes), &info->dyndbg.num_classes); +#ifdef CONFIG_DYNAMIC_DEBUG_CORE +	mod->dyndbg_info.descs = section_objs(info, "__dyndbg", +					      sizeof(*mod->dyndbg_info.descs), +					      &mod->dyndbg_info.num_descs); +	mod->dyndbg_info.classes = section_objs(info, "__dyndbg_classes", +						sizeof(*mod->dyndbg_info.classes), +						&mod->dyndbg_info.num_classes); +#endif  	return 0;  } @@ -2122,109 +2222,82 @@ static int move_module(struct module *mod, struct load_info *info)  {  	int i;  	void *ptr; +	enum mod_mem_type t = 0; +	int ret = -ENOMEM; -	/* Do the allocs. */ -	ptr = module_alloc(mod->core_layout.size); -	/* -	 * The pointer to this block is stored in the module structure -	 * which is inside the block. Just mark it as not being a -	 * leak. -	 */ -	kmemleak_not_leak(ptr); -	if (!ptr) -		return -ENOMEM; - -	memset(ptr, 0, mod->core_layout.size); -	mod->core_layout.base = ptr; - -	if (mod->init_layout.size) { -		ptr = module_alloc(mod->init_layout.size); +	for_each_mod_mem_type(type) { +		if (!mod->mem[type].size) { +			mod->mem[type].base = NULL; +			continue; +		} +		mod->mem[type].size = PAGE_ALIGN(mod->mem[type].size); +		ptr = module_memory_alloc(mod->mem[type].size, type);  		/* -		 * The pointer to this block is stored in the module structure -		 * which is inside the block. This block doesn't need to be -		 * scanned as it contains data and code that will be freed -		 * after the module is initialized. +                 * The pointer to these blocks of memory are stored on the module +                 * structure and we keep that around so long as the module is +                 * around. We only free that memory when we unload the module. +                 * Just mark them as not being a leak then. The .init* ELF +                 * sections *do* get freed after boot so we *could* treat them +                 * slightly differently with kmemleak_ignore() and only grey +                 * them out as they work as typical memory allocations which +                 * *do* eventually get freed, but let's just keep things simple +                 * and avoid *any* false positives.  		 */ -		kmemleak_ignore(ptr); +		kmemleak_not_leak(ptr);  		if (!ptr) { -			module_memfree(mod->core_layout.base); -			return -ENOMEM; +			t = type; +			goto out_enomem;  		} -		memset(ptr, 0, mod->init_layout.size); -		mod->init_layout.base = ptr; -	} else -		mod->init_layout.base = NULL; - -#ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC -	/* Do the allocs. */ -	ptr = vzalloc(mod->data_layout.size); -	/* -	 * The pointer to this block is stored in the module structure -	 * which is inside the block. Just mark it as not being a -	 * leak. -	 */ -	kmemleak_not_leak(ptr); -	if (!ptr) { -		module_memfree(mod->core_layout.base); -		module_memfree(mod->init_layout.base); -		return -ENOMEM; +		memset(ptr, 0, mod->mem[type].size); +		mod->mem[type].base = ptr;  	} -	mod->data_layout.base = ptr; -#endif  	/* Transfer each section which specifies SHF_ALLOC */ -	pr_debug("final section addresses:\n"); +	pr_debug("Final section addresses for %s:\n", mod->name);  	for (i = 0; i < info->hdr->e_shnum; i++) {  		void *dest;  		Elf_Shdr *shdr = &info->sechdrs[i]; +		enum mod_mem_type type = shdr->sh_entsize >> SH_ENTSIZE_TYPE_SHIFT;  		if (!(shdr->sh_flags & SHF_ALLOC))  			continue; -		if (shdr->sh_entsize & INIT_OFFSET_MASK) -			dest = mod->init_layout.base -				+ (shdr->sh_entsize & ~INIT_OFFSET_MASK); -		else if (!(shdr->sh_flags & SHF_EXECINSTR)) -			dest = mod->data_layout.base + shdr->sh_entsize; -		else -			dest = mod->core_layout.base + shdr->sh_entsize; +		dest = mod->mem[type].base + (shdr->sh_entsize & SH_ENTSIZE_OFFSET_MASK); -		if (shdr->sh_type != SHT_NOBITS) +		if (shdr->sh_type != SHT_NOBITS) { +			/* +			 * Our ELF checker already validated this, but let's +			 * be pedantic and make the goal clearer. We actually +			 * end up copying over all modifications made to the +			 * userspace copy of the entire struct module. +			 */ +			if (i == info->index.mod && +			   (WARN_ON_ONCE(shdr->sh_size != sizeof(struct module)))) { +				ret = -ENOEXEC; +				goto out_enomem; +			}  			memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size); -		/* Update sh_addr to point to copy in image. */ +		} +		/* +		 * Update the userspace copy's ELF section address to point to +		 * our newly allocated memory as a pure convenience so that +		 * users of info can keep taking advantage and using the newly +		 * minted official memory area. +		 */  		shdr->sh_addr = (unsigned long)dest; -		pr_debug("\t0x%lx %s\n", -			 (long)shdr->sh_addr, info->secstrings + shdr->sh_name); +		pr_debug("\t0x%lx 0x%.8lx %s\n", (long)shdr->sh_addr, +			 (long)shdr->sh_size, info->secstrings + shdr->sh_name);  	}  	return 0; +out_enomem: +	for (t--; t >= 0; t--) +		module_memory_free(mod->mem[t].base, t); +	return ret;  } -static int check_module_license_and_versions(struct module *mod) +static int check_export_symbol_versions(struct module *mod)  { -	int prev_taint = test_taint(TAINT_PROPRIETARY_MODULE); - -	/* -	 * ndiswrapper is under GPL by itself, but loads proprietary modules. -	 * Don't use add_taint_module(), as it would prevent ndiswrapper from -	 * using GPL-only symbols it needs. -	 */ -	if (strcmp(mod->name, "ndiswrapper") == 0) -		add_taint(TAINT_PROPRIETARY_MODULE, LOCKDEP_NOW_UNRELIABLE); - -	/* driverloader was caught wrongly pretending to be under GPL */ -	if (strcmp(mod->name, "driverloader") == 0) -		add_taint_module(mod, TAINT_PROPRIETARY_MODULE, -				 LOCKDEP_NOW_UNRELIABLE); - -	/* lve claims to be GPL but upstream won't provide source */ -	if (strcmp(mod->name, "lve") == 0) -		add_taint_module(mod, TAINT_PROPRIETARY_MODULE, -				 LOCKDEP_NOW_UNRELIABLE); - -	if (!prev_taint && test_taint(TAINT_PROPRIETARY_MODULE)) -		pr_warn("%s: module license taints kernel.\n", mod->name); -  #ifdef CONFIG_MODVERSIONS  	if ((mod->num_syms && !mod->crcs) ||  	    (mod->num_gpl_syms && !mod->gpl_crcs)) { @@ -2242,12 +2315,14 @@ static void flush_module_icache(const struct module *mod)  	 * Do it before processing of module parameters, so the module  	 * can provide parameter accessor functions of its own.  	 */ -	if (mod->init_layout.base) -		flush_icache_range((unsigned long)mod->init_layout.base, -				   (unsigned long)mod->init_layout.base -				   + mod->init_layout.size); -	flush_icache_range((unsigned long)mod->core_layout.base, -			   (unsigned long)mod->core_layout.base + mod->core_layout.size); +	for_each_mod_mem_type(type) { +		const struct module_memory *mod_mem = &mod->mem[type]; + +		if (mod_mem->size) { +			flush_icache_range((unsigned long)mod_mem->base, +					   (unsigned long)mod_mem->base + mod_mem->size); +		} +	}  }  bool __weak module_elf_check_arch(Elf_Ehdr *hdr) @@ -2290,10 +2365,6 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)  	unsigned int ndx;  	int err; -	err = check_modinfo(info->mod, info, flags); -	if (err) -		return ERR_PTR(err); -  	/* Allow arches to frob section contents and sizes.  */  	err = module_frob_arch_sections(info->hdr, info->sechdrs,  					info->secstrings, info->mod); @@ -2350,11 +2421,8 @@ static void module_deallocate(struct module *mod, struct load_info *info)  {  	percpu_modfree(mod);  	module_arch_freeing_init(mod); -	module_memfree(mod->init_layout.base); -	module_memfree(mod->core_layout.base); -#ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC -	vfree(mod->data_layout.base); -#endif + +	free_mod_mem(mod);  }  int __weak module_finalize(const Elf_Ehdr *hdr, @@ -2380,27 +2448,6 @@ static int post_relocation(struct module *mod, const struct load_info *info)  	return module_finalize(info->hdr, info->sechdrs, mod);  } -/* Is this module of this name done loading?  No locks held. */ -static bool finished_loading(const char *name) -{ -	struct module *mod; -	bool ret; - -	/* -	 * The module_mutex should not be a heavily contended lock; -	 * if we get the occasional sleep here, we'll go an extra iteration -	 * in the wait_event_interruptible(), which is harmless. -	 */ -	sched_annotate_sleep(); -	mutex_lock(&module_mutex); -	mod = find_module_all(name, strlen(name), true); -	ret = !mod || mod->state == MODULE_STATE_LIVE -		|| mod->state == MODULE_STATE_GOING; -	mutex_unlock(&module_mutex); - -	return ret; -} -  /* Call module constructors. */  static void do_mod_ctors(struct module *mod)  { @@ -2415,7 +2462,9 @@ static void do_mod_ctors(struct module *mod)  /* For freeing module_init on success, in case kallsyms traversing */  struct mod_initfree {  	struct llist_node node; -	void *module_init; +	void *init_text; +	void *init_data; +	void *init_rodata;  };  static void do_free_init(struct work_struct *w) @@ -2429,7 +2478,9 @@ static void do_free_init(struct work_struct *w)  	llist_for_each_safe(pos, n, list) {  		initfree = container_of(pos, struct mod_initfree, node); -		module_memfree(initfree->module_init); +		module_memfree(initfree->init_text); +		module_memfree(initfree->init_data); +		module_memfree(initfree->init_rodata);  		kfree(initfree);  	}  } @@ -2450,13 +2501,27 @@ static noinline int do_init_module(struct module *mod)  {  	int ret = 0;  	struct mod_initfree *freeinit; +#if defined(CONFIG_MODULE_STATS) +	unsigned int text_size = 0, total_size = 0; + +	for_each_mod_mem_type(type) { +		const struct module_memory *mod_mem = &mod->mem[type]; +		if (mod_mem->size) { +			total_size += mod_mem->size; +			if (type == MOD_TEXT || type == MOD_INIT_TEXT) +				text_size += mod_mem->size; +		} +	} +#endif  	freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL);  	if (!freeinit) {  		ret = -ENOMEM;  		goto fail;  	} -	freeinit->module_init = mod->init_layout.base; +	freeinit->init_text = mod->mem[MOD_INIT_TEXT].base; +	freeinit->init_data = mod->mem[MOD_INIT_DATA].base; +	freeinit->init_rodata = mod->mem[MOD_INIT_RODATA].base;  	do_mod_ctors(mod);  	/* Start the module */ @@ -2492,8 +2557,8 @@ static noinline int do_init_module(struct module *mod)  	if (!mod->async_probe_requested)  		async_synchronize_full(); -	ftrace_free_mem(mod, mod->init_layout.base, mod->init_layout.base + -			mod->init_layout.size); +	ftrace_free_mem(mod, mod->mem[MOD_INIT_TEXT].base, +			mod->mem[MOD_INIT_TEXT].base + mod->mem[MOD_INIT_TEXT].size);  	mutex_lock(&module_mutex);  	/* Drop initial reference. */  	module_put(mod); @@ -2505,11 +2570,11 @@ static noinline int do_init_module(struct module *mod)  	module_enable_ro(mod, true);  	mod_tree_remove_init(mod);  	module_arch_freeing_init(mod); -	mod->init_layout.base = NULL; -	mod->init_layout.size = 0; -	mod->init_layout.ro_size = 0; -	mod->init_layout.ro_after_init_size = 0; -	mod->init_layout.text_size = 0; +	for_class_mod_mem_type(type, init) { +		mod->mem[type].base = NULL; +		mod->mem[type].size = 0; +	} +  #ifdef CONFIG_DEBUG_INFO_BTF_MODULES  	/* .BTF is not SHF_ALLOC and will get removed, so sanitize pointer */  	mod->btf_data = NULL; @@ -2533,6 +2598,11 @@ static noinline int do_init_module(struct module *mod)  	mutex_unlock(&module_mutex);  	wake_up_all(&module_wq); +	mod_stat_add_long(text_size, &total_text_size); +	mod_stat_add_long(total_size, &total_mod_size); + +	mod_stat_inc(&modcount); +  	return 0;  fail_free_freeinit: @@ -2548,6 +2618,7 @@ fail:  	ftrace_release_mod(mod);  	free_module(mod);  	wake_up_all(&module_wq); +  	return ret;  } @@ -2559,6 +2630,67 @@ static int may_init_module(void)  	return 0;  } +/* Is this module of this name done loading?  No locks held. */ +static bool finished_loading(const char *name) +{ +	struct module *mod; +	bool ret; + +	/* +	 * The module_mutex should not be a heavily contended lock; +	 * if we get the occasional sleep here, we'll go an extra iteration +	 * in the wait_event_interruptible(), which is harmless. +	 */ +	sched_annotate_sleep(); +	mutex_lock(&module_mutex); +	mod = find_module_all(name, strlen(name), true); +	ret = !mod || mod->state == MODULE_STATE_LIVE +		|| mod->state == MODULE_STATE_GOING; +	mutex_unlock(&module_mutex); + +	return ret; +} + +/* Must be called with module_mutex held */ +static int module_patient_check_exists(const char *name, +				       enum fail_dup_mod_reason reason) +{ +	struct module *old; +	int err = 0; + +	old = find_module_all(name, strlen(name), true); +	if (old == NULL) +		return 0; + +	if (old->state == MODULE_STATE_COMING || +	    old->state == MODULE_STATE_UNFORMED) { +		/* Wait in case it fails to load. */ +		mutex_unlock(&module_mutex); +		err = wait_event_interruptible(module_wq, +				       finished_loading(name)); +		mutex_lock(&module_mutex); +		if (err) +			return err; + +		/* The module might have gone in the meantime. */ +		old = find_module_all(name, strlen(name), true); +	} + +	if (try_add_failed_module(name, reason)) +		pr_warn("Could not add fail-tracking for module: %s\n", name); + +	/* +	 * We are here only when the same module was being loaded. Do +	 * not try to load it again right now. It prevents long delays +	 * caused by serialized module load failures. It might happen +	 * when more devices of the same type trigger load of +	 * a particular module. +	 */ +	if (old && old->state == MODULE_STATE_LIVE) +		return -EEXIST; +	return -EBUSY; +} +  /*   * We try to place it in the list now to make sure it's unique before   * we dedicate too many resources.  In particular, temporary percpu @@ -2567,41 +2699,14 @@ static int may_init_module(void)  static int add_unformed_module(struct module *mod)  {  	int err; -	struct module *old;  	mod->state = MODULE_STATE_UNFORMED;  	mutex_lock(&module_mutex); -	old = find_module_all(mod->name, strlen(mod->name), true); -	if (old != NULL) { -		if (old->state == MODULE_STATE_COMING -		    || old->state == MODULE_STATE_UNFORMED) { -			/* Wait in case it fails to load. */ -			mutex_unlock(&module_mutex); -			err = wait_event_interruptible(module_wq, -					       finished_loading(mod->name)); -			if (err) -				goto out_unlocked; - -			/* The module might have gone in the meantime. */ -			mutex_lock(&module_mutex); -			old = find_module_all(mod->name, strlen(mod->name), -					      true); -		} - -		/* -		 * We are here only when the same module was being loaded. Do -		 * not try to load it again right now. It prevents long delays -		 * caused by serialized module load failures. It might happen -		 * when more devices of the same type trigger load of -		 * a particular module. -		 */ -		if (old && old->state == MODULE_STATE_LIVE) -			err = -EEXIST; -		else -			err = -EBUSY; +	err = module_patient_check_exists(mod->name, FAIL_DUP_MOD_LOAD); +	if (err)  		goto out; -	} +  	mod_update_bounds(mod);  	list_add_rcu(&mod->list, &modules);  	mod_tree_insert(mod); @@ -2609,7 +2714,6 @@ static int add_unformed_module(struct module *mod)  out:  	mutex_unlock(&module_mutex); -out_unlocked:  	return err;  } @@ -2628,9 +2732,6 @@ static int complete_formation(struct module *mod, struct load_info *info)  	module_bug_finalize(info->hdr, info->sechdrs, mod);  	module_cfi_finalize(info->hdr, info->sechdrs, mod); -	if (module_check_misalignment(mod)) -		goto out_misaligned; -  	module_enable_ro(mod, false);  	module_enable_nx(mod);  	module_enable_x(mod); @@ -2644,8 +2745,6 @@ static int complete_formation(struct module *mod, struct load_info *info)  	return 0; -out_misaligned: -	err = -EINVAL;  out:  	mutex_unlock(&module_mutex);  	return err; @@ -2688,6 +2787,39 @@ static int unknown_module_param_cb(char *param, char *val, const char *modname,  	return 0;  } +/* Module within temporary copy, this doesn't do any allocation  */ +static int early_mod_check(struct load_info *info, int flags) +{ +	int err; + +	/* +	 * Now that we know we have the correct module name, check +	 * if it's blacklisted. +	 */ +	if (blacklisted(info->name)) { +		pr_err("Module %s is blacklisted\n", info->name); +		return -EPERM; +	} + +	err = rewrite_section_headers(info, flags); +	if (err) +		return err; + +	/* Check module struct version now, before we try to use module. */ +	if (!check_modstruct_version(info, info->mod)) +		return -ENOEXEC; + +	err = check_modinfo(info->mod, info, flags); +	if (err) +		return err; + +	mutex_lock(&module_mutex); +	err = module_patient_check_exists(info->mod->name, FAIL_DUP_MOD_BECOMING); +	mutex_unlock(&module_mutex); + +	return err; +} +  /*   * Allocate and load the module: note that size of section 0 is always   * zero, and we rely on this for optional sections. @@ -2696,6 +2828,7 @@ static int load_module(struct load_info *info, const char __user *uargs,  		       int flags)  {  	struct module *mod; +	bool module_allocated = false;  	long err = 0;  	char *after_dashes; @@ -2717,40 +2850,17 @@ static int load_module(struct load_info *info, const char __user *uargs,  	/*  	 * Do basic sanity checks against the ELF header and -	 * sections. +	 * sections. Cache useful sections and set the +	 * info->mod to the userspace passed struct module.  	 */ -	err = elf_validity_check(info); +	err = elf_validity_cache_copy(info, flags);  	if (err)  		goto free_copy; -	/* -	 * Everything checks out, so set up the section info -	 * in the info structure. -	 */ -	err = setup_load_info(info, flags); +	err = early_mod_check(info, flags);  	if (err)  		goto free_copy; -	/* -	 * Now that we know we have the correct module name, check -	 * if it's blacklisted. -	 */ -	if (blacklisted(info->name)) { -		err = -EPERM; -		pr_err("Module %s is blacklisted\n", info->name); -		goto free_copy; -	} - -	err = rewrite_section_headers(info, flags); -	if (err) -		goto free_copy; - -	/* Check module struct version now, before we try to use module. */ -	if (!check_modstruct_version(info, info->mod)) { -		err = -ENOEXEC; -		goto free_copy; -	} -  	/* Figure out module layout, and allocate all the memory. */  	mod = layout_and_allocate(info, flags);  	if (IS_ERR(mod)) { @@ -2758,6 +2868,8 @@ static int load_module(struct load_info *info, const char __user *uargs,  		goto free_copy;  	} +	module_allocated = true; +  	audit_log_kern_module(mod->name);  	/* Reserve our place in the list. */ @@ -2765,15 +2877,11 @@ static int load_module(struct load_info *info, const char __user *uargs,  	if (err)  		goto free_module; -#ifdef CONFIG_MODULE_SIG -	mod->sig_ok = info->sig_ok; -	if (!mod->sig_ok) { -		pr_notice_once("%s: module verification failed: signature " -			       "and/or required key missing - tainting " -			       "kernel\n", mod->name); -		add_taint_module(mod, TAINT_UNSIGNED_MODULE, LOCKDEP_STILL_OK); -	} -#endif +	/* +	 * We are tainting your kernel if your module gets into +	 * the modules linked list somehow. +	 */ +	module_augment_kernel_taints(mod, info);  	/* To avoid stressing percpu allocator, do this once we're unique. */  	err = percpu_modalloc(mod, info); @@ -2795,7 +2903,7 @@ static int load_module(struct load_info *info, const char __user *uargs,  	if (err)  		goto free_unload; -	err = check_module_license_and_versions(mod); +	err = check_export_symbol_versions(mod);  	if (err)  		goto free_unload; @@ -2825,7 +2933,6 @@ static int load_module(struct load_info *info, const char __user *uargs,  	}  	init_build_id(mod, info); -	dynamic_debug_setup(mod, &info->dyndbg);  	/* Ftrace init must be called in the MODULE_STATE_UNFORMED state */  	ftrace_module_init(mod); @@ -2889,7 +2996,6 @@ static int load_module(struct load_info *info, const char __user *uargs,   ddebug_cleanup:  	ftrace_release_mod(mod); -	dynamic_debug_remove(mod, &info->dyndbg);  	synchronize_rcu();  	kfree(mod->args);   free_arch_cleanup: @@ -2908,11 +3014,22 @@ static int load_module(struct load_info *info, const char __user *uargs,  	synchronize_rcu();  	mutex_unlock(&module_mutex);   free_module: +	mod_stat_bump_invalid(info, flags);  	/* Free lock-classes; relies on the preceding sync_rcu() */ -	lockdep_free_key_range(mod->data_layout.base, mod->data_layout.size); +	for_class_mod_mem_type(type, core_data) { +		lockdep_free_key_range(mod->mem[type].base, +				       mod->mem[type].size); +	}  	module_deallocate(mod, info);   free_copy: +	/* +	 * The info->len is always set. We distinguish between +	 * failures once the proper module was allocated and +	 * before that. +	 */ +	if (!module_allocated) +		mod_stat_bump_becoming(info, flags);  	free_copy(info, flags);  	return err;  } @@ -2931,8 +3048,11 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,  	       umod, len, uargs);  	err = copy_module_from_user(umod, len, &info); -	if (err) +	if (err) { +		mod_stat_inc(&failed_kreads); +		mod_stat_add_long(len, &invalid_kread_bytes);  		return err; +	}  	return load_module(&info, uargs, 0);  } @@ -2957,14 +3077,20 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)  	len = kernel_read_file_from_fd(fd, 0, &buf, INT_MAX, NULL,  				       READING_MODULE); -	if (len < 0) +	if (len < 0) { +		mod_stat_inc(&failed_kreads); +		mod_stat_add_long(len, &invalid_kread_bytes);  		return len; +	}  	if (flags & MODULE_INIT_COMPRESSED_FILE) {  		err = module_decompress(&info, buf, len);  		vfree(buf); /* compressed data is no longer needed */ -		if (err) +		if (err) { +			mod_stat_inc(&failed_decompress); +			mod_stat_add_long(len, &invalid_decompress_bytes);  			return err; +		}  	} else {  		info.hdr = buf;  		info.len = len; @@ -2973,11 +3099,6 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)  	return load_module(&info, uargs, flags);  } -static inline int within(unsigned long addr, void *start, unsigned long size) -{ -	return ((void *)addr >= start && (void *)addr < start + size); -} -  /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */  char *module_flags(struct module *mod, char *buf, bool show_state)  { @@ -3060,20 +3181,21 @@ bool is_module_address(unsigned long addr)  struct module *__module_address(unsigned long addr)  {  	struct module *mod; -	struct mod_tree_root *tree;  	if (addr >= mod_tree.addr_min && addr <= mod_tree.addr_max) -		tree = &mod_tree; +		goto lookup; +  #ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC -	else if (addr >= mod_data_tree.addr_min && addr <= mod_data_tree.addr_max) -		tree = &mod_data_tree; +	if (addr >= mod_tree.data_addr_min && addr <= mod_tree.data_addr_max) +		goto lookup;  #endif -	else -		return NULL; +	return NULL; + +lookup:  	module_assert_mutex_or_preempt(); -	mod = mod_find(addr, tree); +	mod = mod_find(addr, &mod_tree);  	if (mod) {  		BUG_ON(!within_module(addr, mod));  		if (mod->state == MODULE_STATE_UNFORMED) @@ -3113,8 +3235,8 @@ struct module *__module_text_address(unsigned long addr)  	struct module *mod = __module_address(addr);  	if (mod) {  		/* Make sure it's within the text section. */ -		if (!within(addr, mod->init_layout.base, mod->init_layout.text_size) -		    && !within(addr, mod->core_layout.base, mod->core_layout.text_size)) +		if (!within_module_mem_type(addr, mod, MOD_TEXT) && +		    !within_module_mem_type(addr, mod, MOD_INIT_TEXT))  			mod = NULL;  	}  	return mod; @@ -3142,3 +3264,14 @@ void print_modules(void)  			last_unloaded_module.taints);  	pr_cont("\n");  } + +#ifdef CONFIG_MODULE_DEBUGFS +struct dentry *mod_debugfs_root; + +static int module_debugfs_init(void) +{ +	mod_debugfs_root = debugfs_create_dir("modules", NULL); +	return 0; +} +module_init(module_debugfs_init); +#endif  | 
