Skip to content

Commit a85e089

Browse files
yonghong-songKernel Patches Daemon
authored and
Kernel Patches Daemon
committed
selftests/bpf: Fix dynptr/test_dynptr_is_null
With latest llvm17, dynptr/test_dynptr_is_null subtest failed in my testing VM. The failure log looks like below: All error logs: tester_init:PASS:tester_log_buf 0 nsec process_subtest:PASS:obj_open_mem 0 nsec process_subtest:PASS:Can't alloc specs array 0 nsec verify_success:PASS:dynptr_success__open 0 nsec verify_success:PASS:bpf_object__find_program_by_name 0 nsec verify_success:PASS:dynptr_success__load 0 nsec verify_success:PASS:bpf_program__attach 0 nsec verify_success:FAIL:err unexpected err: actual 4 != expected 0 #65/9 dynptr/test_dynptr_is_null:FAIL The error happens for bpf prog test_dynptr_is_null in dynptr_success.c. if (bpf_dynptr_is_null(&ptr2)) { err = 4; goto exit; } The bpf_dynptr_is_null(&ptr) unexpectedly returned a non-zero value and the control went to the error path. Digging further, I found the root cause is due to function signature difference between kernel and user space. In kernel, we have __bpf_kfunc bool bpf_dynptr_is_null(struct bpf_dynptr_kern *ptr) while in bpf_kfuncs.h we have extern int bpf_dynptr_is_null(const struct bpf_dynptr *ptr) __ksym; The kernel bpf_dynptr_is_null disasm code: ffffffff812f1a90 <bpf_dynptr_is_null>: ffffffff812f1a90: f3 0f 1e fa endbr64 ffffffff812f1a94: 0f 1f 44 00 00 nopl (%rax,%rax) ffffffff812f1a99: 53 pushq %rbx ffffffff812f1a9a: 48 89 fb movq %rdi, %rbx ffffffff812f1a9d: e8 ae 29 17 00 callq 0xffffffff81464450 <__asan_load8_noabort> ffffffff812f1aa2: 48 83 3b 00 cmpq $0x0, (%rbx) ffffffff812f1aa6: 0f 94 c0 sete %al ffffffff812f1aa9: 5b popq %rbx ffffffff812f1aaa: c3 retq Note that only 1-byte register %al is set and the other 7-bytes are not touched. In bpf program, the asm code for the above bpf_dynptr_is_null(&ptr2): 266: 85 10 00 00 ff ff ff ff call -0x1 267: b4 01 00 00 04 00 00 00 w1 = 0x4 268: 16 00 03 00 00 00 00 00 if w0 == 0x0 goto +0x3 <LBB9_8> Basically, 4-byte subregister is tested. This might cause error as the value other than the lowest byte might not be 0. This patch fixed the issue by using the identical func prototype across kernel and selftest user space. The fixed bpf asm code: 267: 85 10 00 00 ff ff ff ff call -0x1 268: 54 00 00 00 01 00 00 00 w0 &= 0x1 269: b4 01 00 00 04 00 00 00 w1 = 0x4 270: 16 00 03 00 00 00 00 00 if w0 == 0x0 goto +0x3 <LBB9_8> Signed-off-by: Yonghong Song <[email protected]>
1 parent bf42de8 commit a85e089

File tree

4 files changed

+4
-1
lines changed

4 files changed

+4
-1
lines changed

tools/testing/selftests/bpf/bpf_kfuncs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ extern void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr *ptr, __u32 offset,
3636
void *buffer, __u32 buffer__szk) __ksym;
3737

3838
extern int bpf_dynptr_adjust(const struct bpf_dynptr *ptr, __u32 start, __u32 end) __ksym;
39-
extern int bpf_dynptr_is_null(const struct bpf_dynptr *ptr) __ksym;
39+
extern bool bpf_dynptr_is_null(const struct bpf_dynptr *ptr) __ksym;
4040
extern int bpf_dynptr_is_rdonly(const struct bpf_dynptr *ptr) __ksym;
4141
extern __u32 bpf_dynptr_size(const struct bpf_dynptr *ptr) __ksym;
4242
extern int bpf_dynptr_clone(const struct bpf_dynptr *ptr, struct bpf_dynptr *clone__init) __ksym;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <errno.h>
55
#include <string.h>
6+
#include <stdbool.h>
67
#include <linux/bpf.h>
78
#include <bpf/bpf_helpers.h>
89
#include <linux/if_ether.h>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* Copyright (c) 2022 Facebook */
33

44
#include <string.h>
5+
#include <stdbool.h>
56
#include <linux/bpf.h>
67
#include <bpf/bpf_helpers.h>
78
#include "bpf_misc.h"

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* Copyright (c) 2022 Meta */
33
#include <stddef.h>
44
#include <string.h>
5+
#include <stdbool.h>
56
#include <linux/bpf.h>
67
#include <linux/if_ether.h>
78
#include <linux/if_packet.h>

0 commit comments

Comments
 (0)