Patch "xsk: Honor SO_BINDTODEVICE on bind" has been added to the 6.1-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

    xsk: Honor SO_BINDTODEVICE on bind

to the 6.1-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:
     xsk-honor-so_bindtodevice-on-bind.patch
and it can be found in the queue-6.1 subdirectory.

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



commit ce5a1e02a3139e887cb4a454e46c175e800509fe
Author: Ilya Maximets <i.maximets@xxxxxxx>
Date:   Mon Jul 3 19:53:29 2023 +0200

    xsk: Honor SO_BINDTODEVICE on bind
    
    [ Upstream commit f7306acec9aae9893d15e745c8791124d42ab10a ]
    
    Initial creation of an AF_XDP socket requires CAP_NET_RAW capability. A
    privileged process might create the socket and pass it to a non-privileged
    process for later use. However, that process will be able to bind the socket
    to any network interface. Even though it will not be able to receive any
    traffic without modification of the BPF map, the situation is not ideal.
    
    Sockets already have a mechanism that can be used to restrict what interface
    they can be attached to. That is SO_BINDTODEVICE.
    
    To change the SO_BINDTODEVICE binding the process will need CAP_NET_RAW.
    
    Make xsk_bind() honor the SO_BINDTODEVICE in order to allow safer workflow
    when non-privileged process is using AF_XDP.
    
    The intended workflow is following:
    
      1. First process creates a bare socket with socket(AF_XDP, ...).
      2. First process loads the XSK program to the interface.
      3. First process adds the socket fd to a BPF map.
      4. First process ties socket fd to a particular interface using
         SO_BINDTODEVICE.
      5. First process sends socket fd to a second process.
      6. Second process allocates UMEM.
      7. Second process binds socket to the interface with bind(...).
      8. Second process sends/receives the traffic.
    
    All the steps above are possible today if the first process is privileged
    and the second one has sufficient RLIMIT_MEMLOCK and no capabilities.
    However, the second process will be able to bind the socket to any interface
    it wants on step 7 and send traffic from it. With the proposed change, the
    second process will be able to bind the socket only to a specific interface
    chosen by the first process at step 4.
    
    Fixes: 965a99098443 ("xsk: add support for bind for Rx")
    Signed-off-by: Ilya Maximets <i.maximets@xxxxxxx>
    Signed-off-by: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
    Acked-by: Magnus Karlsson <magnus.karlsson@xxxxxxxxx>
    Acked-by: John Fastabend <john.fastabend@xxxxxxxxx>
    Acked-by: Jason Wang <jasowang@xxxxxxxxxx>
    Link: https://lore.kernel.org/bpf/20230703175329.3259672-1-i.maximets@xxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/Documentation/networking/af_xdp.rst b/Documentation/networking/af_xdp.rst
index 60b217b436be6..5b77b9e5ac7e6 100644
--- a/Documentation/networking/af_xdp.rst
+++ b/Documentation/networking/af_xdp.rst
@@ -433,6 +433,15 @@ start N bytes into the buffer leaving the first N bytes for the
 application to use. The final option is the flags field, but it will
 be dealt with in separate sections for each UMEM flag.
 
+SO_BINDTODEVICE setsockopt
+--------------------------
+
+This is a generic SOL_SOCKET option that can be used to tie AF_XDP
+socket to a particular network interface.  It is useful when a socket
+is created by a privileged process and passed to a non-privileged one.
+Once the option is set, kernel will refuse attempts to bind that socket
+to a different interface.  Updating the value requires CAP_NET_RAW.
+
 XDP_STATISTICS getsockopt
 -------------------------
 
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 13f62d2402e71..371d269d22fa0 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -886,6 +886,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 	struct sock *sk = sock->sk;
 	struct xdp_sock *xs = xdp_sk(sk);
 	struct net_device *dev;
+	int bound_dev_if;
 	u32 flags, qid;
 	int err = 0;
 
@@ -899,6 +900,10 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 		      XDP_USE_NEED_WAKEUP))
 		return -EINVAL;
 
+	bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+	if (bound_dev_if && bound_dev_if != sxdp->sxdp_ifindex)
+		return -EINVAL;
+
 	rtnl_lock();
 	mutex_lock(&xs->mutex);
 	if (xs->state != XSK_READY) {



[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