* [PATCH stable-5.4.y] bpf: sockmap: Require attach_bpf_fd when detaching a program
@ 2020-08-04 8:47 Lorenz Bauer
2020-08-05 14:34 ` Greg KH
0 siblings, 1 reply; 2+ messages in thread
From: Lorenz Bauer @ 2020-08-04 8:47 UTC (permalink / raw)
To: stable, gregkh, bpf; +Cc: kernel-team, Lorenz Bauer, Alexei Starovoitov
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
---
The 5.4 tree needs a dedicated backport, since some headers have
changed sufficiently to cause the patch to fail. bpf_prog_detach
needs further massaging to pass the correct program type to
sock_map_prog_detach. Please queue this patch together with
commit f43cb0d672aa ("selftests: bpf: Fix detach from sockmap tests").
---
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(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 3bf3835d0e86..7aa0d8b5aaf0 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -956,11 +956,14 @@ static inline void bpf_map_offload_map_free(struct bpf_map *map)
#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(const union bpf_attr *attr,
{
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)
diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
index 4bdb5e4bbd6a..20f3550b0b11 100644
--- a/include/linux/skmsg.h
+++ b/include/linux/skmsg.h
@@ -450,6 +450,19 @@ static inline void psock_set_prog(struct bpf_prog **pprog,
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);
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 8bc904f9badb..bf03d04a9e2f 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2029,10 +2029,10 @@ static int bpf_prog_detach(const union bpf_attr *attr)
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:
diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index 6bbc118bf00e..df52061f99f7 100644
--- 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_attr *attr, struct bpf_prog *prog)
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_progs(struct bpf_map *map)
}
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;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH stable-5.4.y] bpf: sockmap: Require attach_bpf_fd when detaching a program
2020-08-04 8:47 [PATCH stable-5.4.y] bpf: sockmap: Require attach_bpf_fd when detaching a program Lorenz Bauer
@ 2020-08-05 14:34 ` Greg KH
0 siblings, 0 replies; 2+ messages in thread
From: Greg KH @ 2020-08-05 14:34 UTC (permalink / raw)
To: Lorenz Bauer; +Cc: stable, bpf, kernel-team, Alexei Starovoitov
On Tue, Aug 04, 2020 at 09:47:47AM +0100, Lorenz Bauer wrote:
> 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
> ---
> The 5.4 tree needs a dedicated backport, since some headers have
> changed sufficiently to cause the patch to fail. bpf_prog_detach
> needs further massaging to pass the correct program type to
> sock_map_prog_detach. Please queue this patch together with
> commit f43cb0d672aa ("selftests: bpf: Fix detach from sockmap tests").
Thanks for the backport, now queued up.
greg k-h
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-08-05 20:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-08-04 8:47 [PATCH stable-5.4.y] bpf: sockmap: Require attach_bpf_fd when detaching a program Lorenz Bauer
2020-08-05 14:34 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).