Commit 967a72fa authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'v6.18-rc5-smb-server-fixes' of git://git.samba.org/ksmbd

Pull smb server fixes from Steve French:

 - Fix smbdirect (RDMA) disconnect hang bug

 - Fix potential Denial of Service when connection limit exceeded

 - Fix smbdirect (RDMA) connection (potentially accessing freed memory)
   bug

* tag 'v6.18-rc5-smb-server-fixes' of git://git.samba.org/ksmbd:
  smb: server: let smb_direct_disconnect_rdma_connection() turn CREATED into DISCONNECTED
  ksmbd: close accepted socket when per-IP limit rejects connection
  smb: server: rdma: avoid unmapping posted recv on accept failure
parents 6fa9041b 55286b1e
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -334,6 +334,9 @@ smb_direct_disconnect_rdma_connection(struct smbdirect_socket *sc)
		break;

	case SMBDIRECT_SOCKET_CREATED:
		sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
		break;

	case SMBDIRECT_SOCKET_CONNECTED:
		sc->status = SMBDIRECT_SOCKET_ERROR;
		break;
@@ -1883,6 +1886,7 @@ static int smb_direct_accept_client(struct smbdirect_socket *sc)
static int smb_direct_prepare_negotiation(struct smbdirect_socket *sc)
{
	struct smbdirect_recv_io *recvmsg;
	bool recv_posted = false;
	int ret;

	WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_CREATED);
@@ -1899,6 +1903,7 @@ static int smb_direct_prepare_negotiation(struct smbdirect_socket *sc)
		pr_err("Can't post recv: %d\n", ret);
		goto out_err;
	}
	recv_posted = true;

	ret = smb_direct_accept_client(sc);
	if (ret) {
@@ -1908,6 +1913,13 @@ static int smb_direct_prepare_negotiation(struct smbdirect_socket *sc)

	return 0;
out_err:
	/*
	 * If the recv was never posted, return it to the free list.
	 * If it was posted, leave it alone so disconnect teardown can
	 * drain the QP and complete it (flush) and the completion path
	 * will unmap it exactly once.
	 */
	if (!recv_posted)
		put_recvmsg(sc, recvmsg);
	return ret;
}
+4 −1
Original line number Diff line number Diff line
@@ -290,8 +290,11 @@ static int ksmbd_kthread_fn(void *p)
			}
		}
		up_read(&conn_list_lock);
		if (ret == -EAGAIN)
		if (ret == -EAGAIN) {
			/* Per-IP limit hit: release the just-accepted socket. */
			sock_release(client_sk);
			continue;
		}

skip_max_ip_conns_limit:
		if (server_conf.max_connections &&