Michal Kubecek 39a491
From: Michal Kubecek <mkubecek@suse.cz>
Michal Kubecek 39a491
Date: Wed, 18 Jan 2023 11:52:15 +0100
Michal Kubecek 39a491
Subject: objtool: Check that module init/exit function is an indirect call target
Michal Kubecek 39a491
Patch-mainline: Queued in subsystem maintainer repository
Michal Kubecek 39a491
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
Michal Kubecek 39a491
Git-commit: 03d7a1053cf72372be22b43faada5bca12ff183d
Michal Kubecek 39a491
References: none
Michal Kubecek 39a491
Michal Kubecek 39a491
Some out-of-tree modules still do not use module_init() / module_exit()
Michal Kubecek 39a491
macros and simply create functions with magic names init_module() and
Michal Kubecek 39a491
cleanup_module() instead. As a result, these functions are not recognized
Michal Kubecek 39a491
as indirect call targets by objtool and such module fails to load into an
Michal Kubecek 39a491
IBT enabled kernel.
Michal Kubecek 39a491
Michal Kubecek 39a491
This old way is not even documented any more but it is cleaner to issue
Michal Kubecek 39a491
a warning than to let the module fail on load without obvious reason.
Michal Kubecek 39a491
Michal Kubecek 39a491
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Michal Kubecek 39a491
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Michal Kubecek 39a491
Link: https://lkml.kernel.org/r/20230118105215.B9DA960514@lion.mk-sys.cz
Michal Kubecek 39a491
---
Michal Kubecek 39a491
 tools/objtool/Documentation/objtool.txt | 8 ++++++++
Michal Kubecek 39a491
 tools/objtool/check.c                   | 7 +++++++
Michal Kubecek 39a491
 2 files changed, 15 insertions(+)
Michal Kubecek 39a491
Michal Kubecek 39a491
--- a/tools/objtool/Documentation/objtool.txt
Michal Kubecek 39a491
+++ b/tools/objtool/Documentation/objtool.txt
Michal Kubecek 39a491
@@ -410,6 +410,14 @@ the objtool maintainers.
Michal Kubecek 39a491
    can remove this warning by putting the ANNOTATE_INTRA_FUNCTION_CALL
Michal Kubecek 39a491
    directive right before the call.
Michal Kubecek 39a491
 
Michal Kubecek 39a491
+12. file.o: warning: func(): not an indirect call target
Michal Kubecek 39a491
+
Michal Kubecek 39a491
+   This means that objtool is running with --ibt and a function expected
Michal Kubecek 39a491
+   to be an indirect call target is not. In particular, this happens for
Michal Kubecek 39a491
+   init_module() or cleanup_module() if a module relies on these special
Michal Kubecek 39a491
+   names and does not use module_init() / module_exit() macros to create
Michal Kubecek 39a491
+   them.
Michal Kubecek 39a491
+
Michal Kubecek 39a491
 
Michal Kubecek 39a491
 If the error doesn't seem to make sense, it could be a bug in objtool.
Michal Kubecek 39a491
 Feel free to ask the objtool maintainer for help.
Michal Kubecek 39a491
--- a/tools/objtool/check.c
Michal Kubecek 39a491
+++ b/tools/objtool/check.c
Michal Kubecek 39a491
@@ -847,8 +847,15 @@ static int create_ibt_endbr_seal_sections(struct objtool_file *file)
Michal Kubecek 39a491
 	list_for_each_entry(insn, &file->endbr_list, call_node) {
Michal Kubecek 39a491
 
Michal Kubecek 39a491
 		int *site = (int *)sec->data->d_buf + idx;
Michal Kubecek 39a491
+		struct symbol *sym = insn->sym;
Michal Kubecek 39a491
 		*site = 0;
Michal Kubecek 39a491
 
Michal Kubecek 39a491
+		if (opts.module && sym && sym->type == STT_FUNC &&
Michal Kubecek 39a491
+		    insn->offset == sym->offset &&
Michal Kubecek 39a491
+		    (!strcmp(sym->name, "init_module") ||
Michal Kubecek 39a491
+		     !strcmp(sym->name, "cleanup_module")))
Michal Kubecek 39a491
+			WARN("%s(): not an indirect call target", sym->name);
Michal Kubecek 39a491
+
Michal Kubecek 39a491
 		if (elf_add_reloc_to_insn(file->elf, sec,
Michal Kubecek 39a491
 					  idx * sizeof(int),
Michal Kubecek 39a491
 					  R_X86_64_PC32,