]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Aug 2020 14:36:06 +0000 (16:36 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Aug 2020 14:36:06 +0000 (16:36 +0200)
added patches:
bpf-sockmap-require-attach_bpf_fd-when-detaching-a-program.patch
selftests-bpf-fix-detach-from-sockmap-tests.patch

queue-5.4/bpf-sockmap-require-attach_bpf_fd-when-detaching-a-program.patch [new file with mode: 0644]
queue-5.4/selftests-bpf-fix-detach-from-sockmap-tests.patch [new file with mode: 0644]
queue-5.4/series

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 (file)
index 0000000..da979ae
--- /dev/null
@@ -0,0 +1,183 @@
+From bb0de3131f4c60a9bf976681e0fe4d1e55c7a821 Mon Sep 17 00:00:00 2001
+From: Lorenz Bauer <lmb@cloudflare.com>
+Date: Mon, 29 Jun 2020 10:56:28 +0100
+Subject: bpf: sockmap: Require attach_bpf_fd when detaching a program
+
+From: Lorenz Bauer <lmb@cloudflare.com>
+
+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 <lmb@cloudflare.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20200629095630.7933-5-lmb@cloudflare.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..3e6e971
--- /dev/null
@@ -0,0 +1,75 @@
+From f43cb0d672aa8eb09bfdb779de5900c040487d1d Mon Sep 17 00:00:00 2001
+From: Lorenz Bauer <lmb@cloudflare.com>
+Date: Thu, 9 Jul 2020 12:51:51 +0100
+Subject: selftests: bpf: Fix detach from sockmap tests
+
+From: Lorenz Bauer <lmb@cloudflare.com>
+
+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 <kafai@fb.com>
+Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/20200709115151.75829-1-lmb@cloudflare.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
index ba5f833785034f80d9715d743c3ee70519443636..d24bcb8b840e2fd44e406dbc5e50cbb7d88f0c48 100644 (file)
@@ -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