Skip to content

Commit e628bf9

Browse files
namjaejeonSteve French
authored andcommitted
ksmbd: reduce descriptor size if remaining bytes is less than request size
Create 3 kinds of files to reproduce this problem. dd if=/dev/urandom of=127k.bin bs=1024 count=127 dd if=/dev/urandom of=128k.bin bs=1024 count=128 dd if=/dev/urandom of=129k.bin bs=1024 count=129 When copying files from ksmbd share to windows or cifs.ko, The following error message happen from windows client. "The file '129k.bin' is too large for the destination filesystem." We can see the error logs from ksmbd debug prints [48394.611537] ksmbd: RDMA r/w request 0x0: token 0x669d, length 0x20000 [48394.612054] ksmbd: smb_direct: RDMA write, len 0x20000, needed credits 0x1 [48394.612572] ksmbd: filename 129k.bin, offset 131072, len 131072 [48394.614189] ksmbd: nbytes 1024, offset 132096 mincount 0 [48394.614585] ksmbd: Failed to process 8 [-22] And we can reproduce it with cifs.ko, e.g. dd if=129k.bin of=/dev/null bs=128KB count=2 This problem is that ksmbd rdma return error if remaining bytes is less than Length of Buffer Descriptor V1 Structure. smb_direct_rdma_xmit() ... if (desc_buf_len == 0 || total_length > buf_len || total_length > t->max_rdma_rw_size) return -EINVAL; This patch reduce descriptor size with remaining bytes and remove the check for total_length and buf_len. Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 65656f5 commit e628bf9

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

fs/smb/server/transport_rdma.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,24 +1364,35 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t,
13641364
LIST_HEAD(msg_list);
13651365
char *desc_buf;
13661366
int credits_needed;
1367-
unsigned int desc_buf_len;
1368-
size_t total_length = 0;
1367+
unsigned int desc_buf_len, desc_num = 0;
13691368

13701369
if (t->status != SMB_DIRECT_CS_CONNECTED)
13711370
return -ENOTCONN;
13721371

1372+
if (buf_len > t->max_rdma_rw_size)
1373+
return -EINVAL;
1374+
13731375
/* calculate needed credits */
13741376
credits_needed = 0;
13751377
desc_buf = buf;
13761378
for (i = 0; i < desc_len / sizeof(*desc); i++) {
1379+
if (!buf_len)
1380+
break;
1381+
13771382
desc_buf_len = le32_to_cpu(desc[i].length);
1383+
if (!desc_buf_len)
1384+
return -EINVAL;
1385+
1386+
if (desc_buf_len > buf_len) {
1387+
desc_buf_len = buf_len;
1388+
desc[i].length = cpu_to_le32(desc_buf_len);
1389+
buf_len = 0;
1390+
}
13781391

13791392
credits_needed += calc_rw_credits(t, desc_buf, desc_buf_len);
13801393
desc_buf += desc_buf_len;
1381-
total_length += desc_buf_len;
1382-
if (desc_buf_len == 0 || total_length > buf_len ||
1383-
total_length > t->max_rdma_rw_size)
1384-
return -EINVAL;
1394+
buf_len -= desc_buf_len;
1395+
desc_num++;
13851396
}
13861397

13871398
ksmbd_debug(RDMA, "RDMA %s, len %#x, needed credits %#x\n",
@@ -1393,7 +1404,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t,
13931404

13941405
/* build rdma_rw_ctx for each descriptor */
13951406
desc_buf = buf;
1396-
for (i = 0; i < desc_len / sizeof(*desc); i++) {
1407+
for (i = 0; i < desc_num; i++) {
13971408
msg = kzalloc(offsetof(struct smb_direct_rdma_rw_msg, sg_list) +
13981409
sizeof(struct scatterlist) * SG_CHUNK_SIZE, GFP_KERNEL);
13991410
if (!msg) {

0 commit comments

Comments
 (0)