Prereq: "2.11.9" diff -cr --new-file /var/tmp/postfix-2.11.9/src/global/mail_version.h ./src/global/mail_version.h *** /var/tmp/postfix-2.11.9/src/global/mail_version.h 2016-12-31 19:49:42.000000000 -0500 --- ./src/global/mail_version.h 2017-06-13 13:35:10.000000000 -0400 *************** *** 20,27 **** * 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 "2.11.9" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE --- 20,27 ---- * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ ! #define MAIL_RELEASE_DATE "20170613" ! #define MAIL_VERSION_NUMBER "2.11.10" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff -cr --new-file /var/tmp/postfix-2.11.9/HISTORY ./HISTORY *** /var/tmp/postfix-2.11.9/HISTORY 2016-12-31 19:40:34.000000000 -0500 --- ./HISTORY 2017-06-13 13:34:26.000000000 -0400 *************** *** 19780,19782 **** --- 19780,19795 ---- 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. + + 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 -cr --new-file /var/tmp/postfix-2.11.9/src/util/dict_db.c ./src/util/dict_db.c *** /var/tmp/postfix-2.11.9/src/util/dict_db.c 2012-01-24 19:41:08.000000000 -0500 --- ./src/util/dict_db.c 2017-06-13 12:19:33.000000000 -0400 *************** *** 116,121 **** --- 116,124 ---- 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 *************** *** 558,563 **** --- 561,569 ---- 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) *************** *** 567,572 **** --- 573,616 ---- 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, *************** *** 583,588 **** --- 627,636 ---- int db_flags; #endif + #if DB_VERSION_MAJOR > 2 + DB_ENV *dbenv; + + #endif /* * Mismatches between #include file and library are a common cause for *************** *** 685,696 **** db_flags |= DB_CREATE; if (open_flags & O_TRUNC) db_flags |= DB_TRUNCATE; ! if ((errno = db_create(&db, 0, 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 == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0) --- 733,742 ---- db_flags |= DB_CREATE; if (open_flags & O_TRUNC) db_flags |= DB_TRUNCATE; ! 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 (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 == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0) *************** *** 745,750 **** --- 791,799 ---- 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