Message ID | 20190820155025.91216-1-iii@linux.ibm.com |
---|---|
State | Accepted |
Delegated to: | BPF Maintainers |
Headers | show |
Series | [bpf] bpf: allow narrow loads of some sk_reuseport_md fields with offset > 0 | expand |
On 8/20/19 5:50 PM, Ilya Leoshkevich wrote: > test_select_reuseport fails on s390 due to verifier rejecting > test_select_reuseport_kern.o with the following message: > > ; data_check.eth_protocol = reuse_md->eth_protocol; > 18: (69) r1 = *(u16 *)(r6 +22) > invalid bpf_context access off=22 size=2 > > This is because on big-endian machines casts from __u32 to __u16 are > generated by referencing the respective variable as __u16 with an offset > of 2 (as opposed to 0 on little-endian machines). > > The verifier already has all the infrastructure in place to allow such > accesses, it's just that they are not explicitly enabled for > eth_protocol field. Enable them for eth_protocol field by using > bpf_ctx_range instead of offsetof. > > Ditto for ip_protocol, bind_inany and len, since they already allow > narrowing, and the same problem can arise when working with them. > > Fixes: 2dbb9b9e6df6 ("bpf: Introduce BPF_PROG_TYPE_SK_REUSEPORT") > Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Applied, thanks!
diff --git a/net/core/filter.c b/net/core/filter.c index 7878f918b8c0..4c6a252d4212 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -8757,13 +8757,13 @@ sk_reuseport_is_valid_access(int off, int size, return size == size_default; /* Fields that allow narrowing */ - case offsetof(struct sk_reuseport_md, eth_protocol): + case bpf_ctx_range(struct sk_reuseport_md, eth_protocol): if (size < FIELD_SIZEOF(struct sk_buff, protocol)) return false; /* fall through */ - case offsetof(struct sk_reuseport_md, ip_protocol): - case offsetof(struct sk_reuseport_md, bind_inany): - case offsetof(struct sk_reuseport_md, len): + case bpf_ctx_range(struct sk_reuseport_md, ip_protocol): + case bpf_ctx_range(struct sk_reuseport_md, bind_inany): + case bpf_ctx_range(struct sk_reuseport_md, len): bpf_ctx_record_field_size(info, size_default); return bpf_ctx_narrow_access_ok(off, size, size_default);
test_select_reuseport fails on s390 due to verifier rejecting test_select_reuseport_kern.o with the following message: ; data_check.eth_protocol = reuse_md->eth_protocol; 18: (69) r1 = *(u16 *)(r6 +22) invalid bpf_context access off=22 size=2 This is because on big-endian machines casts from __u32 to __u16 are generated by referencing the respective variable as __u16 with an offset of 2 (as opposed to 0 on little-endian machines). The verifier already has all the infrastructure in place to allow such accesses, it's just that they are not explicitly enabled for eth_protocol field. Enable them for eth_protocol field by using bpf_ctx_range instead of offsetof. Ditto for ip_protocol, bind_inany and len, since they already allow narrowing, and the same problem can arise when working with them. Fixes: 2dbb9b9e6df6 ("bpf: Introduce BPF_PROG_TYPE_SK_REUSEPORT") Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> --- net/core/filter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)