From a684d2f6c7a0df7d8448a202e671733d7172ca28 Mon Sep 17 00:00:00 2001 From: InterLinked1 <24227567+InterLinked1@users.noreply.github.com> Date: Sat, 28 Sep 2024 09:17:24 -0400 Subject: [PATCH] mod_mailscript: Fix NULL pointer dereference for outgoing filters. The message processing callbacks for outgoing messages are run on messages for all recipients at once, rather than per recipient, so mproc.to (the envelope recipient) is actually empty in this case. As such, ensure that the recipient is non-empty before attempting to do string comparison on it. --- modules/mod_mailscript.c | 4 +++- nets/net_smtp.c | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/mod_mailscript.c b/modules/mod_mailscript.c index d38a6a5..8ca2fd6 100644 --- a/modules/mod_mailscript.c +++ b/modules/mod_mailscript.c @@ -152,7 +152,7 @@ static int header_match(struct smtp_msg_process *mproc, const char *header, cons return found; } -static void str_match(const char *matchtype, const char *a, const char *expr, int *restrict match) +static void __attribute__ ((nonnull (2, 3, 4))) str_match(const char *matchtype, const char *a, const char *expr, int *restrict match) { if (!strcasecmp(matchtype, "EQUALS")) { *match = !strcmp(a, expr); @@ -206,12 +206,14 @@ static int test_condition(struct smtp_msg_process *mproc, int lineno, int lastre matchtype = strsep(&s, " "); expr = s; REQUIRE_ARG(expr); + REQUIRE_ARG(mproc->from); str_match(matchtype, mproc->from, expr, &match); } else if (!strcasecmp(next, "RECIPIENT")) { const char *expr, *matchtype; matchtype = strsep(&s, " "); expr = s; REQUIRE_ARG(expr); + REQUIRE_ARG(mproc->recipient); str_match(matchtype, mproc->recipient, expr, &match); } else if (!strcasecmp(next, "HEADER")) { int found; diff --git a/nets/net_smtp.c b/nets/net_smtp.c index 46db1a5..6cce712 100644 --- a/nets/net_smtp.c +++ b/nets/net_smtp.c @@ -2284,6 +2284,12 @@ static int do_deliver(struct smtp_session *smtp, const char *filename, size_t da mproc.mbox = NULL; mproc.userid = (int) smtp->node->user->id; mproc.user = smtp->node->user; + /* Note that mproc.to here is NULL, since we don't process recipients until expand_and_deliver, + * i.e. we run the callbacks here per-message, not per-recipient, so we don't have access + * to a specific recipient for this outgoing rules. This is "pre transaction" + * so there's not really an "envelope" recipient per se we can use. + * XXX We do have access to &smtp->recipients at this point, so we could make those available + * to rules if needed. */ if (smtp_run_callbacks(&mproc)) { return 0; /* If returned nonzero, it's assumed it responded with an SMTP error code as appropriate. */ }