Hi Kevin,

> Date: 2026-09-22 11:12:12+0800
> From: "Kevin J. McCarthy" <[email protected]>
>
> The leak was triggered in mutt_make_message_attach() with
> $mime_forward set and $allow_8bit unset, on an attachment with 8-bit
> characters.  However, it probably occurred in other situations too.
> 
> mutt_make_message_attach() indirectly chains down to
> mutt_message_to_7bit(), which calls the originator of the leak:
> _parse_messageRFC822().  That function overwrites parent->hdr with a
> newly allocated header.
> 
> At first I tried to "fix" the problem in that function, but it turns
> out to be difficult to do given the wide variety of callers and
> state of the data structures.  Some callers pass a header with
> content set, and other times it's not set.
> 
> After further research I discovered other callers of the
> mutt_parse_(part/multipart/messageRFC822) set of functions take care
> to save a top level header and restore it.  (Which also made solving
> the leak inside _parse_messageRFC822() difficult.)
> 
> After more research I decided the right place to fix was
> mutt_message_to_7bit(): the caller of mutt_parse_messageRFC822() in
> this case.
> 
> Since this is a generic function used in different circumstances, I
> made no assumptions about whether a->hdr exists.  If so, I save and
> restore it.
> 
> The original function frees the a->hdr->content (or a->parts), so I
> kept the same logic.
> ---
>  sendlib.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/sendlib.c b/sendlib.c
> index dbd3eabe..db73eaf1 100644
> --- a/sendlib.c
> +++ b/sendlib.c
> @@ -1108,6 +1108,7 @@ void mutt_message_to_7bit(BODY *a, FILE *fp)
>    FILE *fpin = NULL;
>    FILE *fpout = NULL;
>    struct stat sb;
> +  HEADER *saved_hdr = NULL;
>  
>    if (!a->filename && fp)
>      fpin = fp;
> @@ -1138,6 +1139,10 @@ void mutt_message_to_7bit(BODY *a, FILE *fp)
>    }
>  
>    fseeko(fpin, a->offset, SEEK_SET);
> +  /* Note: mutt_parse_messageRFC822() overwrites a->hdr, so it needs to
> +   * saved and restored below.

needs to _be_ saved.  :)

> +   */
> +  saved_hdr = a->hdr;
>    a->parts = mutt_parse_messageRFC822(fpin, a);
>  
>    transform_to_7bit(a->parts, fpin);
> @@ -1167,8 +1172,14 @@ void mutt_message_to_7bit(BODY *a, FILE *fp)
>      goto cleanup;
>    }
>    a->length = sb.st_size;
> -  mutt_free_body(&a->parts);
> -  a->hdr->content = NULL;
> +
> +  if (saved_hdr)
> +  {
> +    mutt_free_header(&a->hdr);
> +    a->hdr = saved_hdr;
> +  }
> +  mutt_free_body(&a->hdr->content);
> +  a->parts = NULL;


Have a lovely day!
Alex

>  
>  cleanup:
>    if (fpin && fpin != fp)
> -- 
> 2.55.0
> 

-- 
<https://www.alejandro-colomar.es>

Reply via email to