summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2026-06-15 00:17:58 -0700
committerAlexei Starovoitov <ast@kernel.org>2026-06-15 00:19:44 -0700
commite4287bf34f97a88c7d9322f5bde828724c073a6b (patch)
treeee165ab68a6fa74352bd7f4843253f9edb4a1fbc
parent4e7c52b178a75d9e733761ccae9fc25eaa7d8583 (diff)
selftests/bpf: Work around llvm stack overflow in crypto progs
clang 23 fails to build crypto_bench.c and crypto_sanity.c with "BPF stack limit exceeded". The progs fill a 408-byte bpf_crypto_params on the stack and pass it to bpf_crypto_ctx_create(). clang 23 copies the byte-aligned cipher/key globals into it one byte at a time through the stack, and keeps more than one copy of the struct around. Together that blows the 512-byte limit. Align the source arrays to 8 bytes so the copy is word-wise, and move params off the stack into a static .bss var. static keeps it out of the skeleton, where bpf_crypto_params is an incomplete type. Either change alone is not enough. Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r--tools/testing/selftests/bpf/progs/crypto_bench.c21
-rw-r--r--tools/testing/selftests/bpf/progs/crypto_sanity.c21
2 files changed, 28 insertions, 14 deletions
diff --git a/tools/testing/selftests/bpf/progs/crypto_bench.c b/tools/testing/selftests/bpf/progs/crypto_bench.c
index 4ac956b26240..4c0a09aa1e6c 100644
--- a/tools/testing/selftests/bpf/progs/crypto_bench.c
+++ b/tools/testing/selftests/bpf/progs/crypto_bench.c
@@ -11,10 +11,19 @@
#include "crypto_common.h"
const volatile unsigned int len = 16;
-char cipher[128] = {};
+/*
+ * cipher[] and key[] are 8-byte aligned and 'params' is kept off the stack to
+ * work around an LLVM code generation bug. clang lowers the memcpy() of these
+ * byte-aligned globals into a per-byte load/store sequence staged on the stack,
+ * and additionally materializes the on-stack 'struct bpf_crypto_params' twice.
+ * Both blow the 512-byte BPF stack limit. Aligning the sources lets clang copy
+ * word-wise, and a global 'params' removes the large object from the stack.
+ */
+char cipher[128] __attribute__((aligned(8))) = {};
u32 key_len, authsize;
char dst[256] = {};
-u8 key[256] = {};
+u8 key[256] __attribute__((aligned(8))) = {};
+static struct bpf_crypto_params params;
long hits = 0;
int status;
@@ -22,11 +31,6 @@ SEC("syscall")
int crypto_setup(void *args)
{
struct bpf_crypto_ctx *cctx;
- struct bpf_crypto_params params = {
- .type = "skcipher",
- .key_len = key_len,
- .authsize = authsize,
- };
int err = 0;
status = 0;
@@ -36,6 +40,9 @@ int crypto_setup(void *args)
return 0;
}
+ __builtin_memcpy(&params.type, "skcipher", sizeof("skcipher"));
+ params.key_len = key_len;
+ params.authsize = authsize;
__builtin_memcpy(&params.algo, cipher, sizeof(cipher));
__builtin_memcpy(&params.key, key, sizeof(key));
cctx = bpf_crypto_ctx_create(&params, sizeof(params), &err);
diff --git a/tools/testing/selftests/bpf/progs/crypto_sanity.c b/tools/testing/selftests/bpf/progs/crypto_sanity.c
index dfd8a258f14a..e81f5ac3b1ae 100644
--- a/tools/testing/selftests/bpf/progs/crypto_sanity.c
+++ b/tools/testing/selftests/bpf/progs/crypto_sanity.c
@@ -10,11 +10,20 @@
#include "bpf_kfuncs.h"
#include "crypto_common.h"
-unsigned char key[256] = {};
+/*
+ * key[] and algo[] are 8-byte aligned and 'params' is kept off the stack to
+ * work around an LLVM code generation bug. clang lowers the memcpy() of these
+ * byte-aligned globals into a per-byte load/store sequence staged on the stack,
+ * and additionally materializes the on-stack 'struct bpf_crypto_params' twice.
+ * Both blow the 512-byte BPF stack limit. Aligning the sources lets clang copy
+ * word-wise, and a global 'params' removes the large object from the stack.
+ */
+unsigned char key[256] __attribute__((aligned(8))) = {};
u16 udp_test_port = 7777;
u32 authsize, key_len;
-char algo[128] = {};
+char algo[128] __attribute__((aligned(8))) = {};
char dst[16] = {}, dst_bad[8] = {};
+static struct bpf_crypto_params params;
int status;
static int skb_dynptr_validate(struct __sk_buff *skb, struct bpf_dynptr *psrc)
@@ -53,11 +62,6 @@ static int skb_dynptr_validate(struct __sk_buff *skb, struct bpf_dynptr *psrc)
SEC("syscall")
int skb_crypto_setup(void *ctx)
{
- struct bpf_crypto_params params = {
- .type = "skcipher",
- .key_len = key_len,
- .authsize = authsize,
- };
struct bpf_crypto_ctx *cctx;
int err;
@@ -67,6 +71,9 @@ int skb_crypto_setup(void *ctx)
return 0;
}
+ __builtin_memcpy(&params.type, "skcipher", sizeof("skcipher"));
+ params.key_len = key_len;
+ params.authsize = authsize;
__builtin_memcpy(&params.algo, algo, sizeof(algo));
__builtin_memcpy(&params.key, key, sizeof(key));