Version in base suite: 6.0.3p1-5+deb10u3 Base version: opensmtpd_6.0.3p1-5+deb10u3 Target version: opensmtpd_6.0.3p1-5+deb10u4 Base file: /srv/ftp-master.debian.org/ftp/pool/main/o/opensmtpd/opensmtpd_6.0.3p1-5+deb10u3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/o/opensmtpd/opensmtpd_6.0.3p1-5+deb10u4.dsc changelog | 12 ++ patches/021_952453.diff | 254 ++++++++++++++++++++++++++++++++++++++++++++++++ patches/series | 1 3 files changed, 267 insertions(+) diff -Nru opensmtpd-6.0.3p1/debian/changelog opensmtpd-6.0.3p1/debian/changelog --- opensmtpd-6.0.3p1/debian/changelog 2020-01-29 00:44:11.000000000 +0000 +++ opensmtpd-6.0.3p1/debian/changelog 2020-02-25 16:12:06.000000000 +0000 @@ -1,3 +1,15 @@ +opensmtpd (6.0.3p1-5+deb10u4) buster-security; urgency=high + + * Fix LPE and RCE vulnerability (Closes: #952453) (CVE-2020-8794) + An out of bounds read in smtpd allows an attacker to inject arbitrary + commands into the envelope file which are then executed as root. + Separately, missing privilege revocation in smtpctl allows arbitrary + commands to be run with the _smtpq group. + OpenBSD 6.6 errata 021: + https://ftp.openbsd.org/pub/OpenBSD/patches/6.6/common/021_smtpd_envelope.patch.sig + + -- Ryan Kavanagh Tue, 25 Feb 2020 11:12:06 -0500 + opensmtpd (6.0.3p1-5+deb10u3) buster-security; urgency=high * Fix two major security bugs (Closes: #950121) (CVE-2020-7247) diff -Nru opensmtpd-6.0.3p1/debian/patches/021_952453.diff opensmtpd-6.0.3p1/debian/patches/021_952453.diff --- opensmtpd-6.0.3p1/debian/patches/021_952453.diff 1970-01-01 00:00:00.000000000 +0000 +++ opensmtpd-6.0.3p1/debian/patches/021_952453.diff 2020-02-25 16:12:06.000000000 +0000 @@ -0,0 +1,254 @@ +Description: Fix arbitrary command execution vulnerability + OpenBSD 6.6 errata 021, February 24, 2020: + + An out of bounds read in smtpd allows an attacker to inject arbitrary + commands into the envelope file which are then executed as root. + Separately, missing privilege revocation in smtpctl allows arbitrary + commands to be run with the _smtpq group. + + https://ftp.openbsd.org/pub/OpenBSD/patches/6.6/common/021_smtpd_envelope.patch.sig + + This patch is NOT the above errata patch. Rather, it was generated + from the upstream git repository as follows: + $ git diff 6.6.3p1..6.6.4p1 > 021_952453.diff + This patch did not apply cleanly. The two rejects were: + * smtpd/makemap.c: manually backported hunk #1 by comparing to + git show 6.6.4p1:smtpd/makemap.c + * smtpd/smtpd.h: hunk #1 was a version bump and has been dropped. +Origin: backport, commit:6.6.3p1..6.6.4p1 +Bug-Debian: https://bugs.debian.org/952453 +Forwarded: not-needed +Applied-Upstream: 6.6.4p1 +Last-Update: 2020-02-25 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: opensmtpd/mk/pathnames +=================================================================== +--- opensmtpd.orig/mk/pathnames 2020-02-25 10:58:56.800106762 -0500 ++++ opensmtpd/mk/pathnames 2020-02-25 10:58:56.796107118 -0500 +@@ -6,6 +6,5 @@ + -DPATH_CHROOT=\"$(PRIVSEP_PATH)\" \ + -DPATH_SMTPCTL=\"$(sbindir)/smtpctl\" \ + -DPATH_MAILLOCAL=\"$(pkglibexecdir)/mail.local\" \ ++ -DPATH_MAKEMAP=\"$(sbindir)/makemap\" \ + -DPATH_LIBEXEC=\"$(pkglibexecdir)\" +- +- +Index: opensmtpd/smtpd/makemap.c +=================================================================== +--- opensmtpd.orig/smtpd/makemap.c 2020-02-25 10:58:56.800106762 -0500 ++++ opensmtpd/smtpd/makemap.c 2020-02-25 11:02:17.122256154 -0500 +@@ -105,8 +105,13 @@ + int ch, dbputs = 0, Uflag = 0; + DBTYPE dbtype = DB_HASH; + char *p; ++ gid_t gid; + int fd = -1; + ++ gid = getgid(); ++ if (setresgid(gid, gid, gid) == -1) ++ err(1, "setresgid"); ++ + log_init(1, LOG_MAIL); + + mode = prog_mode; +@@ -180,9 +185,9 @@ + errx(1, "database name too long"); + } + +- execlp("makemap", "makemap", "-d", argv[0], "-o", dbname, "-", +- (char *)NULL); +- err(1, "execlp"); ++ execl(PATH_MAKEMAP, "makemap", "-d", argv[0], "-o", dbname, ++ "-", (char *)NULL); ++ err(1, "execl"); + } + + if (mode == P_NEWALIASES) { +Index: opensmtpd/smtpd/mta_session.c +=================================================================== +--- opensmtpd.orig/smtpd/mta_session.c 2020-02-25 10:58:56.800106762 -0500 ++++ opensmtpd/smtpd/mta_session.c 2020-02-25 10:58:56.796107118 -0500 +@@ -1214,7 +1214,7 @@ + if (cont) { + if (s->replybuf[0] == '\0') + (void)strlcat(s->replybuf, line, sizeof s->replybuf); +- else { ++ else if (len > 4) { + line = line + 4; + if (isdigit((int)*line) && *(line + 1) == '.' && + isdigit((int)*line+2) && *(line + 3) == '.' && +@@ -1229,7 +1229,9 @@ + /* last line of a reply, check if we're on a continuation to parse out status and ESC. + * if we overflow reply buffer or are not on continuation, log entire last line. + */ +- if (s->replybuf[0] != '\0') { ++ if (s->replybuf[0] == '\0') ++ (void)strlcat(s->replybuf, line, sizeof s->replybuf); ++ else if (len > 4) { + p = line + 4; + if (isdigit((int)*p) && *(p + 1) == '.' && + isdigit((int)*p+2) && *(p + 3) == '.' && +@@ -1238,8 +1240,6 @@ + if (strlcat(s->replybuf, p, sizeof s->replybuf) >= sizeof s->replybuf) + (void)strlcpy(s->replybuf, line, sizeof s->replybuf); + } +- else +- (void)strlcpy(s->replybuf, line, sizeof s->replybuf); + + if (s->state == MTA_QUIT) { + log_info("%016"PRIx64" mta event=closed reason=quit messages=%zu", +Index: opensmtpd/smtpd/queue_fs.c +=================================================================== +--- opensmtpd.orig/smtpd/queue_fs.c 2020-02-25 10:58:56.800106762 -0500 ++++ opensmtpd/smtpd/queue_fs.c 2020-02-25 10:58:56.796107118 -0500 +@@ -314,8 +314,7 @@ + fsqueue_envelope_incoming_path(*evpid, path, + sizeof(path)); + +- r = fsqueue_envelope_dump(path, buf, len, 0, 0); +- if (r >= 0) ++ if ((r = fsqueue_envelope_dump(path, buf, len, 0, 0)) != 0) + goto done; + } + r = 0; +Index: opensmtpd/smtpd/smtpctl.c +=================================================================== +--- opensmtpd.orig/smtpd/smtpctl.c 2020-02-25 10:58:56.800106762 -0500 ++++ opensmtpd/smtpd/smtpctl.c 2020-02-25 10:58:56.796107118 -0500 +@@ -1116,7 +1116,7 @@ + */ + for (i = 1; i < argc; i++) + if (strncmp(argv[i], "-bi", 3) == 0) +- exit(makemap(P_NEWALIASES, argc, argv)); ++ exit(makemap(P_SENDMAIL, argc, argv)); + + if (!srv_connect()) + offlinefp = offline_file(); +Index: opensmtpd/smtpd/smtpd-defines.h +=================================================================== +--- opensmtpd.orig/smtpd/smtpd-defines.h 2020-02-25 10:58:56.800106762 -0500 ++++ opensmtpd/smtpd/smtpd-defines.h 2020-02-25 10:58:56.796107118 -0500 +@@ -46,6 +46,12 @@ + #ifndef PATH_SPOOL + #define PATH_SPOOL "/var/spool/smtpd" + #endif ++#ifndef PATH_MAILLOCAL ++#define PATH_MAILLOCAL "/usr/libexec/mail.local" ++#endif ++#ifndef PATH_MAKEMAP ++#define PATH_MAKEMAP "/usr/sbin/makemap" ++#endif + + #define SUBADDRESSING_DELIMITER "+" + +Index: opensmtpd/smtpd/smtpd.c +=================================================================== +--- opensmtpd.orig/smtpd/smtpd.c 2020-02-25 10:58:56.800106762 -0500 ++++ opensmtpd/smtpd/smtpd.c 2020-02-25 10:58:56.800106762 -0500 +@@ -109,9 +109,9 @@ + static int imsg_wait(struct imsgbuf *, struct imsg *, int); + + static void offline_scan(int, short, void *); +-static int offline_add(char *); ++static int offline_add(char *, uid_t, gid_t); + static void offline_done(void); +-static int offline_enqueue(char *); ++static int offline_enqueue(char *, uid_t, gid_t); + + static void purge_task(void); + static int parent_auth_user(const char *, const char *); +@@ -136,6 +136,8 @@ + + struct offline { + TAILQ_ENTRY(offline) entry; ++ uid_t uid; ++ gid_t gid; + char *path; + }; + +@@ -1409,7 +1411,8 @@ + continue; + } + +- if (offline_add(e->fts_name)) { ++ if (offline_add(e->fts_name, e->fts_statp->st_uid, ++ e->fts_statp->st_gid)) { + log_warnx("warn: smtpd: " + "could not add offline message %s", e->fts_name); + continue; +@@ -1429,7 +1432,7 @@ + } + + static int +-offline_enqueue(char *name) ++offline_enqueue(char *name, uid_t uid, gid_t gid) + { + char *path; + struct stat sb; +@@ -1491,6 +1494,18 @@ + _exit(1); + } + ++ if (sb.st_uid != uid) { ++ log_warnx("warn: smtpd: file %s has bad uid %d", ++ path, sb.st_uid); ++ _exit(1); ++ } ++ ++ if (sb.st_gid != gid) { ++ log_warnx("warn: smtpd: file %s has bad gid %d", ++ path, sb.st_gid); ++ _exit(1); ++ } ++ + pw = getpwuid(sb.st_uid); + if (pw == NULL) { + log_warnx("warn: smtpd: getpwuid for uid %d failed", +@@ -1547,17 +1562,19 @@ + } + + static int +-offline_add(char *path) ++offline_add(char *path, uid_t uid, gid_t gid) + { + struct offline *q; + + if (offline_running < OFFLINE_QUEUEMAX) + /* skip queue */ +- return offline_enqueue(path); ++ return offline_enqueue(path, uid, gid); + + q = malloc(sizeof(*q) + strlen(path) + 1); + if (q == NULL) + return (-1); ++ q->uid = uid; ++ q->gid = gid; + q->path = (char *)q + sizeof(*q); + memmove(q->path, path, strlen(path) + 1); + TAILQ_INSERT_TAIL(&offline_q, q, entry); +@@ -1576,7 +1593,7 @@ + if ((q = TAILQ_FIRST(&offline_q)) == NULL) + break; /* all done */ + TAILQ_REMOVE(&offline_q, q, entry); +- offline_enqueue(q->path); ++ offline_enqueue(q->path, q->uid, q->gid); + free(q); + } + } +Index: opensmtpd/smtpd/smtpd.h +=================================================================== +--- opensmtpd.orig/smtpd/smtpd.h 2020-02-25 10:58:56.800106762 -0500 ++++ opensmtpd/smtpd/smtpd.h 2020-02-25 10:58:56.800106762 -0500 +@@ -128,8 +128,9 @@ + #define MTA_EXT_DSN 0x400 + + +-#define P_NEWALIASES 0 +-#define P_MAKEMAP 1 ++#define P_SENDMAIL 0 ++#define P_NEWALIASES 1 ++#define P_MAKEMAP 2 + + struct userinfo { + char username[SMTPD_VUSERNAME_SIZE]; diff -Nru opensmtpd-6.0.3p1/debian/patches/series opensmtpd-6.0.3p1/debian/patches/series --- opensmtpd-6.0.3p1/debian/patches/series 2020-01-29 00:44:11.000000000 +0000 +++ opensmtpd-6.0.3p1/debian/patches/series 2020-02-25 16:12:06.000000000 +0000 @@ -3,3 +3,4 @@ 11_ssl_1.1.diff 018_smtpd_tls.patch.sig 019_smtpd_exec.patch.sig +021_952453.diff