]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.2.2 v3.2.2
authorWietse Venema <wietse@porcupine.org>
Tue, 13 Jun 2017 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Wed, 12 Jul 2017 05:44:03 +0000 (01:44 -0400)
postfix/HISTORY
postfix/src/global/mail_version.h
postfix/src/util/dict_db.c

index a17ec44873779331608a64c1bf99466f05382b15..9a8d3c4f629b57af9692a50735469cd93f9e503c 100644 (file)
@@ -22979,3 +22979,16 @@ Apologies for any names omitted.
        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.
index 2e0859b386ae6678c9fe46b297a3d5a085d1f934..eac42079954e514c585139b0935a47a772fb66c0 100644 (file)
@@ -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      "20170610"
-#define MAIL_VERSION_NUMBER    "3.2.1"
+#define MAIL_RELEASE_DATE      "20170613"
+#define MAIL_VERSION_NUMBER    "3.2.2"
 
 #ifdef SNAPSHOT
 #define MAIL_VERSION_DATE      "-" MAIL_RELEASE_DATE
index f45034b64ff2a7373c71175029ef2060c6602718..e3d34106074245fea278acf5758b54b8f7e9386d 100644 (file)
 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 @@ static void dict_db_close(DICT *dict)
     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 @@ static void dict_db_close(DICT *dict)
     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,
@@ -577,6 +621,10 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
 #if DB_VERSION_MAJOR > 1
     int     db_flags;
 
+#endif
+#if DB_VERSION_MAJOR > 2
+    DB_ENV *dbenv;
+
 #endif
 
     /*
@@ -681,12 +729,10 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
        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 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
     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