Skip to content

Commit 8de8c46

Browse files
Paulo AlcantaraSteve French
authored andcommitted
cifs: Fix validation of signed data in smb2
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 27c32b4 commit 8de8c46

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

fs/cifs/smb2transport.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
173173
struct kvec *iov = rqst->rq_iov;
174174
struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
175175
struct cifs_ses *ses;
176+
struct shash_desc *shash = &server->secmech.sdeschmacsha256->shash;
177+
struct smb_rqst drqst;
176178

177179
ses = smb2_find_smb_ses(server, shdr->SessionId);
178180
if (!ses) {
@@ -190,21 +192,39 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
190192
}
191193

192194
rc = crypto_shash_setkey(server->secmech.hmacsha256,
193-
ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
195+
ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
194196
if (rc) {
195197
cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
196198
return rc;
197199
}
198200

199-
rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
201+
rc = crypto_shash_init(shash);
200202
if (rc) {
201203
cifs_dbg(VFS, "%s: Could not init sha256", __func__);
202204
return rc;
203205
}
204206

205-
rc = __cifs_calc_signature(rqst, server, sigptr,
206-
&server->secmech.sdeschmacsha256->shash);
207+
/*
208+
* For SMB2+, __cifs_calc_signature() expects to sign only the actual
209+
* data, that is, iov[0] should not contain a rfc1002 length.
210+
*
211+
* Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
212+
* __cifs_calc_signature().
213+
*/
214+
drqst = *rqst;
215+
if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
216+
rc = crypto_shash_update(shash, iov[0].iov_base,
217+
iov[0].iov_len);
218+
if (rc) {
219+
cifs_dbg(VFS, "%s: Could not update with payload\n",
220+
__func__);
221+
return rc;
222+
}
223+
drqst.rq_iov++;
224+
drqst.rq_nvec--;
225+
}
207226

227+
rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
208228
if (!rc)
209229
memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
210230

0 commit comments

Comments
 (0)