]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.12-20260721 master
authorWietse Z Venema <wietse@porcupine.org>
Tue, 21 Jul 2026 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Wed, 22 Jul 2026 14:34:08 +0000 (00:34 +1000)
postfix/HISTORY
postfix/src/global/mail_version.h
postfix/src/nbdb_reindexd/nbdb_process.c
postfix/src/nbdb_reindexd/nbdb_process_test.c
postfix/src/testing/mock_servent.c
postfix/src/util/binhash.c
postfix/src/util/find_inet_service.c

index 0163698c017c5072e60b60c68c3b72595c988dcc..f935fa78ae0e6fda671d715c6ef35f3c889f399d 100644 (file)
@@ -31771,7 +31771,7 @@ Apologies for any names omitted.
        exists. Reported by Qualys, assisted by Claude Mythos
        Preview. File: pipe.c.
 
-20260720:
+20260720
 
        Bug (defect introduced: Postfix 1,1, date: 20010524): the
        postsuper command over-read a very short queue filename.
@@ -31804,6 +31804,25 @@ Apologies for any names omitted.
        service. Files: nbdb_safe.c, nbdb_safe.h, nbdb_safe_test.c,
        nbdb_process_test.c.
 
+20260721
+
+       Hardening: in the non-BerkeleyDB migration service, delay
+       the decision between running postmap or postalias until
+       after the database file/directory owner/permission checks.
+       The benefit from making the decision early (better error
+       messages) was not worth the risk. Qualys, assisted by Claude
+       Mythos Preview. Files: nbdb_process.c, nbdb_process_test.c.
+
+       Back-port htable fixes to binhash tables: 1) segfault in
+       the binhash first/next iterator when a table contains one
+       element; 2) technical debt: allow an element to be deleted
+       after the binhash table's first/next iterator has started,
+       but before it has visited the element; 3) don't free null
+       data pointers. File: util/binhash.c.
+
+       Code health: missing <arpa/inet> includes. Files:
+       testing/mock_servent.c, util/find_inet_service.c.
+
 TODO
 
        Reorganize PTEST_LIB, PMOCK_LIB, TESTLIB, TESTLIBS, etc.
index bd20a5f2eff80acb1592424bd9f244c1ee5f020a..25f9cb49c9f6942099c9b175f772f8a9facde3ea 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20260720"
+#define MAIL_RELEASE_DATE      "20260721"
 #define MAIL_VERSION_NUMBER    "3.12"
 
 #ifdef SNAPSHOT
index 2ddcd4bf94739c043694050febcdc18283142967..cd312add209a96b2190614aee4646b40a413beec 100644 (file)
@@ -170,19 +170,6 @@ int     nbdb_process(const char *leg_type, const char *source_path,
        return (NBDB_STAT_ERROR);
     }
 
-    /*
-     * Should we run postmap or postalias? Open the source file with the same
-     * (uid, gid) as the postmap or postalias commands would, so that we can
-     * detect permission errors quickly.
-     * 
-     * Note: we do this before the file allowlist/owner/permission safety
-     * checks, so that we can log the concrete postmap or postalias command
-     * if a safety check fails.
-     */
-    if ((index_cmd = nbdb_get_index_cmd_as(source_path, leg_idx_st.st_uid,
-                                          leg_idx_st.st_gid, why)) == 0)
-       return (NBDB_STAT_ERROR);
-
     /*
      * Allow indexing as the legacy indexed file owner if it is considered
      * "safe".
@@ -190,7 +177,18 @@ int     nbdb_process(const char *leg_type, const char *source_path,
     if (!nbdb_safe_to_index_as_legacy_index_owner(source_path, &source_st,
                                             STR(leg_idx_path), &leg_idx_st,
                                         parent_dir, &parent_dir_st, why)) {
-       status = NBDB_STAT_ERROR;
+       return (NBDB_STAT_ERROR);
+    }
+
+    /*
+     * Should we run postmap or postalias? Open the source file with the same
+     * (uid, gid) as the postmap or postalias commands would, so that we can
+     * detect permission errors quickly. 202607 Qualys+Mythos: move this
+     * after the safety checks.
+     */
+    if ((index_cmd = nbdb_get_index_cmd_as(source_path, leg_idx_st.st_uid,
+                                          leg_idx_st.st_gid, why)) == 0) {
+       return (NBDB_STAT_ERROR);
     }
 
     /*
index 6659d2568f37115e9ed033d8edf2de2b192ce1b9..1b8c5f94629e4f1ef1ad8008555f3e3475c64d9a 100644 (file)
@@ -505,7 +505,7 @@ static const TEST_CASE test_cases[] = {
            .in_new_type = "hash",
            .in_source_path = "/path/to/file",
            .want_status = NBDB_STAT_ERROR,
-           .want_why = "could not execute command 'postmap cdb:/path/to/file': table /path/to/file has an unexpected pathname",
+           .want_why = "table /path/to/file has an unexpected pathname",
        },
     },
 
index bd3d4c09073cdd93d18dd35629470cbf2642a4ae..94514c70423cef472b1c83626d6c8ca092e6326e 100644 (file)
@@ -96,6 +96,7 @@
   * System library.
   */
 #include <sys_defs.h>
+#include <arpa/inet.h>
 #include <wrap_netdb.h>
 #include <string.h>
 
index 0383a899a00ba4ef3c4ee7d8193e56acd1b824d8..bd2ade50240fb34b38c739c35b9e29ff84668f8b 100644 (file)
 /*     depending on the value of the "how" argument. Specify
 /*     BINHASH_SEQ_FIRST to start a new sequence, BINHASH_SEQ_NEXT
 /*     to continue, and BINHASH_SEQ_STOP to terminate a sequence
-/*     early. The caller must not delete an element before it is
-/*     visited.
+/*     early.
 /* RESTRICTIONS
 /*     A callback function should not modify the hash table that is
 /*     specified to its caller.
@@ -278,7 +277,7 @@ BINHASH_INFO *binhash_locate(BINHASH *table, const void *key, ssize_t key_len)
 void    binhash_delete(BINHASH *table, const void *key, ssize_t key_len, void (*free_fn) (void *))
 {
     if (table != 0) {
-       BINHASH_INFO *ht;
+       BINHASH_INFO *ht, **sp;
        BINHASH_INFO **h = table->data + binhash_hash(key, key_len, table->size);
 
        for (ht = *h; ht; ht = ht->next) {
@@ -291,9 +290,17 @@ void    binhash_delete(BINHASH *table, const void *key, ssize_t key_len, void (*
                    *h = ht->next;
                table->used--;
                myfree(ht->key);
-               if (free_fn)
+               if (free_fn && ht->value)
                    (*free_fn) (ht->value);
                myfree((void *) ht);
+               /* In case the first/next iterator has not yet visited it */
+               for (sp = table->seq_element; sp && *sp; sp++) {
+                   if (*sp == ht) {
+                       while ((*sp = sp[1]) != 0)
+                           sp += 1;
+                       break;
+                   }
+               }
                return;
            }
        }
@@ -315,7 +322,7 @@ void    binhash_free(BINHASH *table, void (*free_fn) (void *))
            for (ht = *h++; ht; ht = next) {
                next = ht->next;
                myfree(ht->key);
-               if (free_fn)
+               if (free_fn && ht->value)
                    (*free_fn) (ht->value);
                myfree((void *) ht);
            }
@@ -378,7 +385,7 @@ BINHASH_INFO *binhash_sequence(BINHASH *table, int how)
            myfree((void *) table->seq_bucket);
        table->seq_bucket = binhash_list(table);
        table->seq_element = table->seq_bucket;
-       return (*(table->seq_element)++);
+       /* FALLTHROUGH */
     case BINHASH_SEQ_NEXT:                     /* next element */
        if (table->seq_element && *table->seq_element)
            return (*(table->seq_element)++);
@@ -439,6 +446,18 @@ int     main(int unused_argc, char **unused_argv)
        msg_panic("%ld entries not deleted", (long) hash->used);
     myfree((void *) ht_info);
     binhash_free(hash, (void (*) (void *)) 0);
+
+    /* Iterate one-element table. */
+    hash = binhash_create(10);
+       binhash_enter(hash, "one", 4, "one");
+    if( binhash_sequence(hash,BINHASH_SEQ_FIRST) == 0)
+       msg_panic("one-element iterator BINHASH_SEQ_FIRST");
+    if (binhash_sequence(hash,BINHASH_SEQ_NEXT) != 0)
+       msg_panic("one-element iterator BINHASH_SEQ_NEXT");
+    binhash_free(hash, (void (*) (void *)) 0);
+
+    /* TODO: Delete element before it is visited by iterator. */
+
     vstring_free(buf);
     return (0);
 }
index 29948c1b80e625a3677c8c3cc9555ce09ac2211f..2a6aeedd2c3f83be1a24c38827ab216a195732f0 100644 (file)
@@ -32,6 +32,7 @@
 /* System libraries. */
 
 #include <sys_defs.h>
+#include <arpa/inet.h>
 #include <wrap_netdb.h>
 #include <stdlib.h>
 #include <string.h>