提交 8de8c460 编写于 作者: P Paulo Alcantara 提交者: Steve French

cifs: Fix validation of signed data in smb2

Fixes: c713c877 ("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: NPaulo Alcantara <palcantara@suse.de>
Reviewed-by: NRonnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: NSteve French <stfrench@microsoft.com>
上级 27c32b49
...@@ -173,6 +173,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) ...@@ -173,6 +173,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
struct kvec *iov = rqst->rq_iov; struct kvec *iov = rqst->rq_iov;
struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base; struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
struct cifs_ses *ses; struct cifs_ses *ses;
struct shash_desc *shash = &server->secmech.sdeschmacsha256->shash;
struct smb_rqst drqst;
ses = smb2_find_smb_ses(server, shdr->SessionId); ses = smb2_find_smb_ses(server, shdr->SessionId);
if (!ses) { if (!ses) {
...@@ -190,21 +192,39 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) ...@@ -190,21 +192,39 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
} }
rc = crypto_shash_setkey(server->secmech.hmacsha256, rc = crypto_shash_setkey(server->secmech.hmacsha256,
ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE); ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: Could not update with response\n", __func__); cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
return rc; return rc;
} }
rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash); rc = crypto_shash_init(shash);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: Could not init sha256", __func__); cifs_dbg(VFS, "%s: Could not init sha256", __func__);
return rc; return rc;
} }
rc = __cifs_calc_signature(rqst, server, sigptr, /*
&server->secmech.sdeschmacsha256->shash); * For SMB2+, __cifs_calc_signature() expects to sign only the actual
* data, that is, iov[0] should not contain a rfc1002 length.
*
* Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
* __cifs_calc_signature().
*/
drqst = *rqst;
if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
rc = crypto_shash_update(shash, iov[0].iov_base,
iov[0].iov_len);
if (rc) {
cifs_dbg(VFS, "%s: Could not update with payload\n",
__func__);
return rc;
}
drqst.rq_iov++;
drqst.rq_nvec--;
}
rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
if (!rc) if (!rc)
memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE); memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册