aboutsummaryrefslogtreecommitdiffstats
path: root/fs/smb/server/transport_tcp.c
diff options
context:
space:
mode:
authorNamjae Jeon <linkinjeon@kernel.org>2025-08-05 18:13:13 +0900
committerSteve French <stfrench@microsoft.com>2025-08-07 18:22:58 -0500
commite6bb9193974059ddbb0ce7763fa3882bd60d4dc3 (patch)
treed8d23cbea4af4bf558e1fa4bedd50a6fa7b2b028 /fs/smb/server/transport_tcp.c
parentsmb: server: let recv_done() avoid touching data_transfer after cleanup/move (diff)
downloadlinux-e6bb9193974059ddbb0ce7763fa3882bd60d4dc3.tar.gz
linux-e6bb9193974059ddbb0ce7763fa3882bd60d4dc3.zip
ksmbd: limit repeated connections from clients with the same IP
Repeated connections from clients with the same IP address may exhaust the max connections and prevent other normal client connections. This patch limit repeated connections from clients with the same IP. Reported-by: tianshuo han <hantianshuo233@gmail.com> Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to '')
-rw-r--r--fs/smb/server/transport_tcp.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c
index 4e9f98db9ff4..d72588f33b9c 100644
--- a/fs/smb/server/transport_tcp.c
+++ b/fs/smb/server/transport_tcp.c
@@ -87,6 +87,7 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk)
return NULL;
}
+ conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr;
conn->transport = KSMBD_TRANS(t);
KSMBD_TRANS(t)->conn = conn;
KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops;
@@ -230,6 +231,8 @@ 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;
while (!kthread_should_stop()) {
@@ -248,6 +251,20 @@ static int ksmbd_kthread_fn(void *p)
continue;
}
+ /*
+ * 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) {
+ ret = -EAGAIN;
+ break;
+ }
+ up_read(&conn_list_lock);
+ if (ret == -EAGAIN)
+ continue;
+
if (server_conf.max_connections &&
atomic_inc_return(&active_num_conn) >= server_conf.max_connections) {
pr_info_ratelimited("Limit the maximum number of connections(%u)\n",