Skip to content

Commit 27c32b4

Browse files
Paulo AlcantaraSteve French
authored andcommitted
cifs: Fix validation of signed data in smb3+
Fixes: c713c87 ("cifs: push rfc1002 generation down the stack") We failed to validate signed data returned by the server because __cifs_calc_signature() now expects to sign the actual data in iov but we were also passing down the rfc1002 length. Fix smb3_calc_signature() to calculate signature of rfc1002 length prior to passing only the actual data iov[1-N] to __cifs_calc_signature(). In addition, there are a few cases where no rfc1002 length is passed so we make sure there's one (iov_len == 4). Signed-off-by: Paulo Alcantara <[email protected]> Reviewed-by: Ronnie Sahlberg <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 696e420 commit 27c32b4

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

fs/cifs/smb2transport.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -408,12 +408,14 @@ generate_smb311signingkey(struct cifs_ses *ses)
408408
int
409409
smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
410410
{
411-
int rc = 0;
411+
int rc;
412412
unsigned char smb3_signature[SMB2_CMACAES_SIZE];
413413
unsigned char *sigptr = smb3_signature;
414414
struct kvec *iov = rqst->rq_iov;
415415
struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
416416
struct cifs_ses *ses;
417+
struct shash_desc *shash = &server->secmech.sdesccmacaes->shash;
418+
struct smb_rqst drqst;
417419

418420
ses = smb2_find_smb_ses(server, shdr->SessionId);
419421
if (!ses) {
@@ -425,8 +427,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
425427
memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
426428

427429
rc = crypto_shash_setkey(server->secmech.cmacaes,
428-
ses->smb3signingkey, SMB2_CMACAES_SIZE);
429-
430+
ses->smb3signingkey, SMB2_CMACAES_SIZE);
430431
if (rc) {
431432
cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
432433
return rc;
@@ -437,15 +438,33 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
437438
* so unlike smb2 case we do not have to check here if secmech are
438439
* initialized
439440
*/
440-
rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash);
441+
rc = crypto_shash_init(shash);
441442
if (rc) {
442443
cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
443444
return rc;
444445
}
445446

446-
rc = __cifs_calc_signature(rqst, server, sigptr,
447-
&server->secmech.sdesccmacaes->shash);
447+
/*
448+
* For SMB2+, __cifs_calc_signature() expects to sign only the actual
449+
* data, that is, iov[0] should not contain a rfc1002 length.
450+
*
451+
* Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
452+
* __cifs_calc_signature().
453+
*/
454+
drqst = *rqst;
455+
if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
456+
rc = crypto_shash_update(shash, iov[0].iov_base,
457+
iov[0].iov_len);
458+
if (rc) {
459+
cifs_dbg(VFS, "%s: Could not update with payload\n",
460+
__func__);
461+
return rc;
462+
}
463+
drqst.rq_iov++;
464+
drqst.rq_nvec--;
465+
}
448466

467+
rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
449468
if (!rc)
450469
memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
451470

0 commit comments

Comments
 (0)