From: Greg Kroah-Hartman Date: Mon, 11 Apr 2022 11:31:56 +0000 (+0200) Subject: 5.17-stable patches X-Git-Tag: v4.9.310~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5c7d90e3072359616a4de063c232ee8017263210;p=thirdparty%2Fkernel%2Fstable-queue.git 5.17-stable patches added patches: bpf-treat-bpf_sk_lookup-remote_port-as-a-2-byte-field.patch selftests-bpf-fix-u8-narrow-load-checks-for-bpf_sk_lookup-remote_port.patch --- diff --git a/queue-5.17/bpf-treat-bpf_sk_lookup-remote_port-as-a-2-byte-field.patch b/queue-5.17/bpf-treat-bpf_sk_lookup-remote_port-as-a-2-byte-field.patch new file mode 100644 index 00000000000..af95c76bf5f --- /dev/null +++ b/queue-5.17/bpf-treat-bpf_sk_lookup-remote_port-as-a-2-byte-field.patch @@ -0,0 +1,88 @@ +From 058ec4a7d9cf77238c73ad9f1e1a3ed9a29afcab Mon Sep 17 00:00:00 2001 +From: Jakub Sitnicki +Date: Sat, 19 Mar 2022 19:33:54 +0100 +Subject: bpf: Treat bpf_sk_lookup remote_port as a 2-byte field + +From: Jakub Sitnicki + +commit 058ec4a7d9cf77238c73ad9f1e1a3ed9a29afcab upstream. + +In commit 9a69e2b385f4 ("bpf: Make remote_port field in struct +bpf_sk_lookup 16-bit wide") the remote_port field has been split up and +re-declared from u32 to be16. + +However, the accompanying changes to the context access converter have not +been well thought through when it comes big-endian platforms. + +Today 2-byte wide loads from offsetof(struct bpf_sk_lookup, remote_port) +are handled as narrow loads from a 4-byte wide field. + +This by itself is not enough to create a problem, but when we combine + + 1. 32-bit wide access to ->remote_port backed by a 16-wide wide load, with + 2. inherent difference between litte- and big-endian in how narrow loads + need have to be handled (see bpf_ctx_narrow_access_offset), + +we get inconsistent results for a 2-byte loads from &ctx->remote_port on LE +and BE architectures. This in turn makes BPF C code for the common case of +2-byte load from ctx->remote_port not portable. + +To rectify it, inform the context access converter that remote_port is +2-byte wide field, and only 1-byte loads need to be treated as narrow +loads. + +At the same time, we special-case the 4-byte load from &ctx->remote_port to +continue handling it the same way as do today, in order to keep the +existing BPF programs working. + +Fixes: 9a69e2b385f4 ("bpf: Make remote_port field in struct bpf_sk_lookup 16-bit wide") +Signed-off-by: Jakub Sitnicki +Signed-off-by: Alexei Starovoitov +Acked-by: Martin KaFai Lau +Link: https://lore.kernel.org/bpf/20220319183356.233666-2-jakub@cloudflare.com +Signed-off-by: Greg Kroah-Hartman +--- + net/core/filter.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -10621,13 +10621,24 @@ static bool sk_lookup_is_valid_access(in + case bpf_ctx_range(struct bpf_sk_lookup, local_ip4): + case bpf_ctx_range_till(struct bpf_sk_lookup, remote_ip6[0], remote_ip6[3]): + case bpf_ctx_range_till(struct bpf_sk_lookup, local_ip6[0], local_ip6[3]): +- case offsetof(struct bpf_sk_lookup, remote_port) ... +- offsetof(struct bpf_sk_lookup, local_ip4) - 1: + case bpf_ctx_range(struct bpf_sk_lookup, local_port): + case bpf_ctx_range(struct bpf_sk_lookup, ingress_ifindex): + bpf_ctx_record_field_size(info, sizeof(__u32)); + return bpf_ctx_narrow_access_ok(off, size, sizeof(__u32)); + ++ case bpf_ctx_range(struct bpf_sk_lookup, remote_port): ++ /* Allow 4-byte access to 2-byte field for backward compatibility */ ++ if (size == sizeof(__u32)) ++ return true; ++ bpf_ctx_record_field_size(info, sizeof(__be16)); ++ return bpf_ctx_narrow_access_ok(off, size, sizeof(__be16)); ++ ++ case offsetofend(struct bpf_sk_lookup, remote_port) ... ++ offsetof(struct bpf_sk_lookup, local_ip4) - 1: ++ /* Allow access to zero padding for backward compatibility */ ++ bpf_ctx_record_field_size(info, sizeof(__u16)); ++ return bpf_ctx_narrow_access_ok(off, size, sizeof(__u16)); ++ + default: + return false; + } +@@ -10709,6 +10720,11 @@ static u32 sk_lookup_convert_ctx_access( + sport, 2, target_size)); + break; + ++ case offsetofend(struct bpf_sk_lookup, remote_port): ++ *target_size = 2; ++ *insn++ = BPF_MOV32_IMM(si->dst_reg, 0); ++ break; ++ + case offsetof(struct bpf_sk_lookup, local_port): + *insn++ = BPF_LDX_MEM(BPF_H, si->dst_reg, si->src_reg, + bpf_target_off(struct bpf_sk_lookup_kern, diff --git a/queue-5.17/selftests-bpf-fix-u8-narrow-load-checks-for-bpf_sk_lookup-remote_port.patch b/queue-5.17/selftests-bpf-fix-u8-narrow-load-checks-for-bpf_sk_lookup-remote_port.patch new file mode 100644 index 00000000000..280a7fcd264 --- /dev/null +++ b/queue-5.17/selftests-bpf-fix-u8-narrow-load-checks-for-bpf_sk_lookup-remote_port.patch @@ -0,0 +1,65 @@ +From 3c69611b8926f8e74fcf76bd97ae0e5dafbeb26a Mon Sep 17 00:00:00 2001 +From: Jakub Sitnicki +Date: Sat, 19 Mar 2022 19:33:55 +0100 +Subject: selftests/bpf: Fix u8 narrow load checks for bpf_sk_lookup remote_port + +From: Jakub Sitnicki + +commit 3c69611b8926f8e74fcf76bd97ae0e5dafbeb26a upstream. + +In commit 9a69e2b385f4 ("bpf: Make remote_port field in struct +bpf_sk_lookup 16-bit wide") ->remote_port field changed from __u32 to +__be16. + +However, narrow load tests which exercise 1-byte sized loads from +offsetof(struct bpf_sk_lookup, remote_port) were not adopted to reflect the +change. + +As a result, on little-endian we continue testing loads from addresses: + + - (__u8 *)&ctx->remote_port + 3 + - (__u8 *)&ctx->remote_port + 4 + +which map to the zero padding following the remote_port field, and don't +break the tests because there is no observable change. + +While on big-endian, we observe breakage because tests expect to see zeros +for values loaded from: + + - (__u8 *)&ctx->remote_port - 1 + - (__u8 *)&ctx->remote_port - 2 + +Above addresses map to ->remote_ip6 field, which precedes ->remote_port, +and are populated during the bpf_sk_lookup IPv6 tests. + +Unsurprisingly, on s390x we observe: + + #136/38 sk_lookup/narrow access to ctx v4:OK + #136/39 sk_lookup/narrow access to ctx v6:FAIL + +Fix it by removing the checks for 1-byte loads from offsets outside of the +->remote_port field. + +Fixes: 9a69e2b385f4 ("bpf: Make remote_port field in struct bpf_sk_lookup 16-bit wide") +Suggested-by: Ilya Leoshkevich +Signed-off-by: Jakub Sitnicki +Signed-off-by: Alexei Starovoitov +Acked-by: Martin KaFai Lau +Link: https://lore.kernel.org/bpf/20220319183356.233666-3-jakub@cloudflare.com +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/progs/test_sk_lookup.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/tools/testing/selftests/bpf/progs/test_sk_lookup.c ++++ b/tools/testing/selftests/bpf/progs/test_sk_lookup.c +@@ -412,8 +412,7 @@ int ctx_narrow_access(struct bpf_sk_look + + /* Narrow loads from remote_port field. Expect SRC_PORT. */ + if (LSB(ctx->remote_port, 0) != ((SRC_PORT >> 0) & 0xff) || +- LSB(ctx->remote_port, 1) != ((SRC_PORT >> 8) & 0xff) || +- LSB(ctx->remote_port, 2) != 0 || LSB(ctx->remote_port, 3) != 0) ++ LSB(ctx->remote_port, 1) != ((SRC_PORT >> 8) & 0xff)) + return SK_DROP; + if (LSW(ctx->remote_port, 0) != SRC_PORT) + return SK_DROP; diff --git a/queue-5.17/series b/queue-5.17/series index e5739130efe..3a19cce0a52 100644 --- a/queue-5.17/series +++ b/queue-5.17/series @@ -315,3 +315,5 @@ drm-amdkfd-fix-variable-set-but-not-used-warning.patch net-smc-send-directly-on-setting-tcp_nodelay.patch revert-selftests-net-add-tls-config-dependency-for-tls-selftests.patch bpf-make-remote_port-field-in-struct-bpf_sk_lookup-16-bit-wide.patch +selftests-bpf-fix-u8-narrow-load-checks-for-bpf_sk_lookup-remote_port.patch +bpf-treat-bpf_sk_lookup-remote_port-as-a-2-byte-field.patch