4590 lines · 117.2 KB · C
RawDownload
 *          [text] [read-only-data] [ro-after-init] [writable data] * text_size -----^                ^               ^               ^ * ro_size ------------------------|               |               | * ro_after_init_size -----------------------------|               | * size -----------------------------------------------------------| * * These values are always page-aligned (as is base) */ /* * Since some arches are moving towards PAGE_KERNEL module allocations instead * of PAGE_KERNEL_EXEC, keep frob_text() and module_enable_x() outside of the * CONFIG_STRICT_MODULE_RWX block below because they are needed regardless of * whether we are strict. */#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWXstatic void frob_text(const struct module_layout *layout,		      int (*set_memory)(unsigned long start, int num_pages)){	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));	BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));	set_memory((unsigned long)layout->base,		   layout->text_size >> PAGE_SHIFT);} static void module_enable_x(const struct module *mod){	frob_text(&mod->core_layout, set_memory_x);	frob_text(&mod->init_layout, set_memory_x);}#else /* !CONFIG_ARCH_HAS_STRICT_MODULE_RWX */static void module_enable_x(const struct module *mod) { }#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ #ifdef CONFIG_STRICT_MODULE_RWXstatic void frob_rodata(const struct module_layout *layout,			int (*set_memory)(unsigned long start, int num_pages)){	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));	BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));	BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));	set_memory((unsigned long)layout->base + layout->text_size,		   (layout->ro_size - layout->text_size) >> PAGE_SHIFT);} static void frob_ro_after_init(const struct module_layout *layout,				int (*set_memory)(unsigned long start, int num_pages)){	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));	BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));	BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1));	set_memory((unsigned long)layout->base + layout->ro_size,		   (layout->ro_after_init_size - layout->ro_size) >> PAGE_SHIFT);} static void frob_writable_data(const struct module_layout *layout,			       int (*set_memory)(unsigned long start, int num_pages)){	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));	BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1));	BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1));	set_memory((unsigned long)layout->base + layout->ro_after_init_size,		   (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT);} static void module_enable_ro(const struct module *mod, bool after_init){	if (!rodata_enabled)		return; 	set_vm_flush_reset_perms(mod->core_layout.base);	set_vm_flush_reset_perms(mod->init_layout.base);	frob_text(&mod->core_layout, set_memory_ro); 	frob_rodata(&mod->core_layout, set_memory_ro);	frob_text(&mod->init_layout, set_memory_ro);	frob_rodata(&mod->init_layout, set_memory_ro); 	if (after_init)		frob_ro_after_init(&mod->core_layout, set_memory_ro);} static void module_enable_nx(const struct module *mod){	frob_rodata(&mod->core_layout, set_memory_nx);	frob_ro_after_init(&mod->core_layout, set_memory_nx);	frob_writable_data(&mod->core_layout, set_memory_nx);	frob_rodata(&mod->init_layout, set_memory_nx);	frob_writable_data(&mod->init_layout, set_memory_nx);} static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,				       char *secstrings, struct module *mod){	const unsigned long shf_wx = SHF_WRITE|SHF_EXECINSTR;	int i; 	for (i = 0; i < hdr->e_shnum; i++) {		if ((sechdrs[i].sh_flags & shf_wx) == shf_wx)			return -ENOEXEC;	} 	return 0;} #else /* !CONFIG_STRICT_MODULE_RWX */static void module_enable_nx(const struct module *mod) { }static void module_enable_ro(const struct module *mod, bool after_init) {}static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,				       char *secstrings, struct module *mod){	return 0;}#endif /*  CONFIG_STRICT_MODULE_RWX */ #ifdef CONFIG_LIVEPATCH/* * Persist Elf information about a module. Copy the Elf header, * section header table, section string table, and symtab section * index from info to mod->klp_info. */static int copy_module_elf(struct module *mod, struct load_info *info){	unsigned int size, symndx;	int ret; 	size = sizeof(*mod->klp_info);	mod->klp_info = kmalloc(size, GFP_KERNEL);	if (mod->klp_info == NULL)		return -ENOMEM; 	/* Elf header */	size = sizeof(mod->klp_info->hdr);	memcpy(&mod->klp_info->hdr, info->hdr, size); 	/* Elf section header table */	size = sizeof(*info->sechdrs) * info->hdr->e_shnum;	mod->klp_info->sechdrs = kmemdup(info->sechdrs, size, GFP_KERNEL);	if (mod->klp_info->sechdrs == NULL) {		ret = -ENOMEM;		goto free_info;	} 	/* Elf section name string table */	size = info->sechdrs[info->hdr->e_shstrndx].sh_size;	mod->klp_info->secstrings = kmemdup(info->secstrings, size, GFP_KERNEL);	if (mod->klp_info->secstrings == NULL) {		ret = -ENOMEM;		goto free_sechdrs;	} 	/* Elf symbol section index */	symndx = info->index.sym;	mod->klp_info->symndx = symndx; 	/*	 * For livepatch modules, core_kallsyms.symtab is a complete	 * copy of the original symbol table. Adjust sh_addr to point	 * to core_kallsyms.symtab since the copy of the symtab in module	 * init memory is freed at the end of do_init_module().	 */	mod->klp_info->sechdrs[symndx].sh_addr = \		(unsigned long) mod->core_kallsyms.symtab; 	return 0; free_sechdrs:	kfree(mod->klp_info->sechdrs);free_info:	kfree(mod->klp_info);	return ret;} static void free_module_elf(struct module *mod){	kfree(mod->klp_info->sechdrs);	kfree(mod->klp_info->secstrings);	kfree(mod->klp_info);}#else /* !CONFIG_LIVEPATCH */static int copy_module_elf(struct module *mod, struct load_info *info){	return 0;} static void free_module_elf(struct module *mod){}#endif /* CONFIG_LIVEPATCH */ void __weak module_memfree(void *module_region){	/*	 * This memory may be RO, and freeing RO memory in an interrupt is not	 * supported by vmalloc.	 */	WARN_ON(in_interrupt());	vfree(module_region);} void __weak module_arch_cleanup(struct module *mod){} void __weak module_arch_freeing_init(struct module *mod){} /* Free a module, remove from lists, etc. */static void free_module(struct module *mod){	trace_module_free(mod); 	mod_sysfs_teardown(mod); 	/* We leave it in list to prevent duplicate loads, but make sure	 * that noone uses it while it's being deconstructed. */	mutex_lock(&module_mutex);	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); 	/* Module unload stuff */	module_unload_free(mod); 	/* Free any allocated parameters. */	destroy_params(mod->kp, mod->num_kp); 	if (is_livepatch_module(mod))		free_module_elf(mod); 	/* Now we can delete it from the lists */	mutex_lock(&module_mutex);	/* Unlink carefully: kallsyms could be walking list. */	list_del_rcu(&mod->list);	mod_tree_remove(mod);	/* Remove this module from bug list, this uses list_del_rcu */	module_bug_cleanup(mod);	/* Wait for RCU-sched synchronizing before releasing mod->list and buglist. */	synchronize_rcu();	mutex_unlock(&module_mutex); 	/* 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->core_layout.base, mod->core_layout.size); 	/* Finally, free the core (containing the module structure) */	module_memfree(mod->core_layout.base);} void *__symbol_get(const char *symbol){	struct module *owner;	const struct kernel_symbol *sym; 	preempt_disable();	sym = find_symbol(symbol, &owner, NULL, NULL, true, true);	if (sym && strong_try_module_get(owner))		sym = NULL;	preempt_enable(); 	return sym ? (void *)kernel_symbol_value(sym) : NULL;}EXPORT_SYMBOL_GPL(__symbol_get); /* * Ensure that an exported symbol [global namespace] does not already exist * in the kernel or in some other module's exported symbol table. * * You must hold the module_mutex. */static int verify_exported_symbols(struct module *mod){	unsigned int i;	struct module *owner;	const struct kernel_symbol *s;	struct {		const struct kernel_symbol *sym;		unsigned int num;	} arr[] = {		{ mod->syms, mod->num_syms },		{ mod->gpl_syms, mod->num_gpl_syms },		{ mod->gpl_future_syms, mod->num_gpl_future_syms },#ifdef CONFIG_UNUSED_SYMBOLS		{ mod->unused_syms, mod->num_unused_syms },		{ mod->unused_gpl_syms, mod->num_unused_gpl_syms },#endif	}; 	for (i = 0; i < ARRAY_SIZE(arr); i++) {		for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {			if (find_symbol(kernel_symbol_name(s), &owner, NULL,					NULL, true, false)) {				pr_err("%s: exports duplicate symbol %s"				       " (owned by %s)\n",				       mod->name, kernel_symbol_name(s),				       module_name(owner));				return -ENOEXEC;			}		}	}	return 0;} /* Change all symbols so that st_value encodes the pointer directly. */static int simplify_symbols(struct module *mod, const struct load_info *info){	Elf_Shdr *symsec = &info->sechdrs[info->index.sym];	Elf_Sym *sym = (void *)symsec->sh_addr;	unsigned long secbase;	unsigned int i;	int ret = 0;	const struct kernel_symbol *ksym; 	for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) {		const char *name = info->strtab + sym[i].st_name; 		switch (sym[i].st_shndx) {		case SHN_COMMON:			/* Ignore common symbols */			if (!strncmp(name, "__gnu_lto", 9))				break; 			/* We compiled with -fno-common.  These are not			   supposed to happen.  */			pr_debug("Common symbol: %s\n", name);			pr_warn("%s: please compile with -fno-common\n",			       mod->name);			ret = -ENOEXEC;			break; 		case SHN_ABS:			/* Don't need to do anything */			pr_debug("Absolute symbol: 0x%08lx\n",			       (long)sym[i].st_value);			break; 		case SHN_LIVEPATCH:			/* Livepatch symbols are resolved by livepatch */			break; 		case SHN_UNDEF:			ksym = resolve_symbol_wait(mod, info, name);			/* Ok if resolved.  */			if (ksym && !IS_ERR(ksym)) {				sym[i].st_value = kernel_symbol_value(ksym);				break;			} 			/* Ok if weak.  */			if (!ksym && ELF_ST_BIND(sym[i].st_info) == STB_WEAK)				break; 			ret = PTR_ERR(ksym) ?: -ENOENT;			pr_warn("%s: Unknown symbol %s (err %d)\n",				mod->name, name, ret);			break; 		default:			/* Divert to percpu allocation if a percpu var. */			if (sym[i].st_shndx == info->index.pcpu)				secbase = (unsigned long)mod_percpu(mod);			else				secbase = info->sechdrs[sym[i].st_shndx].sh_addr;			sym[i].st_value += secbase;			break;		}	} 	return ret;} static int apply_relocations(struct module *mod, const struct load_info *info){	unsigned int i;	int err = 0; 	/* Now do relocations. */	for (i = 1; i < info->hdr->e_shnum; i++) {		unsigned int infosec = info->sechdrs[i].sh_info; 		/* Not a valid relocation section? */		if (infosec >= info->hdr->e_shnum)			continue; 		/* Don't bother with non-allocated sections */		if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC))			continue; 		if (info->sechdrs[i].sh_flags & SHF_RELA_LIVEPATCH)			err = klp_apply_section_relocs(mod, info->sechdrs,						       info->secstrings,						       info->strtab,						       info->index.sym, i,						       NULL);		else if (info->sechdrs[i].sh_type == SHT_REL)			err = apply_relocate(info->sechdrs, info->strtab,					     info->index.sym, i, mod);		else if (info->sechdrs[i].sh_type == SHT_RELA)			err = apply_relocate_add(info->sechdrs, info->strtab,						 info->index.sym, i, mod);		if (err < 0)			break;	}	return err;} /* Additional bytes needed by arch in front of individual sections */unsigned int __weak arch_mod_section_prepend(struct module *mod,					     unsigned int section){	/* default implementation just returns zero */	return 0;} /* Update size with this section: return offset. */static long get_offset(struct module *mod, unsigned int *size,		       Elf_Shdr *sechdr, unsigned int section){	long ret; 	*size += arch_mod_section_prepend(mod, section);	ret = ALIGN(*size, sechdr->sh_addralign ?: 1);	*size = ret + sechdr->sh_size;	return ret;} /* 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 unsigned long const masks[][2] = {		/* NOTE: all executable code must be the first section		 * in this array; otherwise modify the text_size		 * finder in the two loops below */		{ SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL },		{ SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL },		{ SHF_RO_AFTER_INIT | SHF_ALLOC, ARCH_SHF_SMALL },		{ 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; 	pr_debug("Core 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_section(sname))				continue;			s->sh_entsize = get_offset(mod, &mod->core_layout.size, s, i);			pr_debug("\t%s\n", sname);		}		switch (m) {		case 0: /* executable */			mod->core_layout.size = debug_align(mod->core_layout.size);			mod->core_layout.text_size = mod->core_layout.size;			break;		case 1: /* RO: text and ro-data */			mod->core_layout.size = debug_align(mod->core_layout.size);			mod->core_layout.ro_size = mod->core_layout.size;			break;		case 2: /* RO after init */			mod->core_layout.size = debug_align(mod->core_layout.size);			mod->core_layout.ro_after_init_size = mod->core_layout.size;			break;		case 4: /* whole core */			mod->core_layout.size = debug_align(mod->core_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

Lines 2001–2500 of 4590. Previous lines