From e970e4b4cc7d7220c7b43f1f1c84625a8ae271ce Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Apr 17 2023 18:13:36 +0000 Subject: cifs: fix negotiate context parsing (bsc#1210301). --- diff --git a/patches.suse/cifs-fix-negotiate-context-parsing.patch b/patches.suse/cifs-fix-negotiate-context-parsing.patch new file mode 100644 index 0000000..2f56bcc --- /dev/null +++ b/patches.suse/cifs-fix-negotiate-context-parsing.patch @@ -0,0 +1,112 @@ +From fadffe168ca527bd61b9db6d78e5d65441fe447c Mon Sep 17 00:00:00 2001 +From: David Disseldorp +Date: Fri, 7 Apr 2023 00:34:11 +0200 +Subject: [PATCH] cifs: fix negotiate context parsing +Git-commit: 5105a7ffce19160e7062aee67fb6b3b8a1b56d78 +Patch-mainline: v6.3-rc7 +References: bsc#1210301 + +smb311_decode_neg_context() doesn't properly check against SMB packet +boundaries prior to accessing individual negotiate context entries. This +is due to the length check omitting the eight byte smb2_neg_context +header, as well as incorrect decrementing of len_of_ctxts. + +Fixes: 5100d8a3fe03 ("SMB311: Improve checking of negotiate security contexts") +Reported-by: Volker Lendecke +Reviewed-by: Paulo Alcantara (SUSE) +Signed-off-by: David Disseldorp +Signed-off-by: Steve French +[ddiss: rebase against 4.12 without 53d31a3ffd6017 and d7173623bf0b15] + +--- + fs/cifs/smb2pdu.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 7adf891aa683b..c4e058013405a 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -603,11 +603,15 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, + *total_len += sizeof(struct smb2_posix_neg_context); + } + ++/* If invalid preauth context warn but use what we requested, SHA-512 */ + static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt) + { + unsigned int len = le16_to_cpu(ctxt->DataLength); + +- /* If invalid preauth context warn but use what we requested, SHA-512 */ ++ /* ++ * Caller checked that DataLength remains within SMB boundary. We still ++ * need to confirm that one HashAlgorithms member is accounted for. ++ */ + if (len < MIN_PREAUTH_CTXT_DATA_LEN) { + printk_once(KERN_WARNING "server sent bad preauth context\n"); + return; +@@ -623,7 +627,11 @@ static void decode_compress_ctx(struct TCP_Server_Info *server, + { + unsigned int len = le16_to_cpu(ctxt->DataLength); + +- /* sizeof compress context is a one element compression capbility struct */ ++ /* ++ * Caller checked that DataLength remains within SMB boundary. We still ++ * need to confirm that one CompressionAlgorithms member is accounted ++ * for. ++ */ + if (len < 10) { + printk_once(KERN_WARNING "server sent bad compression cntxt\n"); + return; +@@ -645,6 +653,11 @@ static int decode_encrypt_ctx(struct TCP_Server_Info *server, + unsigned int len = le16_to_cpu(ctxt->DataLength); + + cifs_dbg(FYI, "decode SMB3.11 encryption neg context of len %d\n", len); ++ /* ++ * Caller checked that DataLength remains within SMB boundary. We still ++ * need to confirm that one Cipher flexible array member is accounted ++ * for. ++ */ + if (len < MIN_ENCRYPT_CTXT_DATA_LEN) { + printk_once(KERN_WARNING "server sent bad crypto ctxt len\n"); + return -EINVAL; +@@ -686,14 +699,19 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, + for (i = 0; i < ctxt_cnt; i++) { + int clen; + /* check that offset is not beyond end of SMB */ +- if (len_of_ctxts == 0) +- break; +- + if (len_of_ctxts < sizeof(struct smb2_neg_context)) + break; + + pctx = (struct smb2_neg_context *)(offset + (char *)rsp); +- clen = le16_to_cpu(pctx->DataLength); ++ clen = sizeof(struct smb2_neg_context) ++ + le16_to_cpu(pctx->DataLength); ++ /* ++ * 2.2.4 SMB2 NEGOTIATE Response ++ * Subsequent negotiate contexts MUST appear at the first 8-byte ++ * aligned offset following the previous negotiate context. ++ */ ++ if (i + 1 != ctxt_cnt) ++ clen = ALIGN(clen, 8); + if (clen > len_of_ctxts) + break; + +@@ -711,12 +729,10 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, + else + cifs_dbg(VFS, "unknown negcontext of type %d ignored\n", + le16_to_cpu(pctx->ContextType)); +- + if (rc) + break; +- /* offsets must be 8 byte aligned */ +- clen = (clen + 7) & ~0x7; +- offset += clen + sizeof(struct smb2_neg_context); ++ ++ offset += clen; + len_of_ctxts -= clen; + } + return rc; +-- +2.40.0 + diff --git a/series.conf b/series.conf index fa3034c..142c726 100644 --- a/series.conf +++ b/series.conf @@ -26850,6 +26850,7 @@ patches.suse/nfc-st-nci-Fix-use-after-free-bug-in-ndlc_remove-due.patch patches.suse/Bluetooth-btsdio-fix-use-after-free-bug-in-btsdio_re.patch patches.suse/power-supply-da9150-Fix-use-after-free-bug-in-da9150.patch + patches.suse/cifs-fix-negotiate-context-parsing.patch # dhowells/linux-fs keys-uefi patches.suse/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch