]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
do_all_the_voodoo_here: fix memory leak of fromemails and posteraddr
authorMichael S. Tsirkin <mst@redhat.com>
Thu, 8 Jan 2026 12:39:22 +0000 (07:39 -0500)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Fri, 13 Feb 2026 13:24:07 +0000 (14:24 +0100)
The function has two related memory leaks:

1. fromemails strlist is populated by find_email_adr() but never freed.
   The list goes out of scope when the if block ends, but the allocated
   strings remain unreachable.

2. posteraddr is set to tll_front(fromemails), which is just a pointer
   to the first element. This creates a dependency on the leaked list.

Fix:
- Copy the string using xstrdup() so posteraddr owns its memory
- Add tll_length() check before accessing tll_front() to avoid NULL pointer dereference (can occur with empty or malformed From header)
- Free the fromemails list immediately after extracting the value
- Free posteraddr on all return paths (error and success)

Fixes: 59181abe ("customheaders allow substitution on variable $posteraddr$")
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
src/do_all_the_voodoo_here.c

index 6a80a48d229409d7fa9b56cdd4de1728879d12e3..4f7f535a46043c25bd078ab8a15f96b25b49926c 100644 (file)
@@ -91,8 +91,10 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
                strlist fromemails = tll_init();
                if ( readhdrs[0].valuecount == 1 ) {
                        find_email_adr(readhdrs[0].values[0], &fromemails);
-                       posteraddr = tll_front(fromemails);
+                       if (tll_length(fromemails) > 0)
+                               posteraddr = xstrdup(tll_front(fromemails));
                }
+               tll_free_and_free(fromemails, free);
        }
        /* scan all headers from allhdrs , and do the real things */
        tll_foreach(*allhdrs, a_header ) {
@@ -110,6 +112,7 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
                                        log_error(LOG_ARGS, "Could not "
                                                "add extra headers");
                                        tll_free_and_free(allunfoldeds, free);
+                                       free(posteraddr);
                                        return -1;
                                }
                                fsync(outfd);
@@ -150,6 +153,7 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
                                log_error(LOG_ARGS, "Could not "
                                        "add extra headers");
                                tll_free_and_free(allunfoldeds, free);
+                               free(posteraddr);
                                return -1;
                        }
                        fsync(outfd);
@@ -164,6 +168,7 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
        if(dprintf(outfd, "\n") < 0) {
                tll_free_and_free(allunfoldeds, free);
                log_error(LOG_ARGS, "Error writing hdrs.");
+               free(posteraddr);
                return -1;
        }
        
@@ -173,6 +178,7 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
        /* Just print the rest of the mail */
        if(dumpfd2fd(infd, outfd) < 0) {
                log_error(LOG_ARGS, "Error when dumping rest of mail");
+               free(posteraddr);
                return -1;
        }
        fclose(f);
@@ -181,10 +187,12 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
        if(footfd >= 0)
                if(dumpfd2fd(footfd, outfd) < 0) {
                        log_error(LOG_ARGS, "Error when adding footer");
+                       free(posteraddr);
                        return -1;
                }
 
        fsync(outfd);
 
+       free(posteraddr);
        return 0;
 }