Skip to content

Commit 25c388f

Browse files
borkmannKernel Patches Daemon
authored andcommitted
selftests/bpf: Extend crypto_sanity selftest with invalid dst buffer
Small cleanup and test extension to probe the bpf_crypto_{encrypt,decrypt}() kfunc when a bad dst buffer is passed in to assert that an error is returned. Also, encrypt_sanity() and skb_crypto_setup() were explicit to set the global status variable to zero before any test, so do the same for decrypt_sanity(). Do not explicitly zero the on-stack err before bpf_crypto_ctx_create() given the kfunc is expected to do it internally for the success case. Before kernel fix: # ./vmtest.sh -- ./test_progs -t crypto [...] [ 1.531200] bpf_testmod: loading out-of-tree module taints kernel. [ 1.533388] bpf_testmod: module verification failed: signature and/or required key missing - tainting kernel #87/1 crypto_basic/crypto_release:OK #87/2 crypto_basic/crypto_acquire:OK #87 crypto_basic:OK test_crypto_sanity:PASS:skel open 0 nsec test_crypto_sanity:PASS:ip netns add crypto_sanity_ns 0 nsec test_crypto_sanity:PASS:ip -net crypto_sanity_ns -6 addr add face::1/128 dev lo nodad 0 nsec test_crypto_sanity:PASS:ip -net crypto_sanity_ns link set dev lo up 0 nsec test_crypto_sanity:PASS:open_netns 0 nsec test_crypto_sanity:PASS:AF_ALG init fail 0 nsec test_crypto_sanity:PASS:if_nametoindex lo 0 nsec test_crypto_sanity:PASS:skb_crypto_setup fd 0 nsec test_crypto_sanity:PASS:skb_crypto_setup 0 nsec test_crypto_sanity:PASS:skb_crypto_setup retval 0 nsec test_crypto_sanity:PASS:skb_crypto_setup status 0 nsec test_crypto_sanity:PASS:create qdisc hook 0 nsec test_crypto_sanity:PASS:make_sockaddr 0 nsec test_crypto_sanity:PASS:attach encrypt filter 0 nsec test_crypto_sanity:PASS:encrypt socket 0 nsec test_crypto_sanity:PASS:encrypt send 0 nsec test_crypto_sanity:FAIL:encrypt status unexpected error: -5 (errno 95) #88 crypto_sanity:FAIL Summary: 1/2 PASSED, 0 SKIPPED, 1 FAILED After kernel fix: # ./vmtest.sh -- ./test_progs -t crypto [...] [ 1.540963] bpf_testmod: loading out-of-tree module taints kernel. [ 1.542404] bpf_testmod: module verification failed: signature and/or required key missing - tainting kernel #87/1 crypto_basic/crypto_release:OK #87/2 crypto_basic/crypto_acquire:OK #87 crypto_basic:OK #88 crypto_sanity:OK Summary: 2/2 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Cc: Vadim Fedorenko <vadim.fedorenko@linux.dev>
1 parent c488d50 commit 25c388f

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

tools/testing/selftests/bpf/progs/crypto_sanity.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ unsigned char key[256] = {};
1414
u16 udp_test_port = 7777;
1515
u32 authsize, key_len;
1616
char algo[128] = {};
17-
char dst[16] = {};
17+
char dst[16] = {}, dst_bad[8] = {};
1818
int status;
1919

2020
static int skb_dynptr_validate(struct __sk_buff *skb, struct bpf_dynptr *psrc)
@@ -59,19 +59,18 @@ int skb_crypto_setup(void *ctx)
5959
.authsize = authsize,
6060
};
6161
struct bpf_crypto_ctx *cctx;
62-
int err = 0;
62+
int err;
6363

6464
status = 0;
65-
6665
if (key_len > 256) {
6766
status = -EINVAL;
6867
return 0;
6968
}
7069

7170
__builtin_memcpy(&params.algo, algo, sizeof(algo));
7271
__builtin_memcpy(&params.key, key, sizeof(key));
73-
cctx = bpf_crypto_ctx_create(&params, sizeof(params), &err);
7472

73+
cctx = bpf_crypto_ctx_create(&params, sizeof(params), &err);
7574
if (!cctx) {
7675
status = err;
7776
return 0;
@@ -80,7 +79,6 @@ int skb_crypto_setup(void *ctx)
8079
err = crypto_ctx_insert(cctx);
8180
if (err && err != -EEXIST)
8281
status = err;
83-
8482
return 0;
8583
}
8684

@@ -92,6 +90,7 @@ int decrypt_sanity(struct __sk_buff *skb)
9290
struct bpf_dynptr psrc, pdst;
9391
int err;
9492

93+
status = 0;
9594
err = skb_dynptr_validate(skb, &psrc);
9695
if (err < 0) {
9796
status = err;
@@ -110,13 +109,23 @@ int decrypt_sanity(struct __sk_buff *skb)
110109
return TC_ACT_SHOT;
111110
}
112111

113-
/* dst is a global variable to make testing part easier to check. In real
114-
* production code, a percpu map should be used to store the result.
112+
/* Check also bad case where the dst buffer is smaller than the
113+
* skb's linear section.
114+
*/
115+
bpf_dynptr_from_mem(dst_bad, sizeof(dst_bad), 0, &pdst);
116+
status = bpf_crypto_decrypt(ctx, &psrc, &pdst, NULL);
117+
if (!status)
118+
status = -EIO;
119+
if (status != -EINVAL)
120+
goto err;
121+
122+
/* dst is a global variable to make testing part easier to check.
123+
* In real production code, a percpu map should be used to store
124+
* the result.
115125
*/
116126
bpf_dynptr_from_mem(dst, sizeof(dst), 0, &pdst);
117-
118127
status = bpf_crypto_decrypt(ctx, &psrc, &pdst, NULL);
119-
128+
err:
120129
return TC_ACT_SHOT;
121130
}
122131

@@ -129,7 +138,6 @@ int encrypt_sanity(struct __sk_buff *skb)
129138
int err;
130139

131140
status = 0;
132-
133141
err = skb_dynptr_validate(skb, &psrc);
134142
if (err < 0) {
135143
status = err;
@@ -148,13 +156,23 @@ int encrypt_sanity(struct __sk_buff *skb)
148156
return TC_ACT_SHOT;
149157
}
150158

151-
/* dst is a global variable to make testing part easier to check. In real
152-
* production code, a percpu map should be used to store the result.
159+
/* Check also bad case where the dst buffer is smaller than the
160+
* skb's linear section.
161+
*/
162+
bpf_dynptr_from_mem(dst_bad, sizeof(dst_bad), 0, &pdst);
163+
status = bpf_crypto_encrypt(ctx, &psrc, &pdst, NULL);
164+
if (!status)
165+
status = -EIO;
166+
if (status != -EINVAL)
167+
goto err;
168+
169+
/* dst is a global variable to make testing part easier to check.
170+
* In real production code, a percpu map should be used to store
171+
* the result.
153172
*/
154173
bpf_dynptr_from_mem(dst, sizeof(dst), 0, &pdst);
155-
156174
status = bpf_crypto_encrypt(ctx, &psrc, &pdst, NULL);
157-
175+
err:
158176
return TC_ACT_SHOT;
159177
}
160178

0 commit comments

Comments
 (0)