Patch "bpf, net: Fix a potential race in do_sock_getsockopt()" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    bpf, net: Fix a potential race in do_sock_getsockopt()

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     bpf-net-fix-a-potential-race-in-do_sock_getsockopt.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 2cf07c4a40571ef93c411808d99d34c35e9826cb
Author: Tze-nan Wu <Tze-nan.Wu@xxxxxxxxxxxx>
Date:   Fri Aug 30 16:25:17 2024 +0800

    bpf, net: Fix a potential race in do_sock_getsockopt()
    
    [ Upstream commit 33f339a1ba54e56bba57ee9a77c71e385ab4825c ]
    
    There's a potential race when `cgroup_bpf_enabled(CGROUP_GETSOCKOPT)` is
    false during the execution of `BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN`, but
    becomes true when `BPF_CGROUP_RUN_PROG_GETSOCKOPT` is called.
    This inconsistency can lead to `BPF_CGROUP_RUN_PROG_GETSOCKOPT` receiving
    an "-EFAULT" from `__cgroup_bpf_run_filter_getsockopt(max_optlen=0)`.
    Scenario shown as below:
    
               `process A`                      `process B`
               -----------                      ------------
      BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN
                                                enable CGROUP_GETSOCKOPT
      BPF_CGROUP_RUN_PROG_GETSOCKOPT (-EFAULT)
    
    To resolve this, remove the `BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN` macro and
    directly uses `copy_from_sockptr` to ensure that `max_optlen` is always
    set before `BPF_CGROUP_RUN_PROG_GETSOCKOPT` is invoked.
    
    Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks")
    Co-developed-by: Yanghui Li <yanghui.li@xxxxxxxxxxxx>
    Signed-off-by: Yanghui Li <yanghui.li@xxxxxxxxxxxx>
    Co-developed-by: Cheng-Jui Wang <cheng-jui.wang@xxxxxxxxxxxx>
    Signed-off-by: Cheng-Jui Wang <cheng-jui.wang@xxxxxxxxxxxx>
    Signed-off-by: Tze-nan Wu <Tze-nan.Wu@xxxxxxxxxxxx>
    Acked-by: Stanislav Fomichev <sdf@xxxxxxxxxxx>
    Acked-by: Alexei Starovoitov <ast@xxxxxxxxxx>
    Link: https://patch.msgid.link/20240830082518.23243-1-Tze-nan.Wu@xxxxxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 2aa82b7aed89..d4f2c8706042 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -375,14 +375,6 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
 	__ret;								       \
 })
 
-#define BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen)			       \
-({									       \
-	int __ret = 0;							       \
-	if (cgroup_bpf_enabled(CGROUP_GETSOCKOPT))			       \
-		copy_from_sockptr(&__ret, optlen, sizeof(int));		       \
-	__ret;								       \
-})
-
 #define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, optlen,   \
 				       max_optlen, retval)		       \
 ({									       \
@@ -500,7 +492,6 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
 #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
 #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) ({ 0; })
 #define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos) ({ 0; })
-#define BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen) ({ 0; })
 #define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, \
 				       optlen, max_optlen, retval) ({ retval; })
 #define BPF_CGROUP_RUN_PROG_GETSOCKOPT_KERN(sock, level, optname, optval, \
diff --git a/net/socket.c b/net/socket.c
index d275f5f14882..9db33cd4a71b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2355,7 +2355,7 @@ INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level,
 int do_sock_getsockopt(struct socket *sock, bool compat, int level,
 		       int optname, sockptr_t optval, sockptr_t optlen)
 {
-	int max_optlen __maybe_unused;
+	int max_optlen __maybe_unused = 0;
 	const struct proto_ops *ops;
 	int err;
 
@@ -2364,7 +2364,7 @@ int do_sock_getsockopt(struct socket *sock, bool compat, int level,
 		return err;
 
 	if (!compat)
-		max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
+		copy_from_sockptr(&max_optlen, optlen, sizeof(int));
 
 	ops = READ_ONCE(sock->ops);
 	if (level == SOL_SOCKET) {




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux