Here is the original message sent directly to me.

----- Forwarded message from Acts1631 <[email protected]> -----

Date: Wed, 10 Jun 2026 22:59:10 +0000
From: Acts1631 <[email protected]>
To: "[email protected]" <[email protected]>
Subject: mutt null pointer dereference
X-Spam-score: 0.0
X-Delivered-to: [email protected]
Message-ID: 
<xbJ184rpOMrlkTR6NF-wYqIQ4sHTfSq8jPm1XR0KQkpxdudyI1XEJYvxlqIk6V7JlZFydG72oxua_36FcFbi-lje6JDcnUTWC9VY9ey5bCA=@proton.me>

Hi mr McCarthy. I was testing Mutt with some code scanning and found
the following crash. I hope you'll have a moment to look at it.

Opening the attachment view for an email containing 51 nested
message/rfc822 parts crashes Mutt with a null pointer dereference
in mutt_generate_recvattach_list() at recvattach.c:1306.

The crash is reachable from a local mailbox message. No external helper,
mailcap entry, or decryption setup is required.

Mutt was built with:

./configure --disable-doc --disable-nls --disable-imap --disable-pop \
  --disable-smtp --disable-autocrypt --without-ssl --without-sasl \
  CFLAGS='-g -O1 -fsanitize=address,undefined -fno-omit-frame-pointer' \
  LDFLAGS='-fsanitize=address,undefined'
ASAN_OPTIONS=detect_leaks=0 make -j$(nproc)

Attached:
poc-nested-message-rfc822.eml.gz - minimized 4624-byte mbox-style reproducer
fix-null-message-rfc822-hdr.patch - proposed fix

With UBSAN_OPTIONS=halt_on_error=0, UBSan first reports a null member access,
then ASan reports a null-address SEGV:

recvattach.c:1306:32: runtime error: member access within null pointer of type 
'struct header'
ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000
    #0 ... in mutt_generate_recvattach_list /tmp/mutt/recvattach.c:1306
    #1 ... in mutt_generate_recvattach_list /tmp/mutt/recvattach.c:1305
    ...
    #52 ... in mutt_view_attachments /tmp/mutt/recvattach.c:1415
    #53 ... in mutt_pager /tmp/mutt/pager.c:3106
    #54 ... in mutt_display_message /tmp/mutt/commands.c:331
SUMMARY: AddressSanitizer: SEGV /tmp/mutt/recvattach.c:1306 in 
mutt_generate_recvattach_list

_parse_part() stops recursive MIME parsing when recurse_level reaches
MUTT_MIME_MAX_DEPTH:

if (recurse_level >= MUTT_MIME_MAX_DEPTH)
  return;

For a message/rfc822 part at that limit, parsing returns before
_parse_messageRFC822() initializes the nested BODY's hdr field.

Later, attachment view generation assumes every message/rfc822
body has a non-null m->hdr:

mutt_generate_recvattach_list(actx, m->hdr, m->parts, fp, m->type, level + 1, 
decrypted);
hdr->security |= m->hdr->security;

The recursive call safely receives a null parts` pointer and returns,
but thevsubsequent `m->hdr->security` dereference crashes.

The attached patch treats a missing nested header as an unparsed message body.
It still lists the part itself, but does not recurse into children or propagate
security flags unless m->hdr exists. It also guards the parent hdr before
updating security flags.




----- End forwarded message -----

--
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA
diff --git a/recvattach.c b/recvattach.c
index 1ed30ed..6c5dcd4 100644
--- a/recvattach.c
+++ b/recvattach.c
@@ -1302,8 +1302,12 @@ decrypt_failed:
         mutt_generate_recvattach_list(actx, hdr, m->parts, fp, m->type, level + 1, decrypted);
       else if (mutt_is_message_type(m->type, m->subtype))
       {
-        mutt_generate_recvattach_list(actx, m->hdr, m->parts, fp, m->type, level + 1, decrypted);
-        hdr->security |= m->hdr->security;
+        if (m->hdr)
+        {
+          mutt_generate_recvattach_list(actx, m->hdr, m->parts, fp, m->type, level + 1, decrypted);
+          if (hdr)
+            hdr->security |= m->hdr->security;
+        }
       }
     }
   }

Attachment: poc-nested-message-rfc822.eml.gz
Description: application/gzip

Attachment: signature.asc
Description: PGP signature

Reply via email to