]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bpf: Add sockptr support for setsockopt
authorBreno Leitao <leitao@debian.org>
Mon, 16 Oct 2023 13:47:40 +0000 (06:47 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Sep 2024 09:11:34 +0000 (11:11 +0200)
[ Upstream commit 3f31e0d14d44ad491a81b7c1f83f32fbc300a867 ]

The whole network stack uses sockptr, and while it doesn't move to
something more modern, let's use sockptr in setsockptr BPF hooks, so, it
could be used by other callers.

The main motivation for this change is to use it in the io_uring
{g,s}etsockopt(), which will use a userspace pointer for *optval, but, a
kernel value for optlen.

Link: https://lore.kernel.org/all/ZSArfLaaGcfd8LH8@gmail.com/
Signed-off-by: Breno Leitao <leitao@debian.org>
Acked-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20231016134750.1381153-3-leitao@debian.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Stable-dep-of: 33f339a1ba54 ("bpf, net: Fix a potential race in do_sock_getsockopt()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/linux/bpf-cgroup.h
kernel/bpf/cgroup.c
net/socket.c

index c4956a48ab3e93a0a13b0decd759db6afed9c9f7..ebfd3c5a776ad3e1910cbd224206a595eefd9df8 100644 (file)
@@ -138,7 +138,7 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
                                   enum cgroup_bpf_attach_type atype);
 
 int __cgroup_bpf_run_filter_setsockopt(struct sock *sock, int *level,
-                                      int *optname, char __user *optval,
+                                      int *optname, sockptr_t optval,
                                       int *optlen, char **kernel_optval);
 
 int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
index caae07cc885e9c3bfe8aa068734390eebb9f61fc..913a6a7e62ca678bd818f335b25940ddbf4eec37 100644 (file)
@@ -1799,7 +1799,7 @@ static bool sockopt_buf_allocated(struct bpf_sockopt_kern *ctx,
 }
 
 int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
-                                      int *optname, char __user *optval,
+                                      int *optname, sockptr_t optval,
                                       int *optlen, char **kernel_optval)
 {
        struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
@@ -1822,7 +1822,8 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
 
        ctx.optlen = *optlen;
 
-       if (copy_from_user(ctx.optval, optval, min(*optlen, max_optlen)) != 0) {
+       if (copy_from_sockptr(ctx.optval, optval,
+                             min(*optlen, max_optlen))) {
                ret = -EFAULT;
                goto out;
        }
index b2d75d5661be49d3da1cd791fb1d4326f9ed84fb..f0f087004728e0c44204da519d95cf0be1bc6587 100644 (file)
@@ -2307,7 +2307,7 @@ int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
 
        if (!in_compat_syscall())
                err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
-                                                    user_optval, &optlen,
+                                                    optval, &optlen,
                                                     &kernel_optval);
        if (err < 0)
                goto out_put;