Skip to content

Commit b5aaf97

Browse files
Yonghong Songqmonnet
authored andcommitted
bpf: Use named fields for certain bpf uapi structs
Martin and Vadim reported a verifier failure with bpf_dynptr usage. The issue is mentioned but Vadim workarounded the issue with source change ([1]). The below describes what is the issue and why there is a verification failure. int BPF_PROG(skb_crypto_setup) { struct bpf_dynptr algo, key; ... bpf_dynptr_from_mem(..., ..., 0, &algo); ... } The bpf program is using vmlinux.h, so we have the following definition in vmlinux.h: struct bpf_dynptr { long: 64; long: 64; }; Note that in uapi header bpf.h, we have struct bpf_dynptr { long: 64; long: 64; } __attribute__((aligned(8))); So we lost alignment information for struct bpf_dynptr by using vmlinux.h. Let us take a look at a simple program below: $ cat align.c typedef unsigned long long __u64; struct bpf_dynptr_no_align { __u64 :64; __u64 :64; }; struct bpf_dynptr_yes_align { __u64 :64; __u64 :64; } __attribute__((aligned(8))); void bar(void *, void *); int foo() { struct bpf_dynptr_no_align a; struct bpf_dynptr_yes_align b; bar(&a, &b); return 0; } $ clang --target=bpf -O2 -S -emit-llvm align.c Look at the generated IR file align.ll: ... %a = alloca %struct.bpf_dynptr_no_align, align 1 %b = alloca %struct.bpf_dynptr_yes_align, align 8 ... The compiler dictates the alignment for struct bpf_dynptr_no_align is 1 and the alignment for struct bpf_dynptr_yes_align is 8. So theoretically compiler could allocate variable %a with alignment 1 although in reallity the compiler may choose a different alignment by considering other local variables. In [1], the verification failure happens because variable 'algo' is allocated on the stack with alignment 4 (fp-28). But the verifer wants its alignment to be 8. To fix the issue, the RFC patch ([1]) tried to add '__attribute__((aligned(8)))' to struct bpf_dynptr plus other similar structs. Andrii suggested that we could directly modify uapi struct with named fields like struct 'bpf_iter_num': struct bpf_iter_num { /* opaque iterator state; having __u64 here allows to preserve correct * alignment requirements in vmlinux.h, generated from BTF */ __u64 __opaque[1]; } __attribute__((aligned(8))); Indeed, adding named fields for those affected structs in this patch can preserve alignment when bpf program references them in vmlinux.h. With this patch, the verification failure in [1] can also be resolved. [1] https://lore.kernel.org/bpf/[email protected]/ [2] https://lore.kernel.org/bpf/[email protected]/ Cc: Vadim Fedorenko <[email protected]> Cc: Martin KaFai Lau <[email protected]> Suggested-by: Andrii Nakryiko <[email protected]> Signed-off-by: Yonghong Song <[email protected]> Acked-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent fa46ebb commit b5aaf97

File tree

1 file changed

+7
-16
lines changed

1 file changed

+7
-16
lines changed

include/uapi/linux/bpf.h

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7151,40 +7151,31 @@ struct bpf_spin_lock {
71517151
};
71527152

71537153
struct bpf_timer {
7154-
__u64 :64;
7155-
__u64 :64;
7154+
__u64 __opaque[2];
71567155
} __attribute__((aligned(8)));
71577156

71587157
struct bpf_dynptr {
7159-
__u64 :64;
7160-
__u64 :64;
7158+
__u64 __opaque[2];
71617159
} __attribute__((aligned(8)));
71627160

71637161
struct bpf_list_head {
7164-
__u64 :64;
7165-
__u64 :64;
7162+
__u64 __opaque[2];
71667163
} __attribute__((aligned(8)));
71677164

71687165
struct bpf_list_node {
7169-
__u64 :64;
7170-
__u64 :64;
7171-
__u64 :64;
7166+
__u64 __opaque[3];
71727167
} __attribute__((aligned(8)));
71737168

71747169
struct bpf_rb_root {
7175-
__u64 :64;
7176-
__u64 :64;
7170+
__u64 __opaque[2];
71777171
} __attribute__((aligned(8)));
71787172

71797173
struct bpf_rb_node {
7180-
__u64 :64;
7181-
__u64 :64;
7182-
__u64 :64;
7183-
__u64 :64;
7174+
__u64 __opaque[4];
71847175
} __attribute__((aligned(8)));
71857176

71867177
struct bpf_refcount {
7187-
__u32 :32;
7178+
__u32 __opaque[1];
71887179
} __attribute__((aligned(4)));
71897180

71907181
struct bpf_sysctl {

0 commit comments

Comments
 (0)