From 07e2ab0158b3ed1bbd5aae5538f65fd6bce86bec Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Tue, 13 Jun 2017 00:00:00 -0500 Subject: [PATCH] postfix-2.11.10 --- postfix/HISTORY | 13 ++++++++ postfix/src/global/mail_version.h | 4 +-- postfix/src/util/dict_db.c | 55 +++++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/postfix/HISTORY b/postfix/HISTORY index 7738a494f..11f035d93 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -19780,3 +19780,16 @@ Apologies for any names omitted. 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 --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 204708171..2f918db54 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "2.11.9" +#define MAIL_RELEASE_DATE "20170613" +#define MAIL_VERSION_NUMBER "2.11.10" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff --git a/postfix/src/util/dict_db.c b/postfix/src/util/dict_db.c index 93ee48098..9a3c53dd0 100644 --- a/postfix/src/util/dict_db.c +++ b/postfix/src/util/dict_db.c @@ -116,6 +116,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 @@ -558,6 +561,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) @@ -567,6 +573,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, @@ -582,6 +626,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 /* @@ -685,12 +733,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 == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0) @@ -745,6 +791,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