From 442381a84efe29f06d9ae331a36d724c7d24b331 Mon Sep 17 00:00:00 2001 From: Florent Revest Date: Mon, 17 Nov 2025 17:04:51 +0100 Subject: [PATCH] create-diff-object: fix Clang UBSAN diff failure by ignoring unnamed data This fixes a diff failure when generating livepatches for objects compiled with Clang and UBSAN (Undefined Behavior Sanitizer). When UBSAN is enabled, Clang heavily utilizes `.data..L__unnamed_XX` sections to store type descriptors and source location metadata. kpatch-build currently fails to handle these sections, resulting in errors like: fsnotify.o: changed section .data..L__unnamed_1 not selected for inclusion ERROR: fsnotify.o: 1 unsupported section change(s) create-diff-object: unreconcilable difference The numeric suffix (e.g., `_1`) in these section names is an unstable internal counter. If the patch modifies the code, these indices often shift, causing `create-diff-object` to incorrectly correlate unrelated UBSAN metadata between the original and patched objects. Since kpatch cannot support changes to existing data sections, the build aborts. Fix this by treating `.data..L__unnamed_` sections as unstable and uncorrelatable. This patch introduces `is_clang_unnamed_data()` to: 1. Explicitly skip these sections in `kpatch_correlate_sections()`. 2. Prevent `kpatch_correlate_static_local_variables()` from forcing correlation based on symbol usage. This ensures that UBSAN metadata sections are always marked as 'NEW' and allocated safely in the patch module, enabling support for livepatching UBSAN-instrumented kernels. Signed-off-by: Florent Revest --- kpatch-build/create-diff-object.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 09160030..86bc5328 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -396,6 +396,17 @@ static bool is_string_literal_section(struct section *sec) return !strncmp(sec->name, ".rodata.", 8) && strstr(sec->name, ".str"); } +/* + * Clang generates .data..L__unnamed_XX sections for anonymous constants. + * The numeric suffix is unstable (it can change if code is added/removed). + * Therefore, we must never correlate these by name; the patched object + * must always allocate a fresh copy (Status: NEW). + */ +static bool is_clang_unnamed_data(const char *name) +{ + return !strncmp(name, ".data..L__unnamed_", 18); +} + /* * This function detects whether the given symbol is a "special" static local * variable (for lack of a better term). @@ -425,6 +436,10 @@ static bool is_special_static(struct symbol *sym) if (is_dynamic_debug_symbol(sym)) return true; + /* Do not try to correlate statics inside unstable Clang sections */ + if (sym->sec && is_clang_unnamed_data(sym->sec->name)) + return true; + if (sym->type == STT_SECTION) { /* make sure section is bundled */ if (!sym->sec->sym) @@ -1142,6 +1157,11 @@ static void kpatch_correlate_sections(struct list_head *seclist_orig, if (is_ubsan_sec(sec_orig->name)) continue; + /* Skip correlation for unstable Clang anonymous sections */ + if (is_clang_unnamed_data(sec_orig->name) || + is_clang_unnamed_data(sec_patched->name)) + continue; + if (is_special_static(is_rela_section(sec_orig) ? sec_orig->base->secsym : sec_orig->secsym))