ksmbd: validate credit charge after validating SMB2 PDU body size

smb2_validate_credit_charge() accesses fields in the SMB2 PDU body,
but until smb2_calc_size() is called the PDU has not yet been verified
to be large enough to access the PDU dynamic part length field.

Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Ralph Boehme <slow@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>

authored by Ralph Boehme and committed by Steve French 7a334887 2ea086e3

+10 -9
+10 -9
fs/ksmbd/smb2misc.c
··· 400 } 401 } 402 403 - if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) && 404 - smb2_validate_credit_charge(work->conn, hdr)) { 405 - work->conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); 406 - return 1; 407 - } 408 - 409 if (smb2_calc_size(hdr, &clc_len)) 410 return 1; 411 412 if (len != clc_len) { 413 /* client can return one byte more due to implied bcc[0] */ 414 if (clc_len == len + 1) 415 - return 0; 416 417 /* 418 * Some windows servers (win2016) will pad also the final 419 * PDU in a compound to 8 bytes. 420 */ 421 if (ALIGN(clc_len, 8) == len) 422 - return 0; 423 424 /* 425 * windows client also pad up to 8 bytes when compounding. ··· 426 "cli req padded more than expected. Length %d not %d for cmd:%d mid:%llu\n", 427 len, clc_len, command, 428 le64_to_cpu(hdr->MessageId)); 429 - return 0; 430 } 431 432 ksmbd_debug(SMB, ··· 434 len, clc_len, command, 435 le64_to_cpu(hdr->MessageId)); 436 437 return 1; 438 } 439
··· 400 } 401 } 402 403 if (smb2_calc_size(hdr, &clc_len)) 404 return 1; 405 406 if (len != clc_len) { 407 /* client can return one byte more due to implied bcc[0] */ 408 if (clc_len == len + 1) 409 + goto validate_credit; 410 411 /* 412 * Some windows servers (win2016) will pad also the final 413 * PDU in a compound to 8 bytes. 414 */ 415 if (ALIGN(clc_len, 8) == len) 416 + goto validate_credit; 417 418 /* 419 * windows client also pad up to 8 bytes when compounding. ··· 432 "cli req padded more than expected. Length %d not %d for cmd:%d mid:%llu\n", 433 len, clc_len, command, 434 le64_to_cpu(hdr->MessageId)); 435 + goto validate_credit; 436 } 437 438 ksmbd_debug(SMB, ··· 440 len, clc_len, command, 441 le64_to_cpu(hdr->MessageId)); 442 443 + return 1; 444 + } 445 + 446 + validate_credit: 447 + if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) && 448 + smb2_validate_credit_charge(work->conn, hdr)) { 449 + work->conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); 450 return 1; 451 } 452