Skip to content

Commit 05de41f

Browse files
committed
Merge tag 'v6.18-rc1-smb-server-fixes' of git://git.samba.org/ksmbd
Pull smb server fixes from Steve French: - Fix RPC hang due to locking bug - Fix for memory leak in read and refcount leak (in session setup) - Minor cleanup * tag 'v6.18-rc1-smb-server-fixes' of git://git.samba.org/ksmbd: ksmbd: fix recursive locking in RPC handle list access smb/server: fix possible refcount leak in smb2_sess_setup() smb/server: fix possible memory leak in smb2_read() smb: server: Use common error handling code in smb_direct_rdma_xmit()
2 parents 634ec1f + 88f1708 commit 05de41f

File tree

4 files changed

+34
-16
lines changed

4 files changed

+34
-16
lines changed

fs/smb/server/mgmt/user_session.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,11 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id)
147147
int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
148148
{
149149
struct ksmbd_session_rpc *entry;
150-
int method;
151150

152-
down_read(&sess->rpc_lock);
151+
lockdep_assert_held(&sess->rpc_lock);
153152
entry = xa_load(&sess->rpc_handle_list, id);
154-
method = entry ? entry->method : 0;
155-
up_read(&sess->rpc_lock);
156153

157-
return method;
154+
return entry ? entry->method : 0;
158155
}
159156

160157
void ksmbd_session_destroy(struct ksmbd_session *sess)

fs/smb/server/smb2pdu.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
18061806

18071807
if (ksmbd_conn_need_reconnect(conn)) {
18081808
rc = -EFAULT;
1809+
ksmbd_user_session_put(sess);
18091810
sess = NULL;
18101811
goto out_err;
18111812
}
@@ -4625,8 +4626,15 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
46254626
* pipe without opening it, checking error condition here
46264627
*/
46274628
id = req->VolatileFileId;
4628-
if (!ksmbd_session_rpc_method(sess, id))
4629+
4630+
lockdep_assert_not_held(&sess->rpc_lock);
4631+
4632+
down_read(&sess->rpc_lock);
4633+
if (!ksmbd_session_rpc_method(sess, id)) {
4634+
up_read(&sess->rpc_lock);
46294635
return -ENOENT;
4636+
}
4637+
up_read(&sess->rpc_lock);
46304638

46314639
ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n",
46324640
req->FileInfoClass, req->VolatileFileId);
@@ -6824,6 +6832,7 @@ int smb2_read(struct ksmbd_work *work)
68246832

68256833
nbytes = ksmbd_vfs_read(work, fp, length, &offset, aux_payload_buf);
68266834
if (nbytes < 0) {
6835+
kvfree(aux_payload_buf);
68276836
err = nbytes;
68286837
goto out;
68296838
}

fs/smb/server/transport_ipc.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle
825825
if (!msg)
826826
return NULL;
827827

828+
lockdep_assert_not_held(&sess->rpc_lock);
829+
830+
down_read(&sess->rpc_lock);
828831
msg->type = KSMBD_EVENT_RPC_REQUEST;
829832
req = (struct ksmbd_rpc_command *)msg->payload;
830833
req->handle = handle;
@@ -833,6 +836,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle
833836
req->flags |= KSMBD_RPC_WRITE_METHOD;
834837
req->payload_sz = payload_sz;
835838
memcpy(req->payload, payload, payload_sz);
839+
up_read(&sess->rpc_lock);
836840

837841
resp = ipc_msg_send_request(msg, req->handle);
838842
ipc_msg_free(msg);
@@ -849,13 +853,17 @@ struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle)
849853
if (!msg)
850854
return NULL;
851855

856+
lockdep_assert_not_held(&sess->rpc_lock);
857+
858+
down_read(&sess->rpc_lock);
852859
msg->type = KSMBD_EVENT_RPC_REQUEST;
853860
req = (struct ksmbd_rpc_command *)msg->payload;
854861
req->handle = handle;
855862
req->flags = ksmbd_session_rpc_method(sess, handle);
856863
req->flags |= rpc_context_flags(sess);
857864
req->flags |= KSMBD_RPC_READ_METHOD;
858865
req->payload_sz = 0;
866+
up_read(&sess->rpc_lock);
859867

860868
resp = ipc_msg_send_request(msg, req->handle);
861869
ipc_msg_free(msg);
@@ -876,6 +884,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle
876884
if (!msg)
877885
return NULL;
878886

887+
lockdep_assert_not_held(&sess->rpc_lock);
888+
889+
down_read(&sess->rpc_lock);
879890
msg->type = KSMBD_EVENT_RPC_REQUEST;
880891
req = (struct ksmbd_rpc_command *)msg->payload;
881892
req->handle = handle;
@@ -884,6 +895,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle
884895
req->flags |= KSMBD_RPC_IOCTL_METHOD;
885896
req->payload_sz = payload_sz;
886897
memcpy(req->payload, payload, payload_sz);
898+
up_read(&sess->rpc_lock);
887899

888900
resp = ipc_msg_send_request(msg, req->handle);
889901
ipc_msg_free(msg);

fs/smb/server/transport_rdma.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,18 +1574,14 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t,
15741574
get_buf_page_count(desc_buf, desc_buf_len),
15751575
msg->sg_list, SG_CHUNK_SIZE);
15761576
if (ret) {
1577-
kfree(msg);
15781577
ret = -ENOMEM;
1579-
goto out;
1578+
goto free_msg;
15801579
}
15811580

15821581
ret = get_sg_list(desc_buf, desc_buf_len,
15831582
msg->sgt.sgl, msg->sgt.orig_nents);
1584-
if (ret < 0) {
1585-
sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE);
1586-
kfree(msg);
1587-
goto out;
1588-
}
1583+
if (ret < 0)
1584+
goto free_table;
15891585

15901586
ret = rdma_rw_ctx_init(&msg->rdma_ctx, sc->ib.qp, sc->ib.qp->port,
15911587
msg->sgt.sgl,
@@ -1596,9 +1592,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t,
15961592
is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
15971593
if (ret < 0) {
15981594
pr_err("failed to init rdma_rw_ctx: %d\n", ret);
1599-
sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE);
1600-
kfree(msg);
1601-
goto out;
1595+
goto free_table;
16021596
}
16031597

16041598
list_add_tail(&msg->list, &msg_list);
@@ -1630,6 +1624,12 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t,
16301624
atomic_add(credits_needed, &sc->rw_io.credits.count);
16311625
wake_up(&sc->rw_io.credits.wait_queue);
16321626
return ret;
1627+
1628+
free_table:
1629+
sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE);
1630+
free_msg:
1631+
kfree(msg);
1632+
goto out;
16331633
}
16341634

16351635
static int smb_direct_rdma_write(struct ksmbd_transport *t,

0 commit comments

Comments
 (0)