ksmbd: avoid out of bounds access in decode_preauth_ctxt()
authorDavid Disseldorp <ddiss@suse.de>
Thu, 13 Apr 2023 14:49:57 +0000 (23:49 +0900)
committerSteve French <stfrench@microsoft.com>
Thu, 13 Apr 2023 19:17:32 +0000 (14:17 -0500)
Confirm that the accessed pneg_ctxt->HashAlgorithms address sits within
the SMB request boundary; deassemble_neg_contexts() only checks that the
eight byte smb2_neg_context header + (client controlled) DataLength are
within the packet boundary, which is insufficient.

Checking for sizeof(struct smb2_preauth_neg_context) is overkill given
that the type currently assumes SMB311_SALT_SIZE bytes of trailing Salt.

Signed-off-by: David Disseldorp <ddiss@suse.de>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/ksmbd/smb2pdu.c

index 8af939a181be588f932cdca6419a1ac36047a128..67b7e766a06bace88ef65d2afdb7dff514f9f364 100644 (file)
@@ -876,17 +876,21 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
 }
 
 static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn,
-                                 struct smb2_preauth_neg_context *pneg_ctxt)
+                                 struct smb2_preauth_neg_context *pneg_ctxt,
+                                 int len_of_ctxts)
 {
-       __le32 err = STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP;
+       /*
+        * sizeof(smb2_preauth_neg_context) assumes SMB311_SALT_SIZE Salt,
+        * which may not be present. Only check for used HashAlgorithms[1].
+        */
+       if (len_of_ctxts < MIN_PREAUTH_CTXT_DATA_LEN)
+               return STATUS_INVALID_PARAMETER;
 
-       if (pneg_ctxt->HashAlgorithms == SMB2_PREAUTH_INTEGRITY_SHA512) {
-               conn->preauth_info->Preauth_HashId =
-                       SMB2_PREAUTH_INTEGRITY_SHA512;
-               err = STATUS_SUCCESS;
-       }
+       if (pneg_ctxt->HashAlgorithms != SMB2_PREAUTH_INTEGRITY_SHA512)
+               return STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP;
 
-       return err;
+       conn->preauth_info->Preauth_HashId = SMB2_PREAUTH_INTEGRITY_SHA512;
+       return STATUS_SUCCESS;
 }
 
 static void decode_encrypt_ctxt(struct ksmbd_conn *conn,
@@ -1014,7 +1018,8 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
                                break;
 
                        status = decode_preauth_ctxt(conn,
-                                                    (struct smb2_preauth_neg_context *)pctx);
+                                                    (struct smb2_preauth_neg_context *)pctx,
+                                                    len_of_ctxts);
                        if (status != STATUS_SUCCESS)
                                break;
                } else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES) {