]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
7e2a1df0593f4a3616c2304fe28c86efe1889661
[thirdparty/kernel/stable-queue.git] /
1 From stable+bounces-180816-greg=kroah.com@vger.kernel.org Sun Sep 21 17:00:42 2025
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Sun, 21 Sep 2025 11:00:33 -0400
4 Subject: ksmbd: smbdirect: validate data_offset and data_length field of smb_direct_data_transfer
5 To: stable@vger.kernel.org
6 Cc: Namjae Jeon <linkinjeon@kernel.org>, Stefan Metzmacher <metze@samba.org>, "Luigino Camastra, Aisle Research" <luigino.camastra@aisle.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
7 Message-ID: <20250921150033.2932212-1-sashal@kernel.org>
8
9 From: Namjae Jeon <linkinjeon@kernel.org>
10
11 [ Upstream commit 5282491fc49d5614ac6ddcd012e5743eecb6a67c ]
12
13 If data_offset and data_length of smb_direct_data_transfer struct are
14 invalid, out of bounds issue could happen.
15 This patch validate data_offset and data_length field in recv_done.
16
17 Cc: stable@vger.kernel.org
18 Fixes: 2ea086e35c3d ("ksmbd: add buffer validation for smb direct")
19 Reviewed-by: Stefan Metzmacher <metze@samba.org>
20 Reported-by: Luigino Camastra, Aisle Research <luigino.camastra@aisle.com>
21 Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
22 Signed-off-by: Steve French <stfrench@microsoft.com>
23 [ Applied to fs/ksmbd/transport_rdma.c instead of fs/smb/server/transport_rdma.c ]
24 Signed-off-by: Sasha Levin <sashal@kernel.org>
25 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26 ---
27 fs/ksmbd/transport_rdma.c | 17 +++++++++--------
28 1 file changed, 9 insertions(+), 8 deletions(-)
29
30 --- a/fs/ksmbd/transport_rdma.c
31 +++ b/fs/ksmbd/transport_rdma.c
32 @@ -548,7 +548,7 @@ static void recv_done(struct ib_cq *cq,
33 case SMB_DIRECT_MSG_DATA_TRANSFER: {
34 struct smb_direct_data_transfer *data_transfer =
35 (struct smb_direct_data_transfer *)recvmsg->packet;
36 - unsigned int data_length;
37 + unsigned int data_offset, data_length;
38 int avail_recvmsg_count, receive_credits;
39
40 if (wc->byte_len <
41 @@ -559,14 +559,15 @@ static void recv_done(struct ib_cq *cq,
42 }
43
44 data_length = le32_to_cpu(data_transfer->data_length);
45 - if (data_length) {
46 - if (wc->byte_len < sizeof(struct smb_direct_data_transfer) +
47 - (u64)data_length) {
48 - put_recvmsg(t, recvmsg);
49 - smb_direct_disconnect_rdma_connection(t);
50 - return;
51 - }
52 + data_offset = le32_to_cpu(data_transfer->data_offset);
53 + if (wc->byte_len < data_offset ||
54 + wc->byte_len < (u64)data_offset + data_length) {
55 + put_recvmsg(t, recvmsg);
56 + smb_direct_disconnect_rdma_connection(t);
57 + return;
58 + }
59
60 + if (data_length) {
61 if (t->full_packet_received)
62 recvmsg->first_segment = true;
63