]> git.ipfire.org Git - thirdparty/mlmmj.git/log
thirdparty/mlmmj.git
2 days agomove the installation back to bin master
Baptiste Daroussin [Tue, 7 Apr 2026 20:03:46 +0000 (22:03 +0200)] 
move the installation back to bin

10 days agoresend_queue: do not leak a fd
Baptiste Daroussin [Mon, 30 Mar 2026 20:23:44 +0000 (22:23 +0200)] 
resend_queue: do not leak a fd

Instead reset temporarily the CLOEXEC flag and reset it later

10 days agoresend_queue: pass the archive directory via fd to mlmmj-send
Baptiste Daroussin [Mon, 30 Mar 2026 17:47:09 +0000 (19:47 +0200)] 
resend_queue: pass the archive directory via fd to mlmmj-send

duplicate the filedescriptor which archive_open explicitly mark as
O_CLOEXEC.

10 days agoarchive_open: remove ctrlfd argument
Baptiste Daroussin [Mon, 30 Mar 2026 17:42:35 +0000 (19:42 +0200)] 
archive_open: remove ctrlfd argument

It was intended to be used in the future but I change my mind on its
usage

10 days agoarchive_migrate: stop polluting the logs
Baptiste Daroussin [Mon, 30 Mar 2026 17:38:37 +0000 (19:38 +0200)] 
archive_migrate: stop polluting the logs

12 days agoPrepare release 2.0.0
Baptiste Daroussin [Sun, 29 Mar 2026 08:07:42 +0000 (10:07 +0200)] 
Prepare release 2.0.0

12 days agodocumentation: update with latest features
Baptiste Daroussin [Sun, 29 Mar 2026 08:01:58 +0000 (10:01 +0200)] 
documentation: update with latest features

12 days agoadd optional YYYY/MM archive partitioning via control/archivepartition
Baptiste Daroussin [Sun, 29 Mar 2026 06:21:04 +0000 (08:21 +0200)] 
add optional YYYY/MM archive partitioning via control/archivepartition

Large mailing lists accumulate thousands of files in a single archive/
directory, degrading filesystem performance. When control/archivepartition
exists, new archives are written to archive/YYYY/MM/N and mlmmj-maintd
automatically migrates existing flat archives based on file mtime.
Reading always tries flat layout first then falls back to scanning
subdirectories, so archives work regardless of layout.

12 days agogenerate RFC 2919/2369 List-* and Precedence headers natively
Baptiste Daroussin [Sun, 29 Mar 2026 05:55:55 +0000 (07:55 +0200)] 
generate RFC 2919/2369 List-* and Precedence headers natively

Mailing list messages without List-Id/Precedence headers cause vacation
autoreplies to trigger bounces leading to unsubscriptions, prevent mail
clients like Delta Chat from detecting list messages, and hurt
deliverability with major providers.

Generate List-Id, List-Post, List-Help, List-Subscribe, List-Unsubscribe,
and Precedence headers by default in do_all_the_voodoo_here(). List-Owner
is included only when control/owner exists. All headers can be disabled
via control/nolistheaders.

12 days agomlmmj-make-ml: use full email address for default owner
Baptiste Daroussin [Sun, 29 Mar 2026 02:52:18 +0000 (04:52 +0200)] 
mlmmj-make-ml: use full email address for default owner

The default owner "postmaster" lacks a domain part, causing
mlmmj-send to reject it with "No @ in address". Use the FQDN
already collected earlier in the script to build a proper
postmaster@FQDN default.

Closes #36

12 days agosend_mail: add X-Forwarded-To and X-Signed-Recipient headers
Baptiste Daroussin [Sun, 29 Mar 2026 02:38:25 +0000 (04:38 +0200)] 
send_mail: add X-Forwarded-To and X-Signed-Recipient headers

Add per-recipient headers to improve deliverability and support DARA
(draft ARC replay-resistant authentication):

- X-Forwarded-To: helps Gmail recognize legitimate forwarding
- X-Signed-Recipient: used in ARC signatures to prove the message
  was intended for a specific recipient

Both are enabled independently via control files (xforwardedto and dara).
Like addtohdr, these are incompatible with VERP since they require
per-recipient header injection.

Closes #34

12 days agosubscription: follow reply-to on susbcription
Baptiste Daroussin [Sat, 28 Mar 2026 21:55:02 +0000 (22:55 +0100)] 
subscription: follow reply-to on susbcription

12 days agotreat exit 127 ass error
Baptiste Daroussin [Sat, 28 Mar 2026 20:46:55 +0000 (21:46 +0100)] 
treat exit 127 ass error

posix_spawnp(3) may report exec() failures via the
child's exit status (127) instead of the return value

13 days agosyslog: only support system with syslog
Baptiste Daroussin [Fri, 27 Mar 2026 20:31:41 +0000 (21:31 +0100)] 
syslog: only support system with syslog

13 days agofix build
Baptiste Daroussin [Fri, 27 Mar 2026 20:15:01 +0000 (21:15 +0100)] 
fix build

13 days agoadd forgotten configure scrip
Baptiste Daroussin [Fri, 27 Mar 2026 20:11:31 +0000 (21:11 +0100)] 
add forgotten configure scrip

13 days agobuild system, convert to autosetup + custom mk framework
Baptiste Daroussin [Fri, 27 Mar 2026 12:54:19 +0000 (13:54 +0100)] 
build system, convert to autosetup + custom mk framework

13 days agoReplace foot's tllist.h with my own vec.h
Baptiste Daroussin [Fri, 27 Mar 2026 09:36:26 +0000 (10:36 +0100)] 
Replace foot's tllist.h with my own vec.h

I wrote for FreeBSD's pkg manager, no functionnal change expected

2 weeks agoplug memory leak
Baptiste Daroussin [Fri, 27 Mar 2026 07:44:47 +0000 (08:44 +0100)] 
plug memory leak

2 weeks agoUTF8: prevent out of bound reading
Baptiste Daroussin [Fri, 27 Mar 2026 07:40:26 +0000 (08:40 +0100)] 
UTF8: prevent out of bound reading

2 weeks agoplug memory leak and fix naming collision
Baptiste Daroussin [Fri, 27 Mar 2026 07:36:50 +0000 (08:36 +0100)] 
plug memory leak and fix naming collision

2 weeks agoFix fd leak
Baptiste Daroussin [Fri, 27 Mar 2026 07:17:11 +0000 (08:17 +0100)] 
Fix fd leak

2 weeks agofix TOCTOU by using O_NOFOLLOW which also simplifies code
Baptiste Daroussin [Fri, 27 Mar 2026 07:13:01 +0000 (08:13 +0100)] 
fix TOCTOU by using O_NOFOLLOW which also simplifies code

2 weeks agolimite line length to maximum 64k
Baptiste Daroussin [Fri, 27 Mar 2026 06:58:52 +0000 (07:58 +0100)] 
limite line length to maximum 64k

2 weeks agosetgid: test for failures
Baptiste Daroussin [Fri, 27 Mar 2026 06:51:25 +0000 (07:51 +0100)] 
setgid: test for failures

2 weeks agoadd forgotten setgid
Baptiste Daroussin [Fri, 27 Mar 2026 06:50:08 +0000 (07:50 +0100)] 
add forgotten setgid

2 weeks agoharden email validations
Baptiste Daroussin [Fri, 27 Mar 2026 06:34:13 +0000 (07:34 +0100)] 
harden email validations

2 weeks agomail: prevent header injections
Baptiste Daroussin [Fri, 27 Mar 2026 05:59:27 +0000 (06:59 +0100)] 
mail: prevent header injections

while theorically impossible as prefiltered by
MTA, I am aware of usages of mlmmj where inputs
are not through MTA, so better be safe than sorry

2 weeks agofix bad error message
Baptiste Daroussin [Fri, 27 Mar 2026 05:41:30 +0000 (06:41 +0100)] 
fix bad error message

2 weeks agoprevent a crash in case of broken connection
Baptiste Daroussin [Thu, 26 Mar 2026 21:32:59 +0000 (22:32 +0100)] 
prevent a crash in case of broken connection

2 weeks agoensure fd is initialized
Baptiste Daroussin [Thu, 26 Mar 2026 21:31:58 +0000 (22:31 +0100)] 
ensure fd is initialized

2 weeks agorandom: improve on platforms without arc4random
Baptiste Daroussin [Thu, 26 Mar 2026 21:30:27 +0000 (22:30 +0100)] 
random: improve on platforms without arc4random

2 weeks agocleanup: remove debug and fix EINTR logic
Baptiste Daroussin [Thu, 26 Mar 2026 21:27:23 +0000 (22:27 +0100)] 
cleanup: remove debug and fix EINTR logic

2 weeks agoexec_and_wait: multiple fixes
Baptiste Daroussin [Thu, 26 Mar 2026 20:34:03 +0000 (21:34 +0100)] 
exec_and_wait: multiple fixes

Fix EINTR loop
Return -1 if the process did not exit normally.

2 weeks agosubrelease: the order of the test was not deterministic
Baptiste Daroussin [Sat, 14 Mar 2026 22:48:35 +0000 (23:48 +0100)] 
subrelease: the order of the test was not deterministic

Replace with simple matches

3 weeks agosubrelease: fix tests RELEASE_1_8_0
Baptiste Daroussin [Sat, 14 Mar 2026 22:41:23 +0000 (23:41 +0100)] 
subrelease: fix tests

3 weeks agoRelease 1.8.0
Baptiste Daroussin [Sat, 14 Mar 2026 22:34:11 +0000 (23:34 +0100)] 
Release 1.8.0

3 weeks agoselfmoderate: backout better served by subrelease
Baptiste Daroussin [Sat, 14 Mar 2026 22:13:46 +0000 (23:13 +0100)] 
selfmoderate: backout better served by subrelease

3 weeks agosubrelease: finish the implementation started in 2012
Baptiste Daroussin [Sat, 14 Mar 2026 21:35:04 +0000 (22:35 +0100)] 
subrelease: finish the implementation started in 2012

4 weeks agoFactorize code a little
Baptiste Daroussin [Wed, 11 Mar 2026 10:10:37 +0000 (11:10 +0100)] 
Factorize code a little

4 weeks agoUse buffered I/O where possible
Baptiste Daroussin [Tue, 10 Mar 2026 21:50:38 +0000 (22:50 +0100)] 
Use buffered I/O where possible

4 weeks agovoodoo: use buffered I/O
Baptiste Daroussin [Tue, 10 Mar 2026 21:23:43 +0000 (22:23 +0100)] 
voodoo: use buffered I/O

4 weeks agogethdrline: use xstring
Baptiste Daroussin [Tue, 10 Mar 2026 21:17:15 +0000 (22:17 +0100)] 
gethdrline: use xstring

4 weeks agoremove useless fsync
Baptiste Daroussin [Tue, 10 Mar 2026 21:15:01 +0000 (22:15 +0100)] 
remove useless fsync

4 weeks agorewind_thread_list: imrpove
Baptiste Daroussin [Tue, 10 Mar 2026 21:07:32 +0000 (22:07 +0100)] 
rewind_thread_list: imrpove

Add test and rework the code:
- only read mail headers
- improvement memory management
- cleanup code
- make the code testable

4 weeks agoprocess_headers_fd: use buffered I/O
Baptiste Daroussin [Tue, 10 Mar 2026 20:55:56 +0000 (21:55 +0100)] 
process_headers_fd: use buffered I/O

4 weeks agofakesmtp: make it more robust
Baptiste Daroussin [Tue, 10 Mar 2026 13:01:37 +0000 (14:01 +0100)] 
fakesmtp: make it more robust

Instead of statically bind a port, dynamically bind one and report which
one was open.

Better handle killing the process when kyua receives sigterm or sigkill

4 weeks agovoodoo: add more unit tests
Baptiste Daroussin [Tue, 10 Mar 2026 09:56:10 +0000 (10:56 +0100)] 
voodoo: add more unit tests

4 weeks agoscan_headers: add unit tests
Baptiste Daroussin [Tue, 10 Mar 2026 09:44:58 +0000 (10:44 +0100)] 
scan_headers: add unit tests

4 weeks agosubstitute: add unit tests
Baptiste Daroussin [Tue, 10 Mar 2026 09:05:58 +0000 (10:05 +0100)] 
substitute: add unit tests

4 weeks agovoodoo: add tests for header manipulations
Baptiste Daroussin [Tue, 10 Mar 2026 08:59:20 +0000 (09:59 +0100)] 
voodoo: add tests for header manipulations

4 weeks agodumpfd2fd: cover with more tests
Baptiste Daroussin [Tue, 10 Mar 2026 08:50:37 +0000 (09:50 +0100)] 
dumpfd2fd: cover with more tests

4 weeks agowrite_mailbody: improve testing
Baptiste Daroussin [Tue, 10 Mar 2026 08:29:39 +0000 (09:29 +0100)] 
write_mailbody: improve testing

4 weeks agoreadlf: improve completness of the test
Baptiste Daroussin [Tue, 10 Mar 2026 08:24:52 +0000 (09:24 +0100)] 
readlf: improve completness of the test

4 weeks agounistr: add unit tests
Baptiste Daroussin [Tue, 10 Mar 2026 08:18:35 +0000 (09:18 +0100)] 
unistr: add unit tests

4 weeks agosubscription: add more tests about subscriptions functions
Baptiste Daroussin [Tue, 10 Mar 2026 08:09:37 +0000 (09:09 +0100)] 
subscription: add more tests about subscriptions functions

4 weeks agocheckwait_smtpreply add unit tests
Baptiste Daroussin [Tue, 10 Mar 2026 07:19:16 +0000 (08:19 +0100)] 
checkwait_smtpreply add unit tests

4 weeks agomlmmj-process: factorize
Baptiste Daroussin [Tue, 10 Mar 2026 06:50:36 +0000 (07:50 +0100)] 
mlmmj-process: factorize

4 weeks agosend_digest: code cleanup
Baptiste Daroussin [Tue, 10 Mar 2026 06:48:09 +0000 (07:48 +0100)] 
send_digest: code cleanup

no functional change intended

4 weeks agoproperky close smtp in case of ehlo failure
Baptiste Daroussin [Tue, 10 Mar 2026 06:31:18 +0000 (07:31 +0100)] 
properky close smtp in case of ehlo failure

4 weeks agosend_mail improve error handling
Baptiste Daroussin [Mon, 9 Mar 2026 21:38:28 +0000 (22:38 +0100)] 
send_mail improve error handling

4 weeks agosend_mail: test openat error
Baptiste Daroussin [Mon, 9 Mar 2026 21:35:16 +0000 (22:35 +0100)] 
send_mail: test openat error

4 weeks agoUse buffered I/O
Baptiste Daroussin [Mon, 9 Mar 2026 21:26:53 +0000 (22:26 +0100)] 
Use buffered I/O

4 weeks agofix thread grouping in digest
Baptiste Daroussin [Mon, 9 Mar 2026 21:22:08 +0000 (22:22 +0100)] 
fix thread grouping in digest

4 weeks agofix send_digest garbage
Baptiste Daroussin [Mon, 9 Mar 2026 21:18:02 +0000 (22:18 +0100)] 
fix send_digest garbage

5 weeks agoUpdate exim4 configuration hints 88/head
Wulf Coulmann [Fri, 6 Mar 2026 08:40:23 +0000 (09:40 +0100)] 
Update exim4 configuration hints
  - add debug output to router and transport
  - lookup changes according exim4 >= 4.94 taind behaver (Errors like "Tainted filename for search")
  - add router condition for setups with more than one domain (you need uniq local_parts over all your lists, but we do not want to match the transport on local_part@wrong.domain)

hint
  - VERP config is not changed/updated, may not work

7 weeks agomlmmj-process: clean up queue file on second do_all_the_voodoo_here failure 86/head
Michael S. Tsirkin [Sun, 8 Feb 2026 22:24:33 +0000 (17:24 -0500)] 
mlmmj-process: clean up queue file on second do_all_the_voodoo_here failure

The owner-forwarding path re-opens donemailname with O_TRUNC and calls
do_all_the_voodoo_here a second time. If this call fails, the truncated
queue file is left behind. Add unlink(donemailname) and free(donemailname)
to match the cleanup already done at the first call site.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7 weeks agotests: add test for owner path queue file cleanup
Michael S. Tsirkin [Sat, 17 Jan 2026 13:01:09 +0000 (08:01 -0500)] 
tests: add test for owner path queue file cleanup

Test that the queue file is cleaned up when do_all_the_voodoo_here
fails in the owner-forwarding path (second voodoo call).

Uses ulimit -n to limit file descriptors. With a tight limit, the
first voodoo succeeds but the second fails on dup().

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agoRelease 1.7.1 RELEASE_1_7_1
Baptiste Daroussin [Fri, 13 Feb 2026 14:10:35 +0000 (15:10 +0100)] 
Release 1.7.1

7 weeks agomlmmj-process: guard fclose on failed fopen
Michael S. Tsirkin [Tue, 10 Feb 2026 11:37:45 +0000 (06:37 -0500)] 
mlmmj-process: guard fclose on failed fopen

Avoid undefined behavior when queue file opens fail in moderation
notification paths.

7 weeks agoprepstdreply: fix resource leaks in error paths
Michael S. Tsirkin [Mon, 12 Jan 2026 15:37:43 +0000 (10:37 -0500)] 
prepstdreply: fix resource leaks in error paths

Use close_text() instead of free() when cleaning up txt in error paths.
The txt parameter is a fully initialized text structure from open_text(),
so it needs proper cleanup via close_text() to free all internal resources.

Also add missing close_text() call when prepstdreply_to() fails.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agodo_all_the_voodoo_here: fix memory leaks and NULL dereference
Michael S. Tsirkin [Mon, 12 Jan 2026 15:37:34 +0000 (10:37 -0500)] 
do_all_the_voodoo_here: fix memory leaks and NULL dereference

Fix two pre-existing issues:

1. Memory leak: unfolded variable from tll_pop_front() was never freed
   in the header processing loop. Add free(unfolded) at loop end and
   before continue statements.

2. NULL dereference: posteraddr can be NULL if From: header is missing
   or malformed. Pass empty string to process_headers_fd() when NULL
   to avoid undefined behavior in xasprintf().

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agosend_help: fix FILE* leak in send_help_noexit
Michael S. Tsirkin [Fri, 9 Jan 2026 10:24:34 +0000 (05:24 -0500)] 
send_help: fix FILE* leak in send_help_noexit

Add missing fclose(mail.fp) after send_single_mail(). The file is
opened with fopen() but never closed before returning.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agosubscriberfuncs: fix FILE* leak in generate_subconfirm
Michael S. Tsirkin [Fri, 9 Jan 2026 10:24:27 +0000 (05:24 -0500)] 
subscriberfuncs: fix FILE* leak in generate_subconfirm

Add missing fclose(mail.fp) after send_single_mail(). The file is
opened with fopen() but never closed before exit().

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agodo_all_the_voodoo_here: fix FILE* leaks in error paths
Michael S. Tsirkin [Fri, 9 Jan 2026 10:01:42 +0000 (05:01 -0500)] 
do_all_the_voodoo_here: fix FILE* leaks in error paths

Four error paths return without closing the FILE* f:
- process_headers_fd() failure in MIME header case
- process_headers_fd() failure in !hdrsadded case
- dprintf() failure when writing header terminator
- dumpfd2fd() failure when dumping mail body

Add fclose(f) before each return -1.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agolistcontrol: fix resource leaks in CTRL_GET error path
Michael S. Tsirkin [Fri, 9 Jan 2026 10:01:32 +0000 (05:01 -0500)] 
listcontrol: fix resource leaks in CTRL_GET error path

When send_single_mail() fails, the code returns without freeing
bounceaddr, archivefilename, or closing mail.fp. Also add cleanup on
the success path which is missing the same resources.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agofix missing fdopen() NULL checks across multiple files
Michael S. Tsirkin [Thu, 8 Jan 2026 12:48:45 +0000 (07:48 -0500)] 
fix missing fdopen() NULL checks across multiple files

If fdopen() fails (e.g., due to memory pressure), passing NULL to
subsequent stdio operations (getline, fclose, scan_headers, etc.)
causes undefined behavior, typically segmentation faults.

Add NULL checks after fdopen() calls in multiple files:

subscriberfuncs.c:
- find_subscriber(): return false on fdopen failure
- autosubscribe_sender(): return early on fdopen failure

mlmmj-send.c:
- send_mail_many_fd(): return -1 on fdopen failure
- main(): exit with failure on fdopen failure

mlmmj-process.c:
- is_moderator(): exit with failure on fdopen failure

listcontrol.c:
- listcontrol(): return -1 on fdopen failure, freeing resources

prepstdreply.c:
- init_file_lines_fd(): return NULL on fdopen failure
- get_msgid_line(): return id on fdopen failure (graceful degradation)
- open_text_fd(): return NULL on fdopen failure

do_all_the_voodoo_here.c:
- do_all_the_voodoo_here(): return -1 on fdopen or dup failure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agomlmmj: fix resource leaks in dsnparseaddr()
Michael S. Tsirkin [Thu, 8 Jan 2026 12:41:26 +0000 (07:41 -0500)] 
mlmmj: fix resource leaks in dsnparseaddr()

The dsnparseaddr() function has three resource leaks:

1. The file handle 'f' is never closed after parsing the DSN mail
2. The 'boundary' string is allocated but never freed
3. The 'emails' list is populated but never freed on exit

Free all three resources before all return paths.

Fixes: a1f1fbc8 ("mlmmj-bounce: make sure mlmmj-bounce is never called directly")
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agomlmmj: fix multiple resource leaks in send_probe()
Michael S. Tsirkin [Thu, 8 Jan 2026 12:40:30 +0000 (07:40 -0500)] 
mlmmj: fix multiple resource leaks in send_probe()

The send_probe() function has several resource leaks:

1. bfd (bounce directory file descriptor) is opened but never closed
2. fd (probe file descriptor) is opened but never closed on success
3. mail.fp is not closed on send_single_mail() failure path
4. queuefilename is allocated by prepstdreply() but never freed
5. myaddr and from are not freed on send_single_mail() failure path

Clean up all resources properly on both success and failure
paths.

Fixes: 958d3143 ("probes: fix a regression causing the probes not to sent the bounce numbers")
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agodo_all_the_voodoo_here: fix memory leak of fromemails and posteraddr
Michael S. Tsirkin [Thu, 8 Jan 2026 12:39:22 +0000 (07:39 -0500)] 
do_all_the_voodoo_here: fix memory leak of fromemails and posteraddr

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>
7 weeks agoprepstdreply: fix resource leaks on prepstdreply_to() failure
Michael S. Tsirkin [Thu, 8 Jan 2026 12:37:15 +0000 (07:37 -0500)] 
prepstdreply: fix resource leaks on prepstdreply_to() failure

When prepstdreply_to() returns false, the prepstdreply() function
returns NULL without:
1. Freeing the allocated retstr (queue filename)
2. Closing the opened outfd file descriptor

Add the cleanup.

Fixes: 660caa29 ("prepstdreply: split the function to make it more testable")
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agomlmmj-send: fix memory leak of verp variable
Michael S. Tsirkin [Thu, 8 Jan 2026 12:36:23 +0000 (07:36 -0500)] 
mlmmj-send: fix memory leak of verp variable

The verp variable is allocated via ctrlvalue() or xstrdup().
We free it in posfix case before it's assigned but we
forgot to free it when it's assigned NULL, so it will leak.

Free verp each time before it's assigned NULL.

Fixes: 4e53dbc8 ("VERP support")
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agosend_mail: fix memory leak in newsmtp()
Michael S. Tsirkin [Thu, 8 Jan 2026 12:34:40 +0000 (07:34 -0500)] 
send_mail: fix memory leak in newsmtp()

The newsmtp() function allocates memory for relayhost and smtphelo
but never frees them.

- relayhost: allocated via xstrdup() or ctrlvalue()
- smtphelo: allocated via ctrlvalue() or hostnamestr()

Both allocations are only used temporarily to call initsmtp(), which
copies the values it needs. So, just free() both.

Fixes: 48418b61 ("mlmmj-bounce: use send_mail directly and stop executing mlmmj-send")
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agotest: add a test about previous patch
Baptiste Daroussin [Fri, 13 Feb 2026 13:22:27 +0000 (14:22 +0100)] 
test: add a test about previous patch

7 weeks agomlmmj-process: move owner file open inside conditional
Michael S. Tsirkin [Thu, 8 Jan 2026 13:47:20 +0000 (08:47 -0500)] 
mlmmj-process: move owner file open inside conditional

The openat() call for the "owner" control file is executed
unconditionally for all recipextra values, but it's only needed
when recipextra equals "owner". Move the openat() and xasprintf()
calls inside the conditional block where they are actually used.

Fixes: ac9e3eef ("mlmmj-process: pass the owner via file descriptor to mlmmj-send")
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agotest: add a unit test about previous commit
Baptiste Daroussin [Fri, 13 Feb 2026 13:16:23 +0000 (14:16 +0100)] 
test: add a unit test about previous commit

7 weeks agomlmmj-send: only unlink subfilename when it was a real path
Michael S. Tsirkin [Mon, 12 Jan 2026 15:42:45 +0000 (10:42 -0500)] 
mlmmj-send: only unlink subfilename when it was a real path

When resending failed mails (case '3'), subfilename can be either:
- A numeric string like "5" representing an inherited file descriptor
- An actual file path

The strtoim() call sets errp=NULL when subfilename parses as a number,
and errp!=NULL when it's a path that needs to be opened.

Only call unlink() when errp!=NULL, i.e., when we opened a real file.
Otherwise unlink("5") would try to delete a file literally named "5"
in the current directory.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agoAdd a test case about the previous commit
Baptiste Daroussin [Fri, 13 Feb 2026 13:09:24 +0000 (14:09 +0100)] 
Add a test case about the previous commit

7 weeks agomlmmj-process: clean up queue file on do_all_the_voodoo_here failure
Michael S. Tsirkin [Fri, 9 Jan 2026 10:12:29 +0000 (05:12 -0500)] 
mlmmj-process: clean up queue file on do_all_the_voodoo_here failure

When do_all_the_voodoo_here() fails, the partially written queue file
is left behind. Add unlink() to match the cleanup done in the earlier
rawmailfd open failure path.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agotest: add test case about the keep queued resend file on failure
Baptiste Daroussin [Fri, 13 Feb 2026 12:54:23 +0000 (13:54 +0100)] 
test: add test case about the keep queued resend file on failure

7 weeks agomlmmj-send: keep queued resend file on failure
Michael S. Tsirkin [Fri, 9 Jan 2026 10:40:57 +0000 (05:40 -0500)] 
mlmmj-send: keep queued resend file on failure

Avoid deleting the queued recipients file when resending a failed mail if
sending fails again (e.g., fdopen/connect errors), preventing message loss.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agotest: add 2 new tests convering the previous commit
Baptiste Daroussin [Fri, 13 Feb 2026 12:47:42 +0000 (13:47 +0100)] 
test: add 2 new tests convering the previous commit

7 weeks agorequeuemail: fix single-recipient send failure losing address
Michael S. Tsirkin [Sat, 17 Jan 2026 10:40:01 +0000 (05:40 -0500)] 
requeuemail: fix single-recipient send failure losing address

When send_mail() fails for the only (or last) recipient, the address
gets popped into the 'addr' parameter, leaving 'addrs' empty. The
early return was checking only if addrs was empty, ignoring addr.

Effect: when sending to a single recipient fails, that recipient is
not saved to the requeue file and is lost entirely. The return value
of 0 (false) propagates back as "success", causing the caller to
delete the queue file as if sending succeeded.

Fix by only returning early when there is nothing to save (both addrs
empty AND addr NULL). This ensures failed recipients are properly
requeued for retry.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7 weeks agolistcontrol: replace __attribute__((fallthrough)) with comment
Konstantin Ryabitsev [Thu, 12 Feb 2026 15:10:12 +0000 (10:10 -0500)] 
listcontrol: replace __attribute__((fallthrough)) with comment

The __attribute__((fallthrough)) statement was added in GCC 7. Older
versions treat it as an empty declaration and emit a warning. Use a
/* fallthrough */ comment instead, which GCC (-Wimplicit-fallthrough)
and Clang both recognise as an intentional fallthrough annotation.

Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Assisted-by: claude-opus-4-6
7 weeks agoRename __unused macro to MLMMJ_UNUSED
Konstantin Ryabitsev [Thu, 12 Feb 2026 14:49:39 +0000 (09:49 -0500)] 
Rename __unused macro to MLMMJ_UNUSED

Identifiers with double-underscore prefixes are reserved for the C
implementation. Older glibc headers (bits/stat.h) use __unused as a
struct field name, so the mlmmj macro expansion produces invalid syntax
when that header is included transitively via fcntl.h.

Rename to MLMMJ_UNUSED to avoid the conflict and stay out of the
reserved namespace.

Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Assisted-by: claude-opus-4-6
7 weeks agoAdd a test case about the NULL deref in case of double call to
Baptiste Daroussin [Fri, 13 Feb 2026 12:39:40 +0000 (13:39 +0100)] 
Add a test case about the NULL deref in case of double call to
list+owner

8 weeks agomlmmj-process: fix NULL deref in owner mail reprocessing path 82/head 83/head
Konstantin Ryabitsev [Thu, 12 Feb 2026 15:25:15 +0000 (10:25 -0500)] 
mlmmj-process: fix NULL deref in owner mail reprocessing path

When mail is addressed to listname+owner, mlmmj-process calls
do_all_the_voodoo_here() a second time to strip envelope headers
before forwarding to the list owner. This second call reuses the
same allheaders list that was already populated by the first call.

Inside do_all_the_voodoo_here(), scan_headers() appends the new
mail's headers to the passed-in allhdrs list, while allunfoldeds
is a fresh local list containing only the headers from the current
scan. The main loop then iterates all entries in allhdrs (which now
includes headers from both calls) while popping from allunfoldeds
(which only has entries from the second scan). Once the unfolded
entries are exhausted, tll_pop_front() on the empty list dereferences
NULL and crashes.

Fix this by passing a separate local strlist to the second call so
that allhdrs and allunfoldeds stay in sync.

Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Assisted-by: claude-opus-4-6
2 months agoRelease 1.7.0 RELEASE_1_7_0
Baptiste Daroussin [Sun, 11 Jan 2026 19:51:17 +0000 (20:51 +0100)] 
Release 1.7.0

2 months agotests: enable glibc malloc corruption detection 78/head
Michael S. Tsirkin [Fri, 9 Jan 2026 08:49:17 +0000 (03:49 -0500)] 
tests: enable glibc malloc corruption detection

Set MALLOC_CHECK_=3 in test environment to detect memory corruption
issues like double-free and buffer overflows. When detected, glibc
will print a diagnostic and abort the program.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2 months agolistcontrol: fix double-free in CTRL_RELEASE error path
Michael S. Tsirkin [Thu, 8 Jan 2026 06:49:01 +0000 (01:49 -0500)] 
listcontrol: fix double-free in CTRL_RELEASE error path

moderatefilename is already freed before the autosubscribe block:

free(moderatefilename);
bool autosubscribe = statctrl(ml->ctrlfd, "autosubscribe");
if (autosubscribe) {
...
if (mfd == -1) {
free(sendfilename);
free(moderatefilename);  // double-free
return (-1);
}

Remove the second free.

Fixes: ac7f7646 ("autosubscribe: new feature")
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>