Commit eb4a0992 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '6.17-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull smb server fixes from Steve French:

 - fix refcount issue that can cause memory leak

 - rate limit repeated connections from IPv6, not just IPv4 addresses

 - fix potential null pointer access of smb direct work queue

* tag '6.17-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: fix refcount leak causing resource not released
  ksmbd: extend the connection limiting mechanism to support IPv6
  smb: server: split ksmbd_rdma_stop_listening() out of ksmbd_rdma_destroy()
parents 068a56e5 89bb430f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -504,7 +504,8 @@ void ksmbd_conn_transport_destroy(void)
{
	mutex_lock(&init_lock);
	ksmbd_tcp_destroy();
	ksmbd_rdma_destroy();
	ksmbd_rdma_stop_listening();
	stop_sessions();
	ksmbd_rdma_destroy();
	mutex_unlock(&init_lock);
}
+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;
+10 −3
Original line number Diff line number Diff line
@@ -1102,8 +1102,10 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
			if (!atomic_inc_not_zero(&opinfo->refcount))
				continue;

			if (ksmbd_conn_releasing(opinfo->conn))
			if (ksmbd_conn_releasing(opinfo->conn)) {
				opinfo_put(opinfo);
				continue;
			}

			oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL);
			opinfo_put(opinfo);
@@ -1139,8 +1141,11 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
			if (!atomic_inc_not_zero(&opinfo->refcount))
				continue;

			if (ksmbd_conn_releasing(opinfo->conn))
			if (ksmbd_conn_releasing(opinfo->conn)) {
				opinfo_put(opinfo);
				continue;
			}

			oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL);
			opinfo_put(opinfo);
		}
@@ -1343,8 +1348,10 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
		if (!atomic_inc_not_zero(&brk_op->refcount))
			continue;

		if (ksmbd_conn_releasing(brk_op->conn))
		if (ksmbd_conn_releasing(brk_op->conn)) {
			opinfo_put(brk_op);
			continue;
		}

		if (brk_op->is_lease && (brk_op->o_lease->state &
		    (~(SMB2_LEASE_READ_CACHING_LE |
+4 −1
Original line number Diff line number Diff line
@@ -2194,7 +2194,7 @@ int ksmbd_rdma_init(void)
	return 0;
}

void ksmbd_rdma_destroy(void)
void ksmbd_rdma_stop_listening(void)
{
	if (!smb_direct_listener.cm_id)
		return;
@@ -2203,7 +2203,10 @@ void ksmbd_rdma_destroy(void)
	rdma_destroy_id(smb_direct_listener.cm_id);

	smb_direct_listener.cm_id = NULL;
}

void ksmbd_rdma_destroy(void)
{
	if (smb_direct_wq) {
		destroy_workqueue(smb_direct_wq);
		smb_direct_wq = NULL;
+3 −1
Original line number Diff line number Diff line
@@ -54,13 +54,15 @@ struct smb_direct_data_transfer {

#ifdef CONFIG_SMB_SERVER_SMBDIRECT
int ksmbd_rdma_init(void);
void ksmbd_rdma_stop_listening(void);
void ksmbd_rdma_destroy(void);
bool ksmbd_rdma_capable_netdev(struct net_device *netdev);
void init_smbd_max_io_size(unsigned int sz);
unsigned int get_smbd_max_read_write_size(void);
#else
static inline int ksmbd_rdma_init(void) { return 0; }
static inline int ksmbd_rdma_destroy(void) { return 0; }
static inline void ksmbd_rdma_stop_listening(void) { }
static inline void ksmbd_rdma_destroy(void) { }
static inline bool ksmbd_rdma_capable_netdev(struct net_device *netdev) { return false; }
static inline void init_smbd_max_io_size(unsigned int sz) { }
static inline unsigned int get_smbd_max_read_write_size(void) { return 0; }
Loading