Commit c0d41112 authored by Namjae Jeon's avatar Namjae Jeon Committed by Steve French
Browse files

ksmbd: extend the connection limiting mechanism to support IPv6



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

Cc: stable@vger.kernel.org
Fixes: e6bb9193 ("ksmbd: limit repeated connections from clients with the same IP")
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent bac7b996
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -46,7 +46,12 @@ struct ksmbd_conn {
	struct mutex			srv_mutex;
	int				status;
	unsigned int			cli_cap;
	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;
+23 −3
Original line number Diff line number Diff line
@@ -85,7 +85,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;
@@ -229,7 +236,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;

@@ -252,13 +258,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;