Commit 7e0b172c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'objtool-urgent-2026-02-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull objtool fixes from Ingo Molnar::

 - Bump up the Clang minimum version requirements for livepatch
   builds, due to Clang assembler section handling bugs causing
   silent miscompilations

 - Strip livepatching symbol artifacts from non-livepatch modules

 - Fix livepatch build warnings when certain Clang LTO options
   are enabled

 - Fix livepatch build error when CONFIG_MEM_ALLOC_PROFILING_DEBUG=y

* tag 'objtool-urgent-2026-02-07' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  objtool/klp: Fix unexported static call key access for manually built livepatch modules
  objtool/klp: Fix symbol correlation for orphaned local symbols
  livepatch: Free klp_{object,func}_ext data after initialization
  livepatch: Fix having __klp_objects relics in non-livepatch modules
  livepatch/klp-build: Require Clang assembler >= 20
parents 2687c848 f495054b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -175,6 +175,9 @@ int klp_enable_patch(struct klp_patch *);
int klp_module_coming(struct module *mod);
void klp_module_going(struct module *mod);

void *klp_find_section_by_name(const struct module *mod, const char *name,
			       size_t *sec_size);

void klp_copy_process(struct task_struct *child);
void klp_update_patch_state(struct task_struct *task);

+19 −0
Original line number Diff line number Diff line
@@ -1356,6 +1356,25 @@ void klp_module_going(struct module *mod)
	mutex_unlock(&klp_mutex);
}

void *klp_find_section_by_name(const struct module *mod, const char *name,
			       size_t *sec_size)
{
	struct klp_modinfo *info = mod->klp_info;

	for (int i = 1; i < info->hdr.e_shnum; i++) {
		Elf_Shdr *shdr = &info->sechdrs[i];

		if (!strcmp(info->secstrings + shdr->sh_name, name)) {
			*sec_size = shdr->sh_size;
			return (void *)shdr->sh_addr;
		}
	}

	*sec_size = 0;
	return NULL;
}
EXPORT_SYMBOL_GPL(klp_find_section_by_name);

static int __init klp_init(void)
{
	klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);
+9 −11
Original line number Diff line number Diff line
@@ -9,19 +9,19 @@
#include <linux/slab.h>
#include <linux/livepatch.h>

extern struct klp_object_ext __start_klp_objects[];
extern struct klp_object_ext __stop_klp_objects[];

static struct klp_patch *patch;

static int __init livepatch_mod_init(void)
{
	struct klp_object_ext *obj_exts;
	size_t obj_exts_sec_size;
	struct klp_object *objs;
	unsigned int nr_objs;
	int ret;

	nr_objs = __stop_klp_objects - __start_klp_objects;

	obj_exts = klp_find_section_by_name(THIS_MODULE, ".init.klp_objects",
					    &obj_exts_sec_size);
	nr_objs = obj_exts_sec_size / sizeof(*obj_exts);
	if (!nr_objs) {
		pr_err("nothing to patch!\n");
		ret = -EINVAL;
@@ -41,7 +41,7 @@ static int __init livepatch_mod_init(void)
	}

	for (int i = 0; i < nr_objs; i++) {
		struct klp_object_ext *obj_ext = __start_klp_objects + i;
		struct klp_object_ext *obj_ext = obj_exts + i;
		struct klp_func_ext *funcs_ext = obj_ext->funcs;
		unsigned int nr_funcs = obj_ext->nr_funcs;
		struct klp_func *funcs = objs[i].funcs;
@@ -90,12 +90,10 @@ static int __init livepatch_mod_init(void)

static void __exit livepatch_mod_exit(void)
{
	unsigned int nr_objs;

	nr_objs = __stop_klp_objects - __start_klp_objects;
	struct klp_object *obj;

	for (int i = 0; i < nr_objs; i++)
		kfree(patch->objs[i].funcs);
	klp_for_each_object_static(patch, obj)
		kfree(obj->funcs);

	kfree(patch->objs);
	kfree(patch);
+4 −0
Original line number Diff line number Diff line
@@ -249,6 +249,10 @@ validate_config() {
	[[ -v CONFIG_GCC_PLUGIN_RANDSTRUCT ]] &&	\
		die "kernel option 'CONFIG_GCC_PLUGIN_RANDSTRUCT' not supported"

	[[ -v CONFIG_AS_IS_LLVM ]] &&				\
		[[ "$CONFIG_AS_VERSION" -lt 200000 ]] &&	\
		die "Clang assembler version < 20 not supported"

	return 0
}

+2 −7
Original line number Diff line number Diff line
@@ -34,13 +34,8 @@ SECTIONS {

	__patchable_function_entries : { *(__patchable_function_entries) }

	__klp_funcs		0: ALIGN(8) { KEEP(*(__klp_funcs)) }

	__klp_objects		0: ALIGN(8) {
		__start_klp_objects = .;
		KEEP(*(__klp_objects))
		__stop_klp_objects = .;
	}
	.init.klp_funcs		0 : ALIGN(8) { KEEP(*(.init.klp_funcs)) }
	.init.klp_objects	0 : ALIGN(8) { KEEP(*(.init.klp_objects)) }

#ifdef CONFIG_ARCH_USES_CFI_TRAPS
	__kcfi_traps		: { KEEP(*(.kcfi_traps)) }
Loading