From 5cca5d1e300a41bda91b983c8ccf7fbb60ccb957 Mon Sep 17 00:00:00 2001 From: Matthias Andree Date: Thu, 26 Aug 2021 23:53:14 +0200 Subject: fetchmail.c: Fix SIGSEGV optmerge()ing "no envelope" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported by Bjørn Mork, fixes Debian Bug#992400. Crash happens inside xstrdup() on a strlen((char *)-1) where the argument is constant and the trigger is a local trusted configuration file, so not deemed a vulnerability. --- NEWS | 5 +++++ fetchmail.c | 2 +- fetchmail.h | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 63a8cfcb..927448ac 100644 --- a/NEWS +++ b/NEWS @@ -125,6 +125,11 @@ fetchmail-6.4.22 (not yet released): * Fetchmail no longer leaks memory when processing the arguments of --plugin or --plugout on connections. * On POP3 connections, the CAPAbilities parser is now caseblind. +* Fix segfault on configurations with "defaults ... no envelope". Reported by + Bjørn Mork. Fixes Debian Bug#992400. This is a regression in fetchmail 6.4.3 + and happened when plugging memory leaks, which did not account for that the + envelope parameter is special when set as "no envelope". The segfault happens + in a constant strlen(-1), triggered by trusted local input => no vulnerability. # CHANGES: * IMAP: When fetchmail is in not-authenticated state and the server volunteers diff --git a/fetchmail.c b/fetchmail.c index ac8e4607..71ecc1b0 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -996,7 +996,7 @@ static void optmerge(struct query *h2, struct query *h1, int force) list_merge(&h2->antispam, &h1->antispam, force); #define FLAG_MERGE(fld) do { if (force ? !!h1->fld : !h2->fld) h2->fld = h1->fld; } while (0) -#define STRING_MERGE(fld) do { if (force ? !!h1->fld : !h2->fld) { if (h2->fld) free((void *)h2->fld), h2->fld = 0; if (h1->fld) h2->fld = xstrdup(h1->fld); } } while (0) +#define STRING_MERGE(fld) do { if (force ? !!h1->fld : !h2->fld) { if (h2->fld) free((void *)h2->fld), h2->fld = 0; if (h1->fld) { if (h1->fld != STRING_DISABLED) h2->fld = xstrdup(h1->fld); else h2->fld = STRING_DISABLED; } } } while (0) STRING_MERGE(server.via); FLAG_MERGE(server.protocol); STRING_MERGE(server.service); diff --git a/fetchmail.h b/fetchmail.h index 717ebd6f..d976f481 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -265,7 +265,7 @@ struct hostdata /* shared among all user connections to given server */ int interval; /* # cycles to skip between polls */ int authenticate; /* authentication mode to try */ int timeout; /* inactivity timout in seconds */ - char *envelope; /* envelope address list header */ + char *envelope; /* envelope address list header - WARNING - can take value STRING_DISABLED (-1)! */ int envskip; /* skip to numbered envelope header */ char *qvirtual; /* prefix removed from local user id */ flag skip; /* suppress poll in implicit mode? */ -- cgit v1.2.3