Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian....@packages.debian.org
Usertags: pu

This upload is intended to solve several problems.  While it's somewhat
unusual, since it includes new upstream releases, the upstream changes are
very targetted and all things that I believe are appropriate to fix in a
stable update:

Security:

        Security: Berkeley DB 2 and later try to read settings from
        a file DB_CONFIG in the current directory.

The Debian security team requested this be fixed in a stable update.

Safety:

        Safety net: append a null byte to vstring buffers, so that
        C-style string operations won't scribble past the end.

Regression corrections (relative to postfix 2.11 in oldstable):

        Compatibility fix (introduced: Postfix 3.1): some Milter
        applications do not recognize macros sent as {name} when
        macros have single-character names. Postfix now sends such
        macros without {} as it has done historically.

        Workaround (introduced: Postfix 3.0 20140718): prevent MIME
        downgrade of Postfix-generated message/delivery status.
        It's supposed to be 7bit, therefore quoted-printable encoding
        is not expected. Problem reported by Griff. File:
        bounce/bounce_notify_util.c.

Additionally, there's a packaging fix for a bug that broke multi-instance.

Each of these changes is small and self-contained.  Due to my recent lack of
time for Debian work, the upstream changes have had three months of use with
no issues reported on the very active postfix-users mailing list.

I have the package built and ready to upload.

Scott K
diff -Nru postfix-3.1.4/debian/changelog postfix-3.1.6/debian/changelog
--- postfix-3.1.4/debian/changelog	2017-05-21 14:38:07.000000000 -0400
+++ postfix-3.1.6/debian/changelog	2017-09-27 00:59:24.000000000 -0400
@@ -1,3 +1,40 @@
+postfix (3.1.6-0+deb9u1) stretch; urgency=medium
+
+    [Wietse Venema]
+
+  * New Upstream 3.1.5
+    - Compatibility fix (introduced: Postfix 3.1): some Milter
+      applications do not recognize macros sent as {name} when
+      macros have single-character names. Postfix now sends such
+      macros without {} as it has done historically. Viktor
+      Dukhovni. File: milter/milter.c.
+    - Safety net: append a null byte to vstring buffers, so that
+      C-style string operations won't scribble past the end. File:
+      vstring.c.
+    - Workaround (introduced: Postfix 3.0 20140718): prevent MIME
+      downgrade of Postfix-generated message/delivery status.
+      It's supposed to be 7bit, therefore quoted-printable encoding
+      is not expected. Problem reported by Griff. File:
+      bounce/bounce_notify_util.c.
+  * New Upstream 3.1.6 
+    - Security: Berkeley DB 2 and later try to read settings from
+      a file DB_CONFIG in the current directory.  This undocumented
+      feature may introduce undisclosed vulnerabilities resulting
+      in privilege escalation with Postfix set-gid programs
+      (postdrop, postqueue) before they chdir to the Postfix queue
+      directory, and with the postmap and postalias commands
+      depending on whether the user's current directory is writable
+      by other users. This fix does not change Postfix behavior
+      for Berkeley DB < 3, but reduces file create performance
+      for Berkeley DB 3 .. 4.6.  File: util/dict_db.c.  Closes: #864942
+
+    [Scott Kitterman]
+
+  * Refresh debian/patches/11_postmap_update.diff
+  * Use full path to main.cf in postfix-instance-generator.  Closes: #873957
+
+ -- Scott Kitterman <sc...@kitterman.com>  Wed, 27 Sep 2017 00:56:28 -0400
+
 postfix (3.1.4-7) unstable; urgency=medium
 
   * Fix use of smtp binary for lmtp service on new installs and bump version
diff -Nru postfix-3.1.4/debian/patches/11_postmap_update.diff postfix-3.1.6/debian/patches/11_postmap_update.diff
--- postfix-3.1.4/debian/patches/11_postmap_update.diff	2017-05-19 10:50:13.000000000 -0400
+++ postfix-3.1.6/debian/patches/11_postmap_update.diff	2017-09-27 00:26:51.000000000 -0400
@@ -1,7 +1,7 @@
 Index: postfix/html/postmap.1.html
 ===================================================================
---- postfix.orig/html/postmap.1.html	2016-03-01 05:01:20.999356738 -0700
-+++ postfix/html/postmap.1.html	2016-03-01 05:01:20.995356871 -0700
+--- postfix.orig/html/postmap.1.html	2017-09-27 00:26:44.474769942 -0400
++++ postfix/html/postmap.1.html	2017-09-27 00:26:44.466769942 -0400
 @@ -10,7 +10,7 @@
         postmap - Postfix lookup table management
  
@@ -24,8 +24,8 @@
                instead of the default configuration directory.
 Index: postfix/man/man1/postmap.1
 ===================================================================
---- postfix.orig/man/man1/postmap.1	2016-03-01 05:01:20.999356738 -0700
-+++ postfix/man/man1/postmap.1	2016-03-01 05:01:20.995356871 -0700
+--- postfix.orig/man/man1/postmap.1	2017-09-27 00:26:44.474769942 -0400
++++ postfix/man/man1/postmap.1	2017-09-27 00:26:44.466769942 -0400
 @@ -9,7 +9,7 @@
  .na
  .nf
@@ -46,8 +46,8 @@
  truncate an existing database. By default, \fBpostmap\fR(1) creates
 Index: postfix/src/postmap/postmap.c
 ===================================================================
---- postfix.orig/src/postmap/postmap.c	2016-03-01 05:01:20.999356738 -0700
-+++ postfix/src/postmap/postmap.c	2016-03-01 05:01:20.995356871 -0700
+--- postfix.orig/src/postmap/postmap.c	2017-09-27 00:26:44.474769942 -0400
++++ postfix/src/postmap/postmap.c	2017-09-27 00:26:44.466769942 -0400
 @@ -77,6 +77,8 @@
  /*	syntax checks anyway.
  /* .sp
@@ -165,8 +165,8 @@
  	    usage(argv[0]);
 Index: postfix/src/util/dict.h
 ===================================================================
---- postfix.orig/src/util/dict.h	2016-03-01 05:01:20.999356738 -0700
-+++ postfix/src/util/dict.h	2016-03-01 05:01:20.995356871 -0700
+--- postfix.orig/src/util/dict.h	2017-09-27 00:26:44.474769942 -0400
++++ postfix/src/util/dict.h	2017-09-27 00:26:44.466769942 -0400
 @@ -123,6 +123,7 @@
  #define DICT_FLAG_NO_UNAUTH	(1<<13)	/* disallow unauthenticated data */
  #define DICT_FLAG_FOLD_FIX	(1<<14)	/* case-fold key with fixed-case map */
@@ -177,10 +177,10 @@
  #define DICT_FLAG_BULK_UPDATE	(1<<17)	/* optimize for bulk updates */
 Index: postfix/src/util/dict_db.c
 ===================================================================
---- postfix.orig/src/util/dict_db.c	2016-03-01 05:01:20.999356738 -0700
-+++ postfix/src/util/dict_db.c	2016-03-01 05:01:20.995356871 -0700
-@@ -689,6 +689,12 @@
- 	msg_fatal("set DB cache size %d: %m", dict_db_cache_size);
+--- postfix.orig/src/util/dict_db.c	2017-09-27 00:26:44.474769942 -0400
++++ postfix/src/util/dict_db.c	2017-09-27 00:26:44.466769942 -0400
+@@ -735,6 +735,12 @@
+ 	msg_panic("db_create null result");
      if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0)
  	msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM);
 +    if (dict_flags & DICT_FLAG_UPGRADE) {
diff -Nru postfix-3.1.4/debian/postfix-instance-generator postfix-3.1.6/debian/postfix-instance-generator
--- postfix-3.1.4/debian/postfix-instance-generator	2017-05-07 23:54:30.000000000 -0400
+++ postfix-3.1.6/debian/postfix-instance-generator	2017-09-27 00:55:57.000000000 -0400
@@ -7,7 +7,7 @@
 
 mkdir -p "$WANTDIR"
 
-if [ -f main.cf ]; then
+if [ -f /etc/postfix/main.cf ]; then
     for NAME in $(postmulti -l -a | awk '{ print $1}'); do
         ln -s "$SERVICEFILE" "$WANTDIR/postfix@$NAME.service"
     done
diff -Nru postfix-3.1.4/HISTORY postfix-3.1.6/HISTORY
--- postfix-3.1.4/HISTORY	2017-01-01 12:49:40.000000000 -0500
+++ postfix-3.1.6/HISTORY	2017-06-13 13:31:40.000000000 -0400
@@ -22317,3 +22317,38 @@
 	senders with "smtpd_reject_unlisted_recipient = yes" or
 	with reject_unlisted_sender.  Stephen R. van den Berg (Mr.
 	procmail).  Files: smtpd/smtpd.c, smtpd/smtpd_check.c.
+
+20170221
+
+	Compatibility fix (introduced: Postfix 3.1): some Milter
+	applications do not recognize macros sent as {name} when
+	macros have single-character names. Postfix now sends such
+	macros without {} as it has done historically. Viktor
+	Dukhovni. File: milter/milter.c.
+
+20170430
+
+	Safety net: append a null byte to vstring buffers, so that
+	C-style string operations won't scribble past the end. File:
+	vstring.c.
+
+20170610
+
+	Workaround (introduced: Postfix 3.0 20140718): prevent MIME
+	downgrade of Postfix-generated message/delivery status.
+	It's supposed to be 7bit, therefore quoted-printable encoding
+	is not expected. Problem reported by Griff. File:
+	bounce/bounce_notify_util.c.
+
+20170611
+
+	Security: Berkeley DB 2 and later try to read settings from
+	a file DB_CONFIG in the current directory.  This undocumented
+	feature may introduce undisclosed vulnerabilities resulting
+	in privilege escalation with Postfix set-gid programs
+	(postdrop, postqueue) before they chdir to the Postfix queue
+	directory, and with the postmap and postalias commands
+	depending on whether the user's current directory is writable
+	by other users. This fix does not change Postfix behavior
+	for Berkeley DB < 3, but reduces file create performance
+	for Berkeley DB 3 .. 4.6.  File: util/dict_db.c.
diff -Nru postfix-3.1.4/src/bounce/bounce_notify_util.c postfix-3.1.6/src/bounce/bounce_notify_util.c
--- postfix-3.1.4/src/bounce/bounce_notify_util.c	2015-01-26 15:00:13.000000000 -0500
+++ postfix-3.1.6/src/bounce/bounce_notify_util.c	2017-06-10 14:47:25.000000000 -0400
@@ -637,7 +637,9 @@
 		      (bounce_info->smtputf8 & SMTPUTF8_FLAG_REQUESTED) ?
 		      "global-" : "");
     /* Fix 20140709: addresses may be 8bit. */
-    if (NOT_7BIT_MIME(bounce_info))
+    if (NOT_7BIT_MIME(bounce_info)
+    /* BC Fix 20170610: prevent MIME downgrade of message/delivery-status. */
+	&& (bounce_info->smtputf8 & SMTPUTF8_FLAG_REQUESTED))
 	post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
 			  bounce_info->mime_encoding);
 
diff -Nru postfix-3.1.4/src/global/mail_version.h postfix-3.1.6/src/global/mail_version.h
--- postfix-3.1.4/src/global/mail_version.h	2017-01-01 13:01:36.000000000 -0500
+++ postfix-3.1.6/src/global/mail_version.h	2017-06-13 13:36:23.000000000 -0400
@@ -20,8 +20,8 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE	"20170101"
-#define MAIL_VERSION_NUMBER	"3.1.4"
+#define MAIL_RELEASE_DATE	"20170613"
+#define MAIL_VERSION_NUMBER	"3.1.6"
 
 #ifdef SNAPSHOT
 #define MAIL_VERSION_DATE	"-" MAIL_RELEASE_DATE
diff -Nru postfix-3.1.4/src/milter/milter.c postfix-3.1.6/src/milter/milter.c
--- postfix-3.1.4/src/milter/milter.c	2016-01-23 19:42:19.000000000 -0500
+++ postfix-3.1.6/src/milter/milter.c	2017-02-21 17:32:57.000000000 -0500
@@ -333,18 +333,21 @@
     VSTRING *canon_buf = vstring_alloc(20);
     const char *value;
     const char *name;
+    const char *cname;
 
     while ((name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) {
 	if (msg_verbose)
 	    msg_info("%s: \"%s\"", myname, name);
 	if (*name != '{')			/* } */
-	    name = STR(vstring_sprintf(canon_buf, "{%s}", name));
-	if ((value = milters->mac_lookup(name, milters->mac_context)) != 0) {
+	    cname = STR(vstring_sprintf(canon_buf, "{%s}", name));
+	else
+	    cname = name;
+	if ((value = milters->mac_lookup(cname, milters->mac_context)) != 0) {
 	    if (msg_verbose)
 		msg_info("%s: result \"%s\"", myname, value);
 	    argv_add(argv, name, value, (char *) 0);
 	} else if (milters->macro_defaults != 0
-	     && (value = htable_find(milters->macro_defaults, name)) != 0) {
+	    && (value = htable_find(milters->macro_defaults, cname)) != 0) {
 	    if (msg_verbose)
 		msg_info("%s: using default \"%s\"", myname, value);
 	    argv_add(argv, name, value, (char *) 0);
diff -Nru postfix-3.1.4/src/util/dict_db.c postfix-3.1.6/src/util/dict_db.c
--- postfix-3.1.4/src/util/dict_db.c	2014-12-06 20:35:33.000000000 -0500
+++ postfix-3.1.6/src/util/dict_db.c	2017-06-13 12:15:32.000000000 -0400
@@ -122,6 +122,9 @@
 typedef struct {
     DICT    dict;			/* generic members */
     DB     *db;				/* open db file */
+#if DB_VERSION_MAJOR > 2
+    DB_ENV *dbenv;
+#endif
 #if DB_VERSION_MAJOR > 1
     DBC    *cursor;			/* dict_db_sequence() */
 #endif
@@ -553,6 +556,9 @@
     if (DICT_DB_CLOSE(dict_db->db) < 0)
 	msg_info("close database %s: %m (possible Berkeley DB bug)",
 		 dict_db->dict.name);
+#if DB_VERSION_MAJOR > 2
+    dict_db->dbenv->close(dict_db->dbenv, 0);
+#endif
     if (dict_db->key_buf)
 	vstring_free(dict_db->key_buf);
     if (dict_db->val_buf)
@@ -562,6 +568,44 @@
     dict_free(dict);
 }
 
+#if DB_VERSION_MAJOR > 2
+
+/* dict_db_new_env - workaround for undocumented ./DB_CONFIG read */
+
+static DB_ENV *dict_db_new_env(const char *db_path)
+{
+    VSTRING *db_home_buf;
+    DB_ENV *dbenv;
+    u_int32_t cache_size_gbytes;
+    u_int32_t cache_size_bytes;
+    int     ncache;
+
+    if ((errno = db_env_create(&dbenv, 0)) != 0)
+	msg_fatal("create DB environment: %m");
+#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 7)
+    if ((errno = dbenv->get_cachesize(dbenv, &cache_size_gbytes,
+				      &cache_size_bytes, &ncache)) != 0)
+	msg_fatal("get DB cache size: %m");
+    if (cache_size_gbytes == 0 && cache_size_bytes < dict_db_cache_size) {
+	if ((errno = dbenv->set_cache_max(dbenv, cache_size_gbytes,
+					  dict_db_cache_size)) != 0)
+	    msg_fatal("set DB max cache size %d: %m", dict_db_cache_size);
+	if ((errno = dbenv->set_cachesize(dbenv, cache_size_gbytes,
+					  dict_db_cache_size, ncache)) != 0)
+	    msg_fatal("set DB cache size %d: %m", dict_db_cache_size);
+    }
+#endif
+    /* XXX db_home is also the default directory for the .db file. */
+    db_home_buf = vstring_alloc(100);
+    if ((errno = dbenv->open(dbenv, sane_dirname(db_home_buf, db_path),
+			   DB_INIT_MPOOL | DB_CREATE | DB_PRIVATE, 0)) != 0)
+	msg_fatal("open DB environment: %m");
+    vstring_free(db_home_buf);
+    return (dbenv);
+}
+
+#endif
+
 /* dict_db_open - open data base */
 
 static DICT *dict_db_open(const char *class, const char *path, int open_flags,
@@ -578,6 +622,10 @@
     int     db_flags;
 
 #endif
+#if DB_VERSION_MAJOR > 2
+    DB_ENV *dbenv;
+
+#endif
 
     /*
      * Mismatches between #include file and library are a common cause for
@@ -681,12 +729,10 @@
 	db_flags |= DB_CREATE;
     if (open_flags & O_TRUNC)
 	db_flags |= DB_TRUNCATE;
-    if ((errno = db_create(&db, 0, 0)) != 0)
+    if ((errno = db_create(&db, dbenv = dict_db_new_env(db_path), 0)) != 0)
 	msg_fatal("create DB database: %m");
     if (db == 0)
 	msg_panic("db_create null result");
-    if ((errno = db->set_cachesize(db, 0, dict_db_cache_size, 0)) != 0)
-	msg_fatal("set DB cache size %d: %m", dict_db_cache_size);
     if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0)
 	msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM);
 #if DB_VERSION_MAJOR == 6 || DB_VERSION_MAJOR == 5 || \
@@ -743,6 +789,9 @@
     if (dict_flags & DICT_FLAG_FOLD_FIX)
 	dict_db->dict.fold_buf = vstring_alloc(10);
     dict_db->db = db;
+#if DB_VERSION_MAJOR > 2
+    dict_db->dbenv = dbenv;
+#endif
 #if DB_VERSION_MAJOR > 1
     dict_db->cursor = 0;
 #endif
diff -Nru postfix-3.1.4/src/util/vstring.c postfix-3.1.6/src/util/vstring.c
--- postfix-3.1.4/src/util/vstring.c	2016-02-14 09:26:22.000000000 -0500
+++ postfix-3.1.6/src/util/vstring.c	2017-06-10 17:05:51.000000000 -0400
@@ -280,6 +280,10 @@
 #include "vbuf_print.h"
 #include "vstring.h"
 
+#ifndef SSIZE_T_MAX
+#define SSIZE_T_MAX __MAXINT__(ssize_t)
+#endif
+
 /* vstring_extend - variable-length string buffer extension policy */
 
 static void vstring_extend(VBUF *bp, ssize_t incr)
@@ -299,10 +303,13 @@
      * (The tests are redundant as long as mymalloc() and myrealloc() reject
      * negative length parameters).
      */
-    new_len = bp->len + (bp->len > incr ? bp->len : incr);
-    if (new_len <= bp->len)
+    if (bp->len > incr)
+	incr = bp->len;
+    if (bp->len > SSIZE_T_MAX - incr - 1)
 	msg_fatal("vstring_extend: length overflow");
-    bp->data = (unsigned char *) myrealloc((void *) bp->data, new_len);
+    new_len = bp->len + incr;
+    bp->data = (unsigned char *) myrealloc((void *) bp->data, new_len + 1);
+    bp->data[new_len] = 0;
     bp->len = new_len;
     bp->ptr = bp->data + used;
     bp->cnt = bp->len - used;
@@ -342,12 +349,13 @@
 {
     VSTRING *vp;
 
-    if (len < 1)
+    if (len < 1 || len > SSIZE_T_MAX - 1)
 	msg_panic("vstring_alloc: bad length %ld", (long) len);
     vp = (VSTRING *) mymalloc(sizeof(*vp));
     vp->vbuf.flags = 0;
     vp->vbuf.len = 0;
-    vp->vbuf.data = (unsigned char *) mymalloc(len);
+    vp->vbuf.data = (unsigned char *) mymalloc(len + 1);
+    vp->vbuf.data[len] = 0;
     vp->vbuf.len = len;
     VSTRING_RESET(vp);
     vp->vbuf.data[0] = 0;

Reply via email to