Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

ksmbd: avoid out of bounds access in decode_preauth_ctxt()

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>

authored by

David Disseldorp and committed by
Steve French
e7067a44 09a9639e

+14 -9
+14 -9
fs/ksmbd/smb2pdu.c
··· 876 876 } 877 877 878 878 static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn, 879 - struct smb2_preauth_neg_context *pneg_ctxt) 879 + struct smb2_preauth_neg_context *pneg_ctxt, 880 + int len_of_ctxts) 880 881 { 881 - __le32 err = STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP; 882 + /* 883 + * sizeof(smb2_preauth_neg_context) assumes SMB311_SALT_SIZE Salt, 884 + * which may not be present. Only check for used HashAlgorithms[1]. 885 + */ 886 + if (len_of_ctxts < MIN_PREAUTH_CTXT_DATA_LEN) 887 + return STATUS_INVALID_PARAMETER; 882 888 883 - if (pneg_ctxt->HashAlgorithms == SMB2_PREAUTH_INTEGRITY_SHA512) { 884 - conn->preauth_info->Preauth_HashId = 885 - SMB2_PREAUTH_INTEGRITY_SHA512; 886 - err = STATUS_SUCCESS; 887 - } 889 + if (pneg_ctxt->HashAlgorithms != SMB2_PREAUTH_INTEGRITY_SHA512) 890 + return STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP; 888 891 889 - return err; 892 + conn->preauth_info->Preauth_HashId = SMB2_PREAUTH_INTEGRITY_SHA512; 893 + return STATUS_SUCCESS; 890 894 } 891 895 892 896 static void decode_encrypt_ctxt(struct ksmbd_conn *conn, ··· 1018 1014 break; 1019 1015 1020 1016 status = decode_preauth_ctxt(conn, 1021 - (struct smb2_preauth_neg_context *)pctx); 1017 + (struct smb2_preauth_neg_context *)pctx, 1018 + len_of_ctxts); 1022 1019 if (status != STATUS_SUCCESS) 1023 1020 break; 1024 1021 } else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES) {