|
| 1 | +net: Avoid address overwrite in kernel_connect |
| 2 | + |
| 3 | +jira LE-1907 |
| 4 | +Rebuild_History Non-Buildable kernel-5.14.0-427.31.1.el9_4 |
| 5 | +commit-author Jordan Rife <jrife@google.com> |
| 6 | +commit 0bdf399342c5acbd817c9098b6c7ed21f1974312 |
| 7 | +Empty-Commit: Cherry-Pick Conflicts during history rebuild. |
| 8 | +Will be included in final tarball splat. Ref for failed cherry-pick at: |
| 9 | +ciq/ciq_backports/kernel-5.14.0-427.31.1.el9_4/0bdf3993.failed |
| 10 | + |
| 11 | +BPF programs that run on connect can rewrite the connect address. For |
| 12 | +the connect system call this isn't a problem, because a copy of the address |
| 13 | +is made when it is moved into kernel space. However, kernel_connect |
| 14 | +simply passes through the address it is given, so the caller may observe |
| 15 | +its address value unexpectedly change. |
| 16 | + |
| 17 | +A practical example where this is problematic is where NFS is combined |
| 18 | +with a system such as Cilium which implements BPF-based load balancing. |
| 19 | +A common pattern in software-defined storage systems is to have an NFS |
| 20 | +mount that connects to a persistent virtual IP which in turn maps to an |
| 21 | +ephemeral server IP. This is usually done to achieve high availability: |
| 22 | +if your server goes down you can quickly spin up a replacement and remap |
| 23 | +the virtual IP to that endpoint. With BPF-based load balancing, mounts |
| 24 | +will forget the virtual IP address when the address rewrite occurs |
| 25 | +because a pointer to the only copy of that address is passed down the |
| 26 | +stack. Server failover then breaks, because clients have forgotten the |
| 27 | +virtual IP address. Reconnects fail and mounts remain broken. This patch |
| 28 | +was tested by setting up a scenario like this and ensuring that NFS |
| 29 | +reconnects worked after applying the patch. |
| 30 | + |
| 31 | + Signed-off-by: Jordan Rife <jrife@google.com> |
| 32 | + Signed-off-by: David S. Miller <davem@davemloft.net> |
| 33 | +(cherry picked from commit 0bdf399342c5acbd817c9098b6c7ed21f1974312) |
| 34 | + Signed-off-by: Jonathan Maple <jmaple@ciq.com> |
| 35 | + |
| 36 | +# Conflicts: |
| 37 | +# net/socket.c |
| 38 | +diff --cc net/socket.c |
| 39 | +index a02d2b6014eb,848116d06b51..000000000000 |
| 40 | +--- a/net/socket.c |
| 41 | ++++ b/net/socket.c |
| 42 | +@@@ -3531,7 -3567,12 +3531,16 @@@ EXPORT_SYMBOL(kernel_accept) |
| 43 | + int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, |
| 44 | + int flags) |
| 45 | + { |
| 46 | +++<<<<<<< HEAD |
| 47 | + + return sock->ops->connect(sock, addr, addrlen, flags); |
| 48 | +++======= |
| 49 | ++ struct sockaddr_storage address; |
| 50 | ++ |
| 51 | ++ memcpy(&address, addr, addrlen); |
| 52 | ++ |
| 53 | ++ return READ_ONCE(sock->ops)->connect(sock, (struct sockaddr *)&address, |
| 54 | ++ addrlen, flags); |
| 55 | +++>>>>>>> 0bdf399342c5 (net: Avoid address overwrite in kernel_connect) |
| 56 | + } |
| 57 | + EXPORT_SYMBOL(kernel_connect); |
| 58 | + |
| 59 | +* Unmerged path net/socket.c |
0 commit comments