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

Merge tag 'v6.15rc-part1-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull smb server updates from Steve French:

 - Two fixes for bounds checks of open contexts

 - Two multichannel fixes, including one for important UAF

 - Oplock/lease break fix for potential ksmbd connection refcount leak

 - Security fix to free crypto data more securely

 - Fix to enable allowing Kerberos authentication by default

 - Two RDMA/smbdirect fixes

 - Minor cleanup

* tag 'v6.15rc-part1-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: fix r_count dec/increment mismatch
  ksmbd: fix multichannel connection failure
  ksmbd: fix use-after-free in ksmbd_sessions_deregister()
  ksmbd: use ib_device_get_netdev() instead of calling ops.get_netdev
  ksmbd: use aead_request_free to match aead_request_alloc
  Revert "ksmbd: fix missing RDMA-capable flag for IPoIB device in ksmbd_rdma_capable_netdev()"
  ksmbd: add bounds check for create lease context
  ksmbd: add bounds check for durable handle context
  ksmbd: make SMB_SERVER_KERBEROS5 enable by default
  ksmbd: Use str_read_write() and str_true_false() helpers
parents 8b175e2e ddb7ea36
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -70,4 +70,4 @@ config SMB_SERVER_CHECK_CAP_NET_ADMIN
config SMB_SERVER_KERBEROS5
	bool "Support for Kerberos 5"
	depends on SMB_SERVER
	default n
	default y
+1 −1
Original line number Diff line number Diff line
@@ -1218,7 +1218,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
free_sg:
	kfree(sg);
free_req:
	kfree(req);
	aead_request_free(req);
free_ctx:
	ksmbd_release_crypto_ctx(ctx);
	return rc;
+19 −0
Original line number Diff line number Diff line
@@ -230,6 +230,9 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
			if (!ksmbd_chann_del(conn, sess) &&
			    xa_empty(&sess->ksmbd_chann_list)) {
				hash_del(&sess->hlist);
				down_write(&conn->session_lock);
				xa_erase(&conn->sessions, sess->id);
				up_write(&conn->session_lock);
				ksmbd_session_destroy(sess);
			}
		}
@@ -256,6 +259,22 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
	up_write(&sessions_table_lock);
}

bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
				   unsigned long long id)
{
	struct ksmbd_session *sess;

	down_read(&conn->session_lock);
	sess = xa_load(&conn->sessions, id);
	if (sess) {
		up_read(&conn->session_lock);
		return true;
	}
	up_read(&conn->session_lock);

	return false;
}

struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
					   unsigned long long id)
{
+2 −0
Original line number Diff line number Diff line
@@ -87,6 +87,8 @@ void ksmbd_session_destroy(struct ksmbd_session *sess);
struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id);
struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
					   unsigned long long id);
bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
				     unsigned long long id);
int ksmbd_session_register(struct ksmbd_conn *conn,
			   struct ksmbd_session *sess);
void ksmbd_sessions_deregister(struct ksmbd_conn *conn);
+10 −2
Original line number Diff line number Diff line
@@ -724,8 +724,8 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
	work->conn = conn;
	work->sess = opinfo->sess;

	if (opinfo->op_state == OPLOCK_ACK_WAIT) {
	ksmbd_conn_r_count_inc(conn);
	if (opinfo->op_state == OPLOCK_ACK_WAIT) {
		INIT_WORK(&work->work, __smb2_oplock_break_noti);
		ksmbd_queue_work(work);

@@ -833,8 +833,8 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
	work->conn = conn;
	work->sess = opinfo->sess;

	if (opinfo->op_state == OPLOCK_ACK_WAIT) {
	ksmbd_conn_r_count_inc(conn);
	if (opinfo->op_state == OPLOCK_ACK_WAIT) {
		INIT_WORK(&work->work, __smb2_lease_break_noti);
		ksmbd_queue_work(work);
		wait_for_break_ack(opinfo);
@@ -1505,6 +1505,10 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
	if (sizeof(struct lease_context_v2) == le32_to_cpu(cc->DataLength)) {
		struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;

		if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
		    sizeof(struct create_lease_v2) - 4)
			return NULL;

		memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
		lreq->req_state = lc->lcontext.LeaseState;
		lreq->flags = lc->lcontext.LeaseFlags;
@@ -1517,6 +1521,10 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
	} else {
		struct create_lease *lc = (struct create_lease *)cc;

		if (le16_to_cpu(cc->DataOffset) + le32_to_cpu(cc->DataLength) <
		    sizeof(struct create_lease))
			return NULL;

		memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
		lreq->req_state = lc->lcontext.LeaseState;
		lreq->flags = lc->lcontext.LeaseFlags;
Loading