|
|
@@ -439,7 +439,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req)
|
|
|
build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt);
|
|
|
req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
|
|
|
req->NegotiateContextCount = cpu_to_le16(2);
|
|
|
- inc_rfc1001_len(req, 4 + sizeof(struct smb2_preauth_neg_context) + 2
|
|
|
+ inc_rfc1001_len(req, 4 + sizeof(struct smb2_preauth_neg_context)
|
|
|
+ sizeof(struct smb2_encryption_neg_context)); /* calculate hash */
|
|
|
}
|
|
|
#else
|
|
|
@@ -570,10 +570,11 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
|
|
|
/* ops set to 3.0 by default for default so update */
|
|
|
ses->server->ops = &smb21_operations;
|
|
|
}
|
|
|
- } else if (rsp->DialectRevision != ses->server->vals->protocol_id) {
|
|
|
+ } else if (le16_to_cpu(rsp->DialectRevision) !=
|
|
|
+ ses->server->vals->protocol_id) {
|
|
|
/* if requested single dialect ensure returned dialect matched */
|
|
|
cifs_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n",
|
|
|
- cpu_to_le16(rsp->DialectRevision));
|
|
|
+ le16_to_cpu(rsp->DialectRevision));
|
|
|
return -EIO;
|
|
|
}
|
|
|
|
|
|
@@ -655,15 +656,22 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
|
|
|
|
|
|
/*
|
|
|
* validation ioctl must be signed, so no point sending this if we
|
|
|
- * can not sign it. We could eventually change this to selectively
|
|
|
+ * can not sign it (ie are not known user). Even if signing is not
|
|
|
+ * required (enabled but not negotiated), in those cases we selectively
|
|
|
* sign just this, the first and only signed request on a connection.
|
|
|
- * This is good enough for now since a user who wants better security
|
|
|
- * would also enable signing on the mount. Having validation of
|
|
|
- * negotiate info for signed connections helps reduce attack vectors
|
|
|
+ * Having validation of negotiate info helps reduce attack vectors.
|
|
|
*/
|
|
|
- if (tcon->ses->server->sign == false)
|
|
|
+ if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST)
|
|
|
return 0; /* validation requires signing */
|
|
|
|
|
|
+ if (tcon->ses->user_name == NULL) {
|
|
|
+ cifs_dbg(FYI, "Can't validate negotiate: null user mount\n");
|
|
|
+ return 0; /* validation requires signing */
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL)
|
|
|
+ cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n");
|
|
|
+
|
|
|
vneg_inbuf.Capabilities =
|
|
|
cpu_to_le32(tcon->ses->server->vals->req_capabilities);
|
|
|
memcpy(vneg_inbuf.Guid, tcon->ses->server->client_guid,
|
|
|
@@ -1175,6 +1183,8 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
|
|
|
while (sess_data->func)
|
|
|
sess_data->func(sess_data);
|
|
|
|
|
|
+ if ((ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST) && (ses->sign))
|
|
|
+ cifs_dbg(VFS, "signing requested but authenticated as guest\n");
|
|
|
rc = sess_data->result;
|
|
|
out:
|
|
|
kfree(sess_data);
|