Commit 03d7a105 authored by Michal Kubecek's avatar Michal Kubecek Committed by Peter Zijlstra
Browse files

objtool: Check that module init/exit function is an indirect call target



Some out-of-tree modules still do not use module_init() / module_exit()
macros and simply create functions with magic names init_module() and
cleanup_module() instead. As a result, these functions are not recognized
as indirect call targets by objtool and such module fails to load into an
IBT enabled kernel.

This old way is not even documented any more but it is cleaner to issue
a warning than to let the module fail on load without obvious reason.

Signed-off-by: default avatarMichal Kubecek <mkubecek@suse.cz>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20230118105215.B9DA960514@lion.mk-sys.cz
parent 3da73f10
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -410,6 +410,14 @@ the objtool maintainers.
   can remove this warning by putting the ANNOTATE_INTRA_FUNCTION_CALL
   directive right before the call.

12. file.o: warning: func(): not an indirect call target

   This means that objtool is running with --ibt and a function expected
   to be an indirect call target is not. In particular, this happens for
   init_module() or cleanup_module() if a module relies on these special
   names and does not use module_init() / module_exit() macros to create
   them.


If the error doesn't seem to make sense, it could be a bug in objtool.
Feel free to ask the objtool maintainer for help.
+7 −0
Original line number Diff line number Diff line
@@ -847,8 +847,15 @@ static int create_ibt_endbr_seal_sections(struct objtool_file *file)
	list_for_each_entry(insn, &file->endbr_list, call_node) {

		int *site = (int *)sec->data->d_buf + idx;
		struct symbol *sym = insn->sym;
		*site = 0;

		if (opts.module && sym && sym->type == STT_FUNC &&
		    insn->offset == sym->offset &&
		    (!strcmp(sym->name, "init_module") ||
		     !strcmp(sym->name, "cleanup_module")))
			WARN("%s(): not an indirect call target", sym->name);

		if (elf_add_reloc_to_insn(file->elf, sec,
					  idx * sizeof(int),
					  R_X86_64_PC32,