linux-postmarketos-qcom-sdm845: sync kconfig

Adds two patches to fix BPF for this kernel version.

Signed-off-by: Aster Boese <asterboese@mailbox.org>
Part-of: <https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/8986>
This commit is contained in:
Aster Boese 2026-07-09 20:19:28 +02:00 committed by The Friendly Meow (merge) Bot
parent 61d5db0ca4
commit e2b8338e09
No known key found for this signature in database
5 changed files with 368 additions and 27 deletions

View file

@ -5,25 +5,32 @@ maintainer="Casey Connolly <kcxt@postmarketos.org>"
_flavor="postmarketos-qcom-sdm845"
pkgname=linux-$_flavor
pkgver=7.1_rc1
pkgrel=2
pkgrel=3
pkgdesc="Mainline Kernel fork for SDM845 devices"
arch="aarch64"
_carch="arm64"
url="https://gitlab.com/sdm845-mainline/linux"
license="GPL-2.0-only"
options="!check !tracedeps
options="
!check
!strip
!tracedeps
pmb:cross-native
pmb:kconfigcheck-community"
pmb:kconfigcheck-community
"
makedepends="
bison
clang
elfutils-dev
findutils
flex
installkernel
linux-headers
lld
llvm
openssl-dev
pahole
perl
postmarketos-installkernel
python3
zstd
"
@ -34,6 +41,8 @@ _tag="sdm845-7.1-rc1-r0"
source="
linux-$_tag.tar.gz::https://gitlab.com/sdm845-mainline/linux/-/archive/$_tag/linux-$_tag.tar.gz
config-postmarketos-qcom-sdm845.aarch64
libbpf-Fix-UAF-in-strset__add_str.patch
enable-dynamic-ftrace.patch
"
builddir="$srcdir/linux-$_tag"
@ -83,5 +92,7 @@ package() {
sha512sums="
94da173aaf74dd33ef8ff9015e92759481cd0da5bd8a1e52c8664fd372d48a1155655001ad2e9d26557733c71ae8bc448e4ebdf1372b8f32159907a35f0306a9 linux-sdm845-7.1-rc1-r0.tar.gz
1a06ce39a35dc9dbcae82410f71cfbc8f705411bfdd23560eabb61a44ab6ddeee7d54422e6351f0d918cce77d101b9f2d952d65dd25e29aa388b848492714ec0 config-postmarketos-qcom-sdm845.aarch64
d330554e6e9827c15200b4e9196fbe06a117ba01cc1e8683dc8e9d2403898a4412925e92fa8c47638c184f19d968093f5c3804eca2b5fab41af0e95c495daa6e config-postmarketos-qcom-sdm845.aarch64
e2555390d48cbbdc32a7d3f0c27599ff88f2fe3e786d1d0086caaa5b092cc3edcb6e95e2fb07034edb3793f6dc954da0662c723202eb7e2c4956c99b50919b12 libbpf-Fix-UAF-in-strset__add_str.patch
e8b595f3e076896dc38f249c8908d58e2e6a858eaa77fe1e680f27db0e76d3d74c0b5dfebb7a4c57d546fee0b0f6eb81a38b20dfd72f985c9d02f28d79a5eceb enable-dynamic-ftrace.patch
"

View file

@ -2,15 +2,15 @@
# Automatically generated file; DO NOT EDIT.
# Linux/arm64 7.1.0-rc1 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="Alpine clang version 22.1.3"
CONFIG_CC_VERSION_TEXT="Alpine clang version 22.1.8"
CONFIG_GCC_VERSION=0
CONFIG_CC_IS_CLANG=y
CONFIG_CLANG_VERSION=220103
CONFIG_CLANG_VERSION=220108
CONFIG_AS_IS_LLVM=y
CONFIG_AS_VERSION=220103
CONFIG_AS_VERSION=220108
CONFIG_LD_VERSION=0
CONFIG_LD_IS_LLD=y
CONFIG_LLD_VERSION=220103
CONFIG_LLD_VERSION=220108
CONFIG_RUSTC_VERSION=0
CONFIG_RUSTC_LLVM_VERSION=0
CONFIG_RUSTC_LLVM_MAJOR_VERSION=0
@ -25,7 +25,7 @@ CONFIG_CC_HAS_COUNTED_BY=y
CONFIG_CC_HAS_COUNTED_BY_PTR=y
CONFIG_CC_HAS_MULTIDIMENSIONAL_NONSTRING=y
CONFIG_LD_CAN_USE_KEEP_IN_OVERLAY=y
CONFIG_PAHOLE_VERSION=0
CONFIG_PAHOLE_VERSION=131
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y
@ -124,6 +124,7 @@ CONFIG_PREEMPT_COUNT=y
CONFIG_PREEMPTION=y
# CONFIG_PREEMPT_DYNAMIC is not set
# CONFIG_SCHED_CORE is not set
# CONFIG_SCHED_CLASS_EXT is not set
#
# CPU/Task time and stats accounting
@ -921,6 +922,7 @@ CONFIG_HAVE_ARCH_GET_SECUREBOOT=y
# end of General architecture-dependent options
CONFIG_RT_MUTEXES=y
CONFIG_MODULE_SIG_FORMAT=y
CONFIG_MODULES=y
# CONFIG_MODULE_DEBUG is not set
# CONFIG_MODULE_FORCE_LOAD is not set
@ -929,7 +931,16 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_MODULE_SIG is not set
CONFIG_MODULE_SIG=y
# CONFIG_MODULE_SIG_FORCE is not set
CONFIG_MODULE_SIG_ALL=y
# CONFIG_MODULE_SIG_SHA256 is not set
# CONFIG_MODULE_SIG_SHA384 is not set
CONFIG_MODULE_SIG_SHA512=y
# CONFIG_MODULE_SIG_SHA3_256 is not set
# CONFIG_MODULE_SIG_SHA3_384 is not set
# CONFIG_MODULE_SIG_SHA3_512 is not set
CONFIG_MODULE_SIG_HASH="sha512"
CONFIG_MODULE_COMPRESS=y
# CONFIG_MODULE_COMPRESS_GZIP is not set
# CONFIG_MODULE_COMPRESS_XZ is not set
@ -1592,6 +1603,7 @@ CONFIG_NET_SCH_MULTIQ=m
# CONFIG_NET_SCH_PIE is not set
# CONFIG_NET_SCH_PLUG is not set
# CONFIG_NET_SCH_ETS is not set
# CONFIG_NET_SCH_BPF is not set
# CONFIG_NET_SCH_DUALPI2 is not set
# CONFIG_NET_SCH_DEFAULT is not set
@ -6092,6 +6104,7 @@ CONFIG_HID_MCP2221=m
#
# HID-BPF support
#
# CONFIG_HID_BPF is not set
# end of HID-BPF support
CONFIG_I2C_HID=y
@ -8499,14 +8512,14 @@ CONFIG_XFS_ONLINE_REPAIR=y
# CONFIG_XFS_DEBUG is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
# CONFIG_BTRFS_DEBUG is not set
# CONFIG_BTRFS_ASSERT is not set
# CONFIG_BTRFS_EXPERIMENTAL is not set
# CONFIG_NILFS2_FS is not set
CONFIG_F2FS_FS=y
CONFIG_F2FS_FS=m
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
CONFIG_F2FS_FS_POSIX_ACL=y
@ -8810,7 +8823,7 @@ CONFIG_SECURITY=y
CONFIG_HAS_SECURITY_AUDIT=y
CONFIG_SECURITYFS=y
# CONFIG_SECURITY_NETWORK is not set
# CONFIG_SECURITY_PATH is not set
CONFIG_SECURITY_PATH=y
# CONFIG_STATIC_USERMODEHELPER is not set
# CONFIG_SECURITY_SMACK is not set
# CONFIG_SECURITY_TOMOYO is not set
@ -8818,7 +8831,11 @@ CONFIG_SECURITYFS=y
# CONFIG_SECURITY_LOADPIN is not set
CONFIG_SECURITY_YAMA=y
# CONFIG_SECURITY_SAFESETID is not set
# CONFIG_SECURITY_LOCKDOWN_LSM is not set
CONFIG_SECURITY_LOCKDOWN_LSM=y
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y
# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set
# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set
# CONFIG_SECURITY_LANDLOCK is not set
# CONFIG_SECURITY_IPE is not set
CONFIG_INTEGRITY=y
@ -8828,7 +8845,7 @@ CONFIG_INTEGRITY_AUDIT=y
# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set
# CONFIG_EVM is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,ipe,bpf"
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,selinux,smack,tomoyo,ipe,bpf"
#
# Kernel hardening options
@ -8902,7 +8919,7 @@ CONFIG_CRYPTO_USER=y
# CONFIG_CRYPTO_PCRYPT is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_KRB5ENC is not set
CONFIG_CRYPTO_KRB5ENC=m
CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_ENGINE=m
# end of Crypto core or helper
@ -9092,6 +9109,12 @@ CONFIG_PKCS7_MESSAGE_PARSER=y
#
# Certificates for signature checking
#
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
CONFIG_MODULE_SIG_KEY_TYPE_RSA=y
# CONFIG_MODULE_SIG_KEY_TYPE_ECDSA is not set
# CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_44 is not set
# CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_65 is not set
# CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_87 is not set
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS=""
# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set
@ -9100,13 +9123,14 @@ CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_OPENSSL_SUPPORTS_ML_DSA=y
# end of Certificates for signature checking
# CONFIG_CRYPTO_KRB5 is not set
CONFIG_CRYPTO_KRB5=m
# CONFIG_CRYPTO_KRB5_SELFTESTS is not set
CONFIG_BINARY_PRINTF=y
#
# Library routines
#
CONFIG_RAID6_PQ=y
CONFIG_RAID6_PQ=m
# CONFIG_RAID6_PQ_BENCHMARK is not set
CONFIG_LINEAR_RANGES=y
CONFIG_PACKING=y
@ -9142,7 +9166,7 @@ CONFIG_CRYPTO_LIB_AES_ARCH=y
CONFIG_CRYPTO_LIB_AES_CBC_MACS=y
CONFIG_CRYPTO_LIB_ARC4=m
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_BLAKE2B=y
CONFIG_CRYPTO_LIB_BLAKE2B=m
CONFIG_CRYPTO_LIB_CHACHA=m
CONFIG_CRYPTO_LIB_CHACHA_ARCH=y
CONFIG_CRYPTO_LIB_CURVE25519=m
@ -9165,7 +9189,7 @@ CONFIG_CRYPTO_LIB_SHA3=m
CONFIG_CRYPTO_LIB_SHA3_ARCH=y
CONFIG_CRYPTO_LIB_SM3=m
CONFIG_CRYPTO_LIB_SM3_ARCH=y
CONFIG_XOR_BLOCKS=y
CONFIG_XOR_BLOCKS=m
CONFIG_XOR_BLOCKS_ARCH=y
CONFIG_XXHASH=y
CONFIG_AUDIT_GENERIC=y
@ -9312,14 +9336,19 @@ CONFIG_DEBUG_MISC=y
CONFIG_DEBUG_INFO=y
CONFIG_AS_HAS_NON_CONST_ULEB128=y
# CONFIG_DEBUG_INFO_NONE is not set
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
# CONFIG_DEBUG_INFO_DWARF4 is not set
# CONFIG_DEBUG_INFO_DWARF5 is not set
CONFIG_DEBUG_INFO_REDUCED=y
CONFIG_DEBUG_INFO_DWARF5=y
# CONFIG_DEBUG_INFO_REDUCED is not set
CONFIG_DEBUG_INFO_COMPRESSED_NONE=y
# CONFIG_DEBUG_INFO_COMPRESSED_ZLIB is not set
# CONFIG_DEBUG_INFO_COMPRESSED_ZSTD is not set
# CONFIG_DEBUG_INFO_SPLIT is not set
CONFIG_DEBUG_INFO_BTF=y
CONFIG_PAHOLE_HAS_BTF_TAG=y
CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
CONFIG_DEBUG_INFO_BTF_MODULES=y
# CONFIG_MODULE_ALLOW_BTF_MISMATCH is not set
# CONFIG_GDB_SCRIPTS is not set
CONFIG_FRAME_WARN=2048
# CONFIG_STRIP_ASM_SYMS is not set
@ -9485,6 +9514,7 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_FREGS=y
CONFIG_HAVE_FTRACE_GRAPH_FUNC=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
CONFIG_HAVE_EXTRA_IPI_TRACEPOINTS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
@ -9505,7 +9535,9 @@ CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
# CONFIG_FUNCTION_GRAPH_RETVAL is not set
# CONFIG_FUNCTION_GRAPH_RETADDR is not set
CONFIG_FUNCTION_TRACE_ARGS=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
CONFIG_DYNAMIC_FTRACE_WITH_ARGS=y
# CONFIG_FUNCTION_SELF_TRACING is not set
# CONFIG_FPROBE is not set
@ -9523,6 +9555,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
CONFIG_PROBE_EVENTS_BTF_ARGS=y
CONFIG_KPROBE_EVENTS=y
# CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set
CONFIG_UPROBE_EVENTS=y
@ -9638,3 +9671,4 @@ CONFIG_MEMTEST=y
CONFIG_IO_URING_ZCRX=y
CONFIG_IO_URING_BPF=y
CONFIG_IO_URING_BPF_OPS=y

View file

@ -0,0 +1,124 @@
From d81e256317f22d08afbdd8da83cda875d058b97f Mon Sep 17 00:00:00 2001
From: "Jose Fernandez (Anthropic)" <jose.fernandez@linux.dev>
Date: Tue, 9 Jun 2026 05:19:26 +0000
Subject: [PATCH 1/2] arm64: ftrace: prepare ftrace_modify_call() for use
without CALL_OPS
ftrace_modify_call() is guarded by CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
and calls ftrace_rec_set_ops(rec, arm64_rec_get_ops(rec)) directly,
which only exists when CALL_OPS is enabled.
Generic ftrace also needs ftrace_modify_call() when
CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS is enabled, to retarget a
callsite between two non-FTRACE_ADDR destinations, as happens when a
direct trampoline is modified. The next patch allows DIRECT_CALLS without
CALL_OPS, so widen the guard to cover both configurations and switch
the body to the ftrace_rec_update_ops() wrapper, which already has a
stub for the !CALL_OPS case. ftrace_make_call() already uses the same
wrapper today.
No functional change: with CALL_OPS enabled, ftrace_rec_update_ops()
expands to the exact call this replaces.
Assisted-by: Claude:unspecified
Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
Reviewed-by: Puranjay Mohan <puranjay@kernel.org>
---
arch/arm64/kernel/ftrace.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
index 5a1554a441628..e1a3c0b3a0514 100644
--- a/arch/arm64/kernel/ftrace.c
+++ b/arch/arm64/kernel/ftrace.c
@@ -409,7 +409,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return ftrace_modify_code(pc, old, new, true);
}
-#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
+#if defined(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS) || \
+ defined(CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS)
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr)
{
@@ -417,7 +418,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
u32 old, new;
int ret;
- ret = ftrace_rec_set_ops(rec, arm64_rec_get_ops(rec));
+ ret = ftrace_rec_update_ops(rec);
if (ret)
return ret;
--
2.54.0
From c7d8dc4cd612aec63b954e13a2a940308d6c769e Mon Sep 17 00:00:00 2001
From: "Jose Fernandez (Anthropic)" <jose.fernandez@linux.dev>
Date: Tue, 9 Jun 2026 05:19:27 +0000
Subject: [PATCH 2/2] arm64: ftrace: allow DIRECT_CALLS without CALL_OPS
arm64 gained ftrace direct calls in commit 2aa6ac03516d ("arm64:
ftrace: Add direct call support") on top of
DYNAMIC_FTRACE_WITH_CALL_OPS, using the per-callsite ops pointer as a
fast path to reach the direct trampoline. Since commit baaf553d3bc3
("arm64: Implement HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS"), CALL_OPS is
mutually exclusive with CFI: the pre-function NOPs would change the
offset of the pre-function kCFI type hash, and the compiler support
needed to keep that offset consistent does not exist yet.
The result is that a CONFIG_CFI=y kernel loses CALL_OPS, and with it
DIRECT_CALLS, and with it every BPF trampoline attachment to kernel
functions: register_fentry() returns -ENOTSUPP, so fentry/fexit,
fmod_ret and BPF LSM programs cannot attach at all. This is a real
problem for hardened arm64 deployments that rely on BPF LSM for
security monitoring while keeping kCFI enabled.
CALL_OPS is an optimization for direct calls, not a dependency. When
the direct trampoline is within BL range, the callsite branches
straight to it and ftrace_caller is not involved. When it is out of
range, ftrace_find_callable_addr() already falls back to
ftrace_caller, and the DIRECT_CALLS machinery there
(FREGS_DIRECT_TRAMP, ftrace_caller_direct_late) is gated on
DIRECT_CALLS alone, not CALL_OPS: the ops dispatch invokes
call_direct_funcs(), which stores the trampoline address in
ftrace_regs, and ftrace_caller tail-calls it. s390 and loongarch use
this same mechanism for HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS without
having CALL_OPS at all, and DYNAMIC_FTRACE_WITH_ARGS without CALL_OPS
is already a supported arm64 configuration (GCC builds with
CC_OPTIMIZE_FOR_SIZE do not satisfy the CALL_OPS select condition).
Drop the CALL_OPS requirement from the
HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS select. Configurations that
keep CALL_OPS (!CFI clang builds, and GCC builds without
CC_OPTIMIZE_FOR_SIZE) are unchanged. CALL_OPS-less configurations
take the ftrace_caller ops-dispatch path for out-of-range direct
calls, trading the per-callsite fast path for working BPF
trampolines; in-range attachments still branch directly with no
overhead. GCC -Os builds also gain DIRECT_CALLS as a side effect.
That is intended: s390 and loongarch already ship DIRECT_CALLS
without any per-callsite fast path.
Assisted-by: Claude:unspecified
Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
Reviewed-by: Puranjay Mohan <puranjay@kernel.org>
---
arch/arm64/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index edbaec4b6eead..532ce0d77069a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -214,7 +214,7 @@ config ARM64
if (GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS || \
CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS)
select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \
- if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS
+ if DYNAMIC_FTRACE_WITH_ARGS
select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \
if (DYNAMIC_FTRACE_WITH_ARGS && !CFI && \
(CC_IS_CLANG || !CC_OPTIMIZE_FOR_SIZE))
--
2.54.0

View file

@ -0,0 +1,161 @@
From b23705e6afb6ac4ae6d220dcb35975698667dd76 Mon Sep 17 00:00:00 2001
From: Carlos Llamas <cmllamas@google.com>
Date: Sat, 23 May 2026 16:27:21 +0000
Subject: [PATCH] libbpf: Fix UAF in strset__add_str()
strset_add_str_mem() might reallocate the strset data buffer in order to
accommodate the provided string 's'. However, if 's' points to a string
already present in the buffer, it becomes dangling after the realloc.
This leads to a use-after-free when attempting to memcpy() the string
into the new buffer.
One scenario that triggers this problematic path is when resolve_btfids
attempts to patch kfunc prototypes using existing BTF parameter names:
| resolve_btfids: function bpf_list_push_back_impl already exists in BTF
| Segmentation fault (core dumped)
Compiling resolve_btfids with fsanitize=address generates a detailed
report of the UAF:
| =================================================================
| ERROR: AddressSanitizer: heap-use-after-free on address 0x7f4c4a500bd4
| ==1507892==ERROR: AddressSanitizer: heap-use-after-free on address 0x7f4c4a500bd4 at pc 0x55d25155a2a8 bp 0x7ffcef879060 sp 0x7ffcef878818
| READ of size 5 at 0x7f4c4a500bd4 thread T0
| #0 0x55d25155a2a7 in memcpy (tools/bpf/resolve_btfids/resolve_btfids+0xcf2a7)
| #1 0x55d2515d708e in strset__add_str tools/lib/bpf/strset.c:162:2
| #2 0x55d2515c730b in btf__add_str tools/lib/bpf/btf.c:2109:8
| #3 0x55d2515c9020 in btf__add_func_param tools/lib/bpf/btf.c:3108:14
| #4 0x55d25159f0b5 in process_kfunc_with_implicit_args tools/bpf/resolve_btfids/main.c:1196:9
| #5 0x55d25159e004 in btf2btf tools/bpf/resolve_btfids/main.c:1229:9
| #6 0x55d25159cee7 in main tools/bpf/resolve_btfids/main.c:1535:6
| #7 0x7f4c78e29f76 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
| #8 0x7f4c78e2a026 in __libc_start_main csu/../csu/libc-start.c:360:3
| #9 0x55d2514bb860 in _start (tools/bpf/resolve_btfids/resolve_btfids+0x30860)
|
| 0x7f4c4a500bd4 is located 13268 bytes inside of 2829000-byte region [0x7f4c4a4fd800,0x7f4c4a7b02c8)
| freed by thread T0 here:
| #0 0x55d25155b700 in realloc (tools/bpf/resolve_btfids/resolve_btfids+0xd0700)
| #1 0x55d2515c426c in libbpf_reallocarray tools/lib/bpf/./libbpf_internal.h:220:9
| #2 0x55d2515c426c in libbpf_add_mem tools/lib/bpf/btf.c:224:13
|
| previously allocated by thread T0 here:
| #0 0x55d25155b2e3 in malloc (tools/bpf/resolve_btfids/resolve_btfids+0xd02e3)
| #1 0x55d2515d6e7d in strset__new tools/lib/bpf/strset.c:58:20
While resolve_btfids could be refactored to avoid this call path, let's
instead fix this issue at the source in strset__add_str() and avoid
similar scenarios.
Let's check if set->strs_data was reallocated and whether 's' points to
an internal string within the old strset buffer. In such case, 's' is
reconstructed to point to the new buffer.
While already here, also fix strset__find_str() which suffers from the
same problem by factoring out the common operations into a new helper
function strset_str_append().
Fixes: 90d76d3ececc ("libbpf: Extract internal set-of-strings datastructure APIs")
Suggested-by: Andrii Nakryiko <andrii@kernel.org>
Suggested-by: Mykyta Yatsenko <yatsenko@meta.com>
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260523162722.2718940-1-cmllamas@google.com
---
tools/lib/bpf/strset.c | 62 ++++++++++++++++++++++++++++--------------
1 file changed, 41 insertions(+), 21 deletions(-)
diff --git a/tools/lib/bpf/strset.c b/tools/lib/bpf/strset.c
index 2464bcbd04e037..ace73c6b3d62b4 100644
--- a/tools/lib/bpf/strset.c
+++ b/tools/lib/bpf/strset.c
@@ -107,6 +107,41 @@ static void *strset_add_str_mem(struct strset *set, size_t add_sz)
set->strs_data_len, set->strs_data_max_len, add_sz);
}
+static long strset_str_append(struct strset *set, const char *s)
+{
+ uintptr_t old_data = (uintptr_t)set->strs_data;
+ size_t old_data_len = set->strs_data_len;
+ uintptr_t old_s = (uintptr_t)s;
+ long len = strlen(s) + 1;
+ void *p;
+
+ /*
+ * Hashmap keys are always offsets within set->strs_data, so to even
+ * look up some string from the "outside", we need to first append it
+ * at the end, so that it can be addressed with an offset. Luckily,
+ * until set->strs_data_len is incremented, that string is just a piece
+ * of garbage for the rest of the code, so no harm, no foul. On the
+ * other hand, if the string is unique, it's already appended and
+ * ready to be used, only a simple set->strs_data_len increment away.
+ */
+ p = strset_add_str_mem(set, len);
+ if (!p)
+ return -ENOMEM;
+
+ /*
+ * The set->strs_data might have reallocated and if 's' pointed
+ * to an internal string within the old buffer, then it became
+ * dangling and needs to be reconstructed before the copy.
+ */
+ if (old_data && old_data != (uintptr_t)set->strs_data &&
+ old_s >= old_data && old_s < old_data + old_data_len)
+ s = set->strs_data + (old_s - old_data);
+
+ memcpy(p, s, len);
+
+ return len;
+}
+
/* Find string offset that corresponds to a given string *s*.
* Returns:
* - >0 offset into string data, if string is found;
@@ -116,16 +151,12 @@ static void *strset_add_str_mem(struct strset *set, size_t add_sz)
int strset__find_str(struct strset *set, const char *s)
{
long old_off, new_off, len;
- void *p;
- /* see strset__add_str() for why we do this */
- len = strlen(s) + 1;
- p = strset_add_str_mem(set, len);
- if (!p)
- return -ENOMEM;
+ len = strset_str_append(set, s);
+ if (len < 0)
+ return len;
new_off = set->strs_data_len;
- memcpy(p, s, len);
if (hashmap__find(set->strs_hash, new_off, &old_off))
return old_off;
@@ -142,24 +173,13 @@ int strset__find_str(struct strset *set, const char *s)
int strset__add_str(struct strset *set, const char *s)
{
long old_off, new_off, len;
- void *p;
int err;
- /* Hashmap keys are always offsets within set->strs_data, so to even
- * look up some string from the "outside", we need to first append it
- * at the end, so that it can be addressed with an offset. Luckily,
- * until set->strs_data_len is incremented, that string is just a piece
- * of garbage for the rest of the code, so no harm, no foul. On the
- * other hand, if the string is unique, it's already appended and
- * ready to be used, only a simple set->strs_data_len increment away.
- */
- len = strlen(s) + 1;
- p = strset_add_str_mem(set, len);
- if (!p)
- return -ENOMEM;
+ len = strset_str_append(set, s);
+ if (len < 0)
+ return len;
new_off = set->strs_data_len;
- memcpy(p, s, len);
/* Now attempt to add the string, but only if the string with the same
* contents doesn't exist already (HASHMAP_ADD strategy). If such

View file

@ -11,12 +11,14 @@ CONFIG_DM_CRYPT=y
CONFIG_FB=y
CONFIG_INPUT_EVDEV=m
# CONFIG_KINETO_GAN is not set
CONFIG_NLS_ASCII=y
# CONFIG_PFT is not set
# CONFIG_SEC_RESTRICT_ROOTING is not set
CONFIG_SYN_COOKIES=y
CONFIG_SYSVIPC=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_USE_VFB is not set
CONFIG_VFAT_FS=y
CONFIG_VT=y
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_BINFMT_SCRIPT=y
@ -34,6 +36,10 @@ CONFIG_UDMABUF=y
CONFIG_BPF=y
CONFIG_BPF_JIT=y
CONFIG_BPF_LSM=y
CONFIG_DEBUG_INFO_BTF=y
CONFIG_DEBUG_INFO_BTF_MODULES=y
CONFIG_DEBUG_INFO_DWARF5=y
# CONFIG_DEBUG_INFO_REDUCED is not set
CONFIG_IPC_NS=y
CONFIG_KPROBES=y
CONFIG_KPROBE_EVENTS=y
@ -41,6 +47,7 @@ CONFIG_NET_NS=y
CONFIG_PID_NS=y
CONFIG_SECURITY=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_PATH=y
CONFIG_USER_NS=y
CONFIG_UTS_NS=y
@ -50,6 +57,7 @@ CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CMAC=m
CONFIG_CRYPTO_CTS=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_KRB5=m
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_FSCACHE=y
@ -66,10 +74,10 @@ CONFIG_NFS_V3=m
CONFIG_NFS_V4=m
CONFIG_NFS_V4_2=y
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1=y
CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2=y
CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA=y
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
# accessibility
CONFIG_A11Y_BRAILLE_CONSOLE=y
@ -261,14 +269,14 @@ CONFIG_NF_TABLES_IPV6=y
CONFIG_WIREGUARD=m
# filesystems
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_EROFS_FS=m
CONFIG_EROFS_FS_ZIP=y
CONFIG_EROFS_FS_ZIP_LZMA=y
CONFIG_EXFAT_FS=m
CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
CONFIG_F2FS_FS=m
CONFIG_UDF_FS=m
CONFIG_XFS_FS=m
CONFIG_EROFS_FS_ZIP_DEFLATE=y
@ -475,7 +483,10 @@ CONFIG_EFIVAR_FS=m
CONFIG_DM_VERITY=m
# hardening
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,selinux,smack,tomoyo,ipe,bpf"
CONFIG_SECURITY_DMESG_RESTRICT=y
CONFIG_SECURITY_LOCKDOWN_LSM=y
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
CONFIG_SECURITY_YAMA=y
CONFIG_SHADOW_CALL_STACK=y
CONFIG_CFI=y