Re: [PATCH 4.13 28/43] SMB3: Validate negotiate request must always be signed

From: Srivatsa S. Bhat
Date: Thu Mar 22 2018 - 01:12:29 EST


On 3/21/18 7:02 PM, Steve French wrote:
> Found a patch which solves the dependency issue. In my testing (on
> 4.9, with Windows 2016, and also to Samba) as Pavel suggested this
> appears to fix the problem, but I will let Srivatsa confirm that it
> also fixes it for him. The two attached patches for 4.9 should work.
>

Indeed, those two patches fix the problem for me on 4.9. Thanks a lot
Steve, Pavel and Aurelien for all your efforts in fixing this!

I was also interested in getting this fixed on 4.4, so I modified the
patches to apply on 4.4.88 and verified that they fix the mount
failure. I have attached my patches for 4.4 with this mail.

Steve, Pavel, could you kindly double-check the second patch for 4.4,
especially around the keygen_exit error path?

Thank you very much!

Regards,
Srivatsa
VMware Photon OS
From a01a7dfb60e2d5421a487a7b81fd8a1bf72d96d4 Mon Sep 17 00:00:00 2001
From: Steve French <smfrench@xxxxxxxxx>
Date: Sun, 11 Mar 2018 20:00:27 -0700
Subject: [PATCH 1/2] SMB3: Validate negotiate request must always be signed

commit 4587eee04e2ac7ac3ac9fa2bc164fb6e548f99cd upstream.

According to MS-SMB2 3.2.55 validate_negotiate request must
always be signed. Some Windows can fail the request if you send it unsigned

See kernel bugzilla bug 197311

[ Fixed up for kernel version 4.4 ]

CC: Stable <stable@xxxxxxxxxxxxxxx>
Acked-by: Ronnie Sahlberg <lsahlber.redhat.com>
Signed-off-by: Steve French <smfrench@xxxxxxxxx>
Signed-off-by: Srivatsa S. Bhat <srivatsa@xxxxxxxxxxxxx>
---
fs/cifs/smb2pdu.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 84614a5..6dae5b8 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1558,6 +1558,9 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
} else
iov[0].iov_len = get_rfc1002_length(req) + 4;

+ /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
+ if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
+ req->hdr.Flags |= SMB2_FLAGS_SIGNED;

rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
--
2.7.4

From d0178d8f096b29a88914787274bdc8ee8334ab07 Mon Sep 17 00:00:00 2001
From: Pavel Shilovsky <pshilov@xxxxxxxxxxxxx>
Date: Mon, 7 Nov 2016 18:20:50 -0800
Subject: [PATCH 2/2] CIFS: Enable encryption during session setup phase

commit cabfb3680f78981d26c078a26e5c748531257ebb upstream.

In order to allow encryption on SMB connection we need to exchange
a session key and generate encryption and decryption keys.

[ Fixed up for kernel version 4.4 ]

Signed-off-by: Pavel Shilovsky <pshilov@xxxxxxxxxxxxx>
Signed-off-by: Srivatsa S. Bhat <srivatsa@xxxxxxxxxxxxx>
---
fs/cifs/sess.c | 22 ++++++++++------------
fs/cifs/smb2pdu.c | 8 +-------
2 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index e88ffe1..a035d1a 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -344,13 +344,12 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
/* BB is NTLMV2 session security format easier to use here? */
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
- if (ses->server->sign) {
+ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
+ NTLMSSP_NEGOTIATE_SEAL;
+ if (ses->server->sign)
flags |= NTLMSSP_NEGOTIATE_SIGN;
- if (!ses->server->session_estab ||
- ses->ntlmssp->sesskey_per_smbsess)
- flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
- }
+ if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
+ flags |= NTLMSSP_NEGOTIATE_KEY_XCH;

sec_blob->NegotiateFlags = cpu_to_le32(flags);

@@ -407,13 +406,12 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
flags = NTLMSSP_NEGOTIATE_56 |
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
- if (ses->server->sign) {
+ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
+ NTLMSSP_NEGOTIATE_SEAL;
+ if (ses->server->sign)
flags |= NTLMSSP_NEGOTIATE_SIGN;
- if (!ses->server->session_estab ||
- ses->ntlmssp->sesskey_per_smbsess)
- flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
- }
+ if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
+ flags |= NTLMSSP_NEGOTIATE_KEY_XCH;

tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
sec_blob->NegotiateFlags = cpu_to_le32(flags);
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 6dae5b8..33b1bc2 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -832,10 +832,8 @@ ssetup_exit:

if (!rc) {
mutex_lock(&server->srv_mutex);
- if (server->sign && server->ops->generate_signingkey) {
+ if (server->ops->generate_signingkey) {
rc = server->ops->generate_signingkey(ses);
- kfree(ses->auth_key.response);
- ses->auth_key.response = NULL;
if (rc) {
cifs_dbg(FYI,
"SMB3 session key generation failed\n");
@@ -857,10 +855,6 @@ ssetup_exit:
}

keygen_exit:
- if (!server->sign) {
- kfree(ses->auth_key.response);
- ses->auth_key.response = NULL;
- }
if (spnego_key) {
key_invalidate(spnego_key);
key_put(spnego_key);
--
2.7.4