Currently, previously connected sockets stay in the 4-tuple hash after
__udp_disconnect if the socket was bound to a specific port or port:addr
pair. This is benign if inet_daddr/inet_dport are cleared as well, since
lookups matching the old 4-tuple will not find this socket in the hash.
To maintain the same behavior as before if inet_daddr/inet_dport are not
cleared in __udp_disconnect, always remove a socket from the hash on
disconnect or abort to prevent a lookup for the original 4-tuple from
finding the socket.
Signed-off-by: Jordan Rife <redacted>
---
net/ipv4/udp.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index d91c587c3657..6e5ba2ce9314 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2235,10 +2235,20 @@ int __udp_disconnect(struct sock *sk, int flags)
}
EXPORT_SYMBOL(__udp_disconnect);
+static int udp_disconnect_unhash4(struct sock *sk, int flags)
+{
+ struct udp_table *udptable = udp_get_table_prot(sk);
+
+ udp_unhash4(udptable, sk);
+ __udp_disconnect(sk, flags);
+
+ return 0;
+}
+
int udp_disconnect(struct sock *sk, int flags)
{
lock_sock(sk);
- __udp_disconnect(sk, flags);
+ udp_disconnect_unhash4(sk, flags);
release_sock(sk);
return 0;
}@@ -3254,7 +3264,7 @@ int udp_abort(struct sock *sk, int err)
sk->sk_err = err;
sk_error_report(sk);
- __udp_disconnect(sk, 0);
+ udp_disconnect_unhash4(sk, 0);
out:
if (!has_current_bpf_ctx())
--
2.53.0.1118.gaef5881109-goog