From 4b44463a01ed2fde10b9ebf67e2b5371fbc7c74c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 Aug 2020 16:36:06 +0200 Subject: [PATCH] 5.4-stable patches added patches: bpf-sockmap-require-attach_bpf_fd-when-detaching-a-program.patch selftests-bpf-fix-detach-from-sockmap-tests.patch --- ...tach_bpf_fd-when-detaching-a-program.patch | 183 ++++++++++++++++++ ...ts-bpf-fix-detach-from-sockmap-tests.patch | 75 +++++++ queue-5.4/series | 2 + 3 files changed, 260 insertions(+) create mode 100644 queue-5.4/bpf-sockmap-require-attach_bpf_fd-when-detaching-a-program.patch create mode 100644 queue-5.4/selftests-bpf-fix-detach-from-sockmap-tests.patch diff --git a/queue-5.4/bpf-sockmap-require-attach_bpf_fd-when-detaching-a-program.patch b/queue-5.4/bpf-sockmap-require-attach_bpf_fd-when-detaching-a-program.patch new file mode 100644 index 00000000000..da979aed234 --- /dev/null +++ b/queue-5.4/bpf-sockmap-require-attach_bpf_fd-when-detaching-a-program.patch @@ -0,0 +1,183 @@ +From bb0de3131f4c60a9bf976681e0fe4d1e55c7a821 Mon Sep 17 00:00:00 2001 +From: Lorenz Bauer +Date: Mon, 29 Jun 2020 10:56:28 +0100 +Subject: bpf: sockmap: Require attach_bpf_fd when detaching a program + +From: Lorenz Bauer + +commit bb0de3131f4c60a9bf976681e0fe4d1e55c7a821 upstream. + +The sockmap code currently ignores the value of attach_bpf_fd when +detaching a program. This is contrary to the usual behaviour of +checking that attach_bpf_fd represents the currently attached +program. + +Ensure that attach_bpf_fd is indeed the currently attached +program. It turns out that all sockmap selftests already do this, +which indicates that this is unlikely to cause breakage. + +Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") +Signed-off-by: Lorenz Bauer +Signed-off-by: Alexei Starovoitov +Link: https://lore.kernel.org/bpf/20200629095630.7933-5-lmb@cloudflare.com +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/bpf.h | 13 +++++++++++-- + include/linux/skmsg.h | 13 +++++++++++++ + kernel/bpf/syscall.c | 4 ++-- + net/core/sock_map.c | 50 +++++++++++++++++++++++++++++++++++++++++++++----- + 4 files changed, 71 insertions(+), 9 deletions(-) + +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -956,11 +956,14 @@ static inline void bpf_map_offload_map_f + #endif /* CONFIG_NET && CONFIG_BPF_SYSCALL */ + + #if defined(CONFIG_BPF_STREAM_PARSER) +-int sock_map_prog_update(struct bpf_map *map, struct bpf_prog *prog, u32 which); ++int sock_map_prog_update(struct bpf_map *map, struct bpf_prog *prog, ++ struct bpf_prog *old, u32 which); + int sock_map_get_from_fd(const union bpf_attr *attr, struct bpf_prog *prog); ++int sock_map_prog_detach(const union bpf_attr *attr, enum bpf_prog_type ptype); + #else + static inline int sock_map_prog_update(struct bpf_map *map, +- struct bpf_prog *prog, u32 which) ++ struct bpf_prog *prog, ++ struct bpf_prog *old, u32 which) + { + return -EOPNOTSUPP; + } +@@ -970,6 +973,12 @@ static inline int sock_map_get_from_fd(c + { + return -EINVAL; + } ++ ++static inline int sock_map_prog_detach(const union bpf_attr *attr, ++ enum bpf_prog_type ptype) ++{ ++ return -EOPNOTSUPP; ++} + #endif + + #if defined(CONFIG_XDP_SOCKETS) +--- a/include/linux/skmsg.h ++++ b/include/linux/skmsg.h +@@ -450,6 +450,19 @@ static inline void psock_set_prog(struct + bpf_prog_put(prog); + } + ++static inline int psock_replace_prog(struct bpf_prog **pprog, ++ struct bpf_prog *prog, ++ struct bpf_prog *old) ++{ ++ if (cmpxchg(pprog, old, prog) != old) ++ return -ENOENT; ++ ++ if (old) ++ bpf_prog_put(old); ++ ++ return 0; ++} ++ + static inline void psock_progs_drop(struct sk_psock_progs *progs) + { + psock_set_prog(&progs->msg_parser, NULL); +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -2029,10 +2029,10 @@ static int bpf_prog_detach(const union b + ptype = BPF_PROG_TYPE_CGROUP_DEVICE; + break; + case BPF_SK_MSG_VERDICT: +- return sock_map_get_from_fd(attr, NULL); ++ return sock_map_prog_detach(attr, BPF_PROG_TYPE_SK_MSG); + case BPF_SK_SKB_STREAM_PARSER: + case BPF_SK_SKB_STREAM_VERDICT: +- return sock_map_get_from_fd(attr, NULL); ++ return sock_map_prog_detach(attr, BPF_PROG_TYPE_SK_SKB); + case BPF_LIRC_MODE2: + return lirc_prog_detach(attr); + case BPF_FLOW_DISSECTOR: +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -71,7 +71,42 @@ int sock_map_get_from_fd(const union bpf + map = __bpf_map_get(f); + if (IS_ERR(map)) + return PTR_ERR(map); +- ret = sock_map_prog_update(map, prog, attr->attach_type); ++ ret = sock_map_prog_update(map, prog, NULL, attr->attach_type); ++ fdput(f); ++ return ret; ++} ++ ++int sock_map_prog_detach(const union bpf_attr *attr, enum bpf_prog_type ptype) ++{ ++ u32 ufd = attr->target_fd; ++ struct bpf_prog *prog; ++ struct bpf_map *map; ++ struct fd f; ++ int ret; ++ ++ if (attr->attach_flags) ++ return -EINVAL; ++ ++ f = fdget(ufd); ++ map = __bpf_map_get(f); ++ if (IS_ERR(map)) ++ return PTR_ERR(map); ++ ++ prog = bpf_prog_get(attr->attach_bpf_fd); ++ if (IS_ERR(prog)) { ++ ret = PTR_ERR(prog); ++ goto put_map; ++ } ++ ++ if (prog->type != ptype) { ++ ret = -EINVAL; ++ goto put_prog; ++ } ++ ++ ret = sock_map_prog_update(map, NULL, prog, attr->attach_type); ++put_prog: ++ bpf_prog_put(prog); ++put_map: + fdput(f); + return ret; + } +@@ -1015,27 +1050,32 @@ static struct sk_psock_progs *sock_map_p + } + + int sock_map_prog_update(struct bpf_map *map, struct bpf_prog *prog, +- u32 which) ++ struct bpf_prog *old, u32 which) + { + struct sk_psock_progs *progs = sock_map_progs(map); ++ struct bpf_prog **pprog; + + if (!progs) + return -EOPNOTSUPP; + + switch (which) { + case BPF_SK_MSG_VERDICT: +- psock_set_prog(&progs->msg_parser, prog); ++ pprog = &progs->msg_parser; + break; + case BPF_SK_SKB_STREAM_PARSER: +- psock_set_prog(&progs->skb_parser, prog); ++ pprog = &progs->skb_parser; + break; + case BPF_SK_SKB_STREAM_VERDICT: +- psock_set_prog(&progs->skb_verdict, prog); ++ pprog = &progs->skb_verdict; + break; + default: + return -EOPNOTSUPP; + } + ++ if (old) ++ return psock_replace_prog(pprog, prog, old); ++ ++ psock_set_prog(pprog, prog); + return 0; + } + diff --git a/queue-5.4/selftests-bpf-fix-detach-from-sockmap-tests.patch b/queue-5.4/selftests-bpf-fix-detach-from-sockmap-tests.patch new file mode 100644 index 00000000000..3e6e9715c7b --- /dev/null +++ b/queue-5.4/selftests-bpf-fix-detach-from-sockmap-tests.patch @@ -0,0 +1,75 @@ +From f43cb0d672aa8eb09bfdb779de5900c040487d1d Mon Sep 17 00:00:00 2001 +From: Lorenz Bauer +Date: Thu, 9 Jul 2020 12:51:51 +0100 +Subject: selftests: bpf: Fix detach from sockmap tests + +From: Lorenz Bauer + +commit f43cb0d672aa8eb09bfdb779de5900c040487d1d upstream. + +Fix sockmap tests which rely on old bpf_prog_dispatch behaviour. +In the first case, the tests check that detaching without giving +a program succeeds. Since these are not the desired semantics, +invert the condition. In the second case, the clean up code doesn't +supply the necessary program fds. + +Fixes: bb0de3131f4c ("bpf: sockmap: Require attach_bpf_fd when detaching a program") +Reported-by: Martin KaFai Lau +Signed-off-by: Lorenz Bauer +Signed-off-by: Daniel Borkmann +Reviewed-by: Jakub Sitnicki +Link: https://lore.kernel.org/bpf/20200709115151.75829-1-lmb@cloudflare.com +Signed-off-by: Greg Kroah-Hartman + +--- + tools/testing/selftests/bpf/test_maps.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/tools/testing/selftests/bpf/test_maps.c ++++ b/tools/testing/selftests/bpf/test_maps.c +@@ -793,19 +793,19 @@ static void test_sockmap(unsigned int ta + } + + err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_PARSER); +- if (err) { ++ if (!err) { + printf("Failed empty parser prog detach\n"); + goto out_sockmap; + } + + err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_VERDICT); +- if (err) { ++ if (!err) { + printf("Failed empty verdict prog detach\n"); + goto out_sockmap; + } + + err = bpf_prog_detach(fd, BPF_SK_MSG_VERDICT); +- if (err) { ++ if (!err) { + printf("Failed empty msg verdict prog detach\n"); + goto out_sockmap; + } +@@ -1094,19 +1094,19 @@ static void test_sockmap(unsigned int ta + assert(status == 0); + } + +- err = bpf_prog_detach(map_fd_rx, __MAX_BPF_ATTACH_TYPE); ++ err = bpf_prog_detach2(parse_prog, map_fd_rx, __MAX_BPF_ATTACH_TYPE); + if (!err) { + printf("Detached an invalid prog type.\n"); + goto out_sockmap; + } + +- err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_PARSER); ++ err = bpf_prog_detach2(parse_prog, map_fd_rx, BPF_SK_SKB_STREAM_PARSER); + if (err) { + printf("Failed parser prog detach\n"); + goto out_sockmap; + } + +- err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_VERDICT); ++ err = bpf_prog_detach2(verdict_prog, map_fd_rx, BPF_SK_SKB_STREAM_VERDICT); + if (err) { + printf("Failed parser prog detach\n"); + goto out_sockmap; diff --git a/queue-5.4/series b/queue-5.4/series index ba5f8337850..d24bcb8b840 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -5,3 +5,5 @@ random32-remove-net_rand_state-from-the-latent-entropy-gcc-plugin.patch random32-move-the-pseudo-random-32-bit-definitions-to-prandom.h.patch arm64-workaround-circular-dependency-in-pointer_auth.h.patch ext4-fix-direct-i-o-read-error.patch +selftests-bpf-fix-detach-from-sockmap-tests.patch +bpf-sockmap-require-attach_bpf_fd-when-detaching-a-program.patch -- 2.47.3