From ce51f27fb0f8461e61966e01dcd3a91201b5b382 Mon Sep 17 00:00:00 2001 From: Tony Ambardar Date: Mon, 10 Jun 2024 02:17:40 -0700 Subject: [PATCH] kernel: 6.6: prevent garbage-cleanup of BPF kfuncs Backport an upstream Linux fix to prevent BPF kfunc functions from being removed during linker optimization when building BTF-enabled vmlinux. The telltale sign of this occurring is build log warnings (e.g. mips64el): BTFIDS vmlinux WARN: resolve_btfids: unresolved symbol bpf_verify_pkcs7_signature WARN: resolve_btfids: unresolved symbol bpf_lookup_user_key WARN: resolve_btfids: unresolved symbol bpf_lookup_system_key WARN: resolve_btfids: unresolved symbol bpf_key_put WARN: resolve_btfids: unresolved symbol bpf_iter_task_next WARN: resolve_btfids: unresolved symbol bpf_iter_css_task_new WARN: resolve_btfids: unresolved symbol bpf_get_file_xattr WARN: resolve_btfids: unresolved symbol bpf_ct_insert_entry NM System.map SORTTAB vmlinux Link: https://lore.kernel.org/bpf/ZlkoM6%2FPSxVcGM6X@kodidev-ubuntu/ Signed-off-by: Tony Ambardar Link: https://github.com/openwrt/openwrt/pull/15697 Signed-off-by: Christian Marangi --- ....10-compiler_types.h-Define-__retain.patch | 58 +++++++++++++++++ ...n-__bpf_kfunc-against-linker-removal.patch | 65 +++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 target/linux/generic/backport-6.6/065-v6.10-compiler_types.h-Define-__retain.patch create mode 100644 target/linux/generic/backport-6.6/066-v6.10-bpf-Harden-__bpf_kfunc-against-linker-removal.patch diff --git a/target/linux/generic/backport-6.6/065-v6.10-compiler_types.h-Define-__retain.patch b/target/linux/generic/backport-6.6/065-v6.10-compiler_types.h-Define-__retain.patch new file mode 100644 index 0000000000..862207fd0e --- /dev/null +++ b/target/linux/generic/backport-6.6/065-v6.10-compiler_types.h-Define-__retain.patch @@ -0,0 +1,58 @@ +From 443df175be581618d6ff781dc3af3aa1a9ba789d Mon Sep 17 00:00:00 2001 +From: Tony Ambardar +Date: Fri, 31 May 2024 23:55:55 -0700 +Subject: [PATCH 1/2] compiler_types.h: Define __retain for + __attribute__((__retain__)) + +Some code includes the __used macro to prevent functions and data from +being optimized out. This macro implements __attribute__((__used__)), which +operates at the compiler and IR-level, and so still allows a linker to +remove objects intended to be kept. + +Compilers supporting __attribute__((__retain__)) can address this gap by +setting the flag SHF_GNU_RETAIN on the section of a function/variable, +indicating to the linker the object should be retained. This attribute is +available since gcc 11, clang 13, and binutils 2.36. + +Provide a __retain macro implementing __attribute__((__retain__)), whose +first user will be the '__bpf_kfunc' tag. + +Link: https://lore.kernel.org/bpf/ZlmGoT9KiYLZd91S@krava/T/ +Cc: stable@vger.kernel.org # v6.6+ +Signed-off-by: Tony Ambardar +--- + include/linux/compiler_types.h | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/include/linux/compiler_types.h ++++ b/include/linux/compiler_types.h +@@ -145,6 +145,29 @@ static inline void __chk_io_ptr(const vo + #define __has_builtin(x) (0) + #endif + ++/* ++ * Annotating a function/variable with __retain tells the compiler to place ++ * the object in its own section and set the flag SHF_GNU_RETAIN. This flag ++ * instructs the linker to retain the object during garbage-cleanup or LTO ++ * phases. ++ * ++ * Note that the __used macro is also used to prevent functions or data ++ * being optimized out, but operates at the compiler/IR-level and may still ++ * allow unintended removal of objects during linking. ++ * ++ * Optional: only supported since gcc >= 11, clang >= 13 ++ * ++ * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-retain-function-attribute ++ * clang: https://clang.llvm.org/docs/AttributeReference.html#retain ++ */ ++#if __has_attribute(__retain__) && \ ++ (defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || \ ++ defined(CONFIG_LTO_CLANG)) ++# define __retain __attribute__((__retain__)) ++#else ++# define __retain ++#endif ++ + /* Compiler specific macros. */ + #ifdef __clang__ + #include diff --git a/target/linux/generic/backport-6.6/066-v6.10-bpf-Harden-__bpf_kfunc-against-linker-removal.patch b/target/linux/generic/backport-6.6/066-v6.10-bpf-Harden-__bpf_kfunc-against-linker-removal.patch new file mode 100644 index 0000000000..f7e4f4391d --- /dev/null +++ b/target/linux/generic/backport-6.6/066-v6.10-bpf-Harden-__bpf_kfunc-against-linker-removal.patch @@ -0,0 +1,65 @@ +From ac507ed9882fd91a94657d68fe9ceac04b957103 Mon Sep 17 00:00:00 2001 +From: Tony Ambardar +Date: Sat, 1 Jun 2024 00:00:21 -0700 +Subject: [PATCH 2/2] bpf: Harden __bpf_kfunc tag against linker kfunc removal + +BPF kfuncs are often not directly referenced and may be inadvertently +removed by optimization steps during kernel builds, thus the __bpf_kfunc +tag mitigates against this removal by including the __used macro. However, +this macro alone does not prevent removal during linking, and may still +yield build warnings (e.g. on mips64el): + + LD vmlinux + BTFIDS vmlinux + WARN: resolve_btfids: unresolved symbol bpf_verify_pkcs7_signature + WARN: resolve_btfids: unresolved symbol bpf_lookup_user_key + WARN: resolve_btfids: unresolved symbol bpf_lookup_system_key + WARN: resolve_btfids: unresolved symbol bpf_key_put + WARN: resolve_btfids: unresolved symbol bpf_iter_task_next + WARN: resolve_btfids: unresolved symbol bpf_iter_css_task_new + WARN: resolve_btfids: unresolved symbol bpf_get_file_xattr + WARN: resolve_btfids: unresolved symbol bpf_ct_insert_entry + WARN: resolve_btfids: unresolved symbol bpf_cgroup_release + WARN: resolve_btfids: unresolved symbol bpf_cgroup_from_id + WARN: resolve_btfids: unresolved symbol bpf_cgroup_acquire + WARN: resolve_btfids: unresolved symbol bpf_arena_free_pages + NM System.map + SORTTAB vmlinux + OBJCOPY vmlinux.32 + +Update the __bpf_kfunc tag to better guard against linker optimization by +including the new __retain compiler macro, which fixes the warnings above. + +Verify the __retain macro with readelf by checking object flags for 'R': + + $ readelf -Wa kernel/trace/bpf_trace.o + Section Headers: + [Nr] Name Type Address Off Size ES Flg Lk Inf Al + ... + [178] .text.bpf_key_put PROGBITS 00000000 6420 0050 00 AXR 0 0 8 + ... + Key to Flags: + ... + R (retain), D (mbind), p (processor specific) + +Link: https://lore.kernel.org/bpf/ZlmGoT9KiYLZd91S@krava/T/ +Reported-by: kernel test robot +Closes: https://lore.kernel.org/r/202401211357.OCX9yllM-lkp@intel.com/ +Fixes: 57e7c169cd6a ("bpf: Add __bpf_kfunc tag for marking kernel functions as kfuncs") +Cc: stable@vger.kernel.org # v6.6+ +Signed-off-by: Tony Ambardar +--- + include/linux/btf.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/btf.h ++++ b/include/linux/btf.h +@@ -81,7 +81,7 @@ + * as to avoid issues such as the compiler inlining or eliding either a static + * kfunc, or a global kfunc in an LTO build. + */ +-#define __bpf_kfunc __used noinline ++#define __bpf_kfunc __used __retain noinline + + /* + * Return the name of the passed struct, if exists, or halt the build if for -- 2.30.2