Commit 2632d81f authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull smb server fixes from Steve French:

 - fix use after free in lease break

 - small fix for freeing rdma transport (fixes missing logging of
   cm_qp_destroy)

 - fix write count leak

* tag 'v6.16-rc5-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: fix potential use-after-free in oplock/lease break ack
  ksmbd: fix a mount write count leak in ksmbd_vfs_kern_path_locked()
  smb: server: make use of rdma_destroy_qp()
parents 379f604c 50f930db
Loading
Loading
Loading
Loading
+9 −20
Original line number Diff line number Diff line
@@ -8573,11 +8573,6 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
		goto err_out;
	}

	opinfo->op_state = OPLOCK_STATE_NONE;
	wake_up_interruptible_all(&opinfo->oplock_q);
	opinfo_put(opinfo);
	ksmbd_fd_put(work, fp);

	rsp->StructureSize = cpu_to_le16(24);
	rsp->OplockLevel = rsp_oplevel;
	rsp->Reserved = 0;
@@ -8585,16 +8580,15 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
	rsp->VolatileFid = volatile_id;
	rsp->PersistentFid = persistent_id;
	ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break));
	if (!ret)
		return;

	if (ret) {
err_out:
		smb2_set_err_rsp(work);
	}

	opinfo->op_state = OPLOCK_STATE_NONE;
	wake_up_interruptible_all(&opinfo->oplock_q);

	opinfo_put(opinfo);
	ksmbd_fd_put(work, fp);
	smb2_set_err_rsp(work);
}

static int check_lease_state(struct lease *lease, __le32 req_state)
@@ -8724,11 +8718,6 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
	}

	lease_state = lease->state;
	opinfo->op_state = OPLOCK_STATE_NONE;
	wake_up_interruptible_all(&opinfo->oplock_q);
	atomic_dec(&opinfo->breaking_cnt);
	wake_up_interruptible_all(&opinfo->oplock_brk);
	opinfo_put(opinfo);

	rsp->StructureSize = cpu_to_le16(36);
	rsp->Reserved = 0;
@@ -8737,16 +8726,16 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
	rsp->LeaseState = lease_state;
	rsp->LeaseDuration = 0;
	ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack));
	if (!ret)
		return;

	if (ret) {
err_out:
		smb2_set_err_rsp(work);
	}

	opinfo->op_state = OPLOCK_STATE_NONE;
	wake_up_interruptible_all(&opinfo->oplock_q);
	atomic_dec(&opinfo->breaking_cnt);
	wake_up_interruptible_all(&opinfo->oplock_brk);

	opinfo_put(opinfo);
	smb2_set_err_rsp(work);
}

/**
+3 −2
Original line number Diff line number Diff line
@@ -433,7 +433,8 @@ static void free_transport(struct smb_direct_transport *t)
	if (t->qp) {
		ib_drain_qp(t->qp);
		ib_mr_pool_destroy(t->qp, &t->qp->rdma_mrs);
		ib_destroy_qp(t->qp);
		t->qp = NULL;
		rdma_destroy_qp(t->cm_id);
	}

	ksmbd_debug(RDMA, "drain the reassembly queue\n");
@@ -1940,8 +1941,8 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t,
	return 0;
err:
	if (t->qp) {
		ib_destroy_qp(t->qp);
		t->qp = NULL;
		rdma_destroy_qp(t->cm_id);
	}
	if (t->recv_cq) {
		ib_destroy_cq(t->recv_cq);
+1 −0
Original line number Diff line number Diff line
@@ -1282,6 +1282,7 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,

		err = ksmbd_vfs_lock_parent(parent_path->dentry, path->dentry);
		if (err) {
			mnt_drop_write(parent_path->mnt);
			path_put(path);
			path_put(parent_path);
		}