untrusted comment: verify with openbsd-66-base.pub
RWSvK/c+cFe24PQlSW4IqzXO+O//TGxzhpNhtvf3OZuAuk9HJESyiBCLgdRXom7PLKrqj6GlTDphA7DzYR5zcj78+u0yIkgpEAE=

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.

Apply by doing:
    signify -Vep /etc/signify/openbsd-66-base.pub -x \
	021_smtpd_envelope.patch.sig -m - | (cd /usr/src && patch -p0)

And then rebuild and install smtpd:
    cd /usr/src/usr.sbin/smtpd
    make obj
    make
    make install

Index: usr.sbin/smtpd/makemap.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/makemap.c,v
retrieving revision 1.72
diff -u -r1.72 makemap.c
--- usr.sbin/smtpd/makemap.c	28 Dec 2018 11:40:29 -0000	1.72
+++ usr.sbin/smtpd/makemap.c	20 Feb 2020 01:00:42 -0000
@@ -83,8 +83,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");
+
 	if ((env = config_default()) == NULL)
 		err(1, NULL);
 
@@ -161,9 +166,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: usr.sbin/smtpd/mta_session.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/mta_session.c,v
retrieving revision 1.122.2.1
diff -u -r1.122.2.1 mta_session.c
--- usr.sbin/smtpd/mta_session.c	28 Jan 2020 21:37:29 -0000	1.122.2.1
+++ usr.sbin/smtpd/mta_session.c	20 Feb 2020 01:00:42 -0000
@@ -1177,7 +1177,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) == '.' &&
@@ -1192,7 +1192,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) == '.' &&
@@ -1201,8 +1203,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 disconnected reason=quit messages=%zu",
Index: usr.sbin/smtpd/smtpctl.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpctl.c,v
retrieving revision 1.165
diff -u -r1.165 smtpctl.c
--- usr.sbin/smtpd/smtpctl.c	23 Jul 2019 08:11:10 -0000	1.165
+++ usr.sbin/smtpd/smtpctl.c	20 Feb 2020 01:00:42 -0000
@@ -1125,7 +1125,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: usr.sbin/smtpd/smtpd-defines.h
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpd-defines.h,v
retrieving revision 1.10
diff -u -r1.10 smtpd-defines.h
--- usr.sbin/smtpd/smtpd-defines.h	27 Dec 2018 15:41:50 -0000	1.10
+++ usr.sbin/smtpd/smtpd-defines.h	20 Feb 2020 01:00:42 -0000
@@ -37,6 +37,7 @@
 #define SMTPD_QUEUE_USER	"_smtpq"
 #define SMTPD_QUEUE_GROUP	"_smtpq"
 #define PATH_SPOOL		"/var/spool/smtpd"
+#define PATH_MAKEMAP		"/usr/sbin/makemap"
 
 #define SUBADDRESSING_DELIMITER	"+"
 
Index: usr.sbin/smtpd/smtpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.c,v
retrieving revision 1.325
diff -u -r1.325 smtpd.c
--- usr.sbin/smtpd/smtpd.c	3 Sep 2019 04:48:20 -0000	1.325
+++ usr.sbin/smtpd/smtpd.c	20 Feb 2020 01:00:42 -0000
@@ -81,9 +81,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 *);
@@ -112,6 +112,8 @@
 
 struct offline {
 	TAILQ_ENTRY(offline)	 entry;
+	uid_t			 uid;
+	gid_t			 gid;
 	char			*path;
 };
 
@@ -1550,7 +1552,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;
@@ -1570,7 +1573,7 @@
 }
 
 static int
-offline_enqueue(char *name)
+offline_enqueue(char *name, uid_t uid, gid_t gid)
 {
 	char		*path;
 	struct stat	 sb;
@@ -1633,6 +1636,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",
@@ -1689,17 +1704,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);
@@ -1718,7 +1735,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: usr.sbin/smtpd/smtpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v
retrieving revision 1.641
diff -u -r1.641 smtpd.h
--- usr.sbin/smtpd/smtpd.h	30 Sep 2019 08:31:41 -0000	1.641
+++ usr.sbin/smtpd/smtpd.h	20 Feb 2020 01:00:42 -0000
@@ -98,8 +98,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
 
 #define	CERT_ERROR	-1
 #define	CERT_OK		 0
