Skip to content

Commit

Permalink
ksmbd: disable SMB2_GLOBAL_CAP_ENCRYPTION for SMB 3.1.1
Browse files Browse the repository at this point in the history
According to the official Microsoft MS-SMB2 document section 3.3.5.4, this
flag should be used only for 3.0 and 3.0.2 dialects. Setting it for 3.1.1
is a violation of the specification.

This causes my Windows 10 client to detect an anomaly in the negotiation,
and disable encryption entirely despite being explicitly enabled in ksmbd,
causing all data transfers to go in plain text.

Fixes: e2f3448 ("cifsd: add server-side procedures for SMB3")
Cc: stable@vger.kernel.org # v5.15
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Marcos Del Sol Vives <marcos@orca.pet>
Signed-off-by: Steve French <stfrench@microsoft.com>
  • Loading branch information
Marcos Del Sol Vives authored and Steve French committed Dec 18, 2021
1 parent f2e78af commit 83912d6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
3 changes: 0 additions & 3 deletions fs/ksmbd/smb2ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,6 @@ int init_smb3_11_server(struct ksmbd_conn *conn)
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;

if (conn->cipher_type)
conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;

if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;

Expand Down
25 changes: 21 additions & 4 deletions fs/ksmbd/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,25 @@ static void decode_encrypt_ctxt(struct ksmbd_conn *conn,
}
}

/**
* smb3_encryption_negotiated() - checks if server and client agreed on enabling encryption
* @conn: smb connection
*
* Return: true if connection should be encrypted, else false
*/
static bool smb3_encryption_negotiated(struct ksmbd_conn *conn)
{
if (!conn->ops->generate_encryptionkey)
return false;

/*
* SMB 3.0 and 3.0.2 dialects use the SMB2_GLOBAL_CAP_ENCRYPTION flag.
* SMB 3.1.1 uses the cipher_type field.
*/
return (conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) ||
conn->cipher_type;
}

static void decode_compress_ctxt(struct ksmbd_conn *conn,
struct smb2_compression_capabilities_context *pneg_ctxt)
{
Expand Down Expand Up @@ -1469,8 +1488,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
(req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
sess->sign = true;

if (conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION &&
conn->ops->generate_encryptionkey &&
if (smb3_encryption_negotiated(conn) &&
!(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
rc = conn->ops->generate_encryptionkey(sess);
if (rc) {
Expand Down Expand Up @@ -1559,8 +1577,7 @@ static int krb5_authenticate(struct ksmbd_work *work)
(req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
sess->sign = true;

if ((conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) &&
conn->ops->generate_encryptionkey) {
if (smb3_encryption_negotiated(conn)) {
retval = conn->ops->generate_encryptionkey(sess);
if (retval) {
ksmbd_debug(SMB,
Expand Down

0 comments on commit 83912d6

Please sign in to comment.