]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ksmbd: extend the connection limiting mechanism to support IPv6
authorNamjae Jeon <linkinjeon@kernel.org>
Sun, 17 Aug 2025 00:48:40 +0000 (09:48 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Aug 2025 14:26:05 +0000 (16:26 +0200)
commit c0d41112f1a5828c194b59cca953114bc3776ef2 upstream.

Update the connection tracking logic to handle both IPv4 and IPv6
address families.

Cc: stable@vger.kernel.org
Fixes: e6bb91939740 ("ksmbd: limit repeated connections from clients with the same IP")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/smb/server/connection.h
fs/smb/server/transport_tcp.c

index 0e72be594e910bf94d6a6338d65409180a8f94d6..1f02e10924345ec762203fdc80848516f4376551 100644 (file)
@@ -45,7 +45,12 @@ struct ksmbd_conn {
        struct mutex                    srv_mutex;
        int                             status;
        unsigned int                    cli_cap;
-       __be32                          inet_addr;
+       union {
+               __be32                  inet_addr;
+#if IS_ENABLED(CONFIG_IPV6)
+               u8                      inet6_addr[16];
+#endif
+       };
        char                            *request_buf;
        struct ksmbd_transport          *transport;
        struct nls_table                *local_nls;
index 1222cf6be5efab04733daa9fb676ce056e0f169d..a4e7d1a5d64d73acc487fa686d3689c66ef26220 100644 (file)
@@ -87,7 +87,14 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk)
                return NULL;
        }
 
+#if IS_ENABLED(CONFIG_IPV6)
+       if (client_sk->sk->sk_family == AF_INET6)
+               memcpy(&conn->inet6_addr, &client_sk->sk->sk_v6_daddr, 16);
+       else
+               conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
+#else
        conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
+#endif
        conn->transport = KSMBD_TRANS(t);
        KSMBD_TRANS(t)->conn = conn;
        KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops;
@@ -227,7 +234,6 @@ static int ksmbd_kthread_fn(void *p)
 {
        struct socket *client_sk = NULL;
        struct interface *iface = (struct interface *)p;
-       struct inet_sock *csk_inet;
        struct ksmbd_conn *conn;
        int ret;
 
@@ -250,13 +256,27 @@ static int ksmbd_kthread_fn(void *p)
                /*
                 * Limits repeated connections from clients with the same IP.
                 */
-               csk_inet = inet_sk(client_sk->sk);
                down_read(&conn_list_lock);
                list_for_each_entry(conn, &conn_list, conns_list)
-                       if (csk_inet->inet_daddr == conn->inet_addr) {
+#if IS_ENABLED(CONFIG_IPV6)
+                       if (client_sk->sk->sk_family == AF_INET6) {
+                               if (memcmp(&client_sk->sk->sk_v6_daddr,
+                                          &conn->inet6_addr, 16) == 0) {
+                                       ret = -EAGAIN;
+                                       break;
+                               }
+                       } else if (inet_sk(client_sk->sk)->inet_daddr ==
+                                conn->inet_addr) {
+                               ret = -EAGAIN;
+                               break;
+                       }
+#else
+                       if (inet_sk(client_sk->sk)->inet_daddr ==
+                           conn->inet_addr) {
                                ret = -EAGAIN;
                                break;
                        }
+#endif
                up_read(&conn_list_lock);
                if (ret == -EAGAIN)
                        continue;