]> git.notmuchmail.org Git - notmuch/commitdiff
lib/open: fix potential double-free, ensure *database=NULL on error
authorDavid Bremner <david@tethera.net>
Sat, 23 Oct 2021 13:22:34 +0000 (10:22 -0300)
committerDavid Bremner <david@tethera.net>
Sat, 30 Oct 2021 16:43:58 +0000 (13:43 -0300)
During refactoring for 0.32, the code that set notmuch=NULL on various
errors was moved into _finish_open. This meant that the the code which
relied on that to set *database to NULL on error was no longer
correct. It also introduced a potential double free, since the notmuch
struct was deallocated inside _finish_open (via n_d_destroy).

In this commit we revert to "allocator frees", and leave any cleanup
to the caller of _finish_open. This allows us to get back the
behaviour of setting *database to NULL with a small change. Other
callers of _finish_open will need free notmuch on errors.

lib/open.cc
test/T590-libconfig.sh

index 8a835e986d5dd78661eba0a53e793b288550b083..77f01f727b6bdae860e4f7c84ce22c6af99e3a91 100644 (file)
@@ -396,8 +396,6 @@ _finish_open (notmuch_database_t *notmuch,
                                     "       has a newer database format version (%u) than supported by this\n"
                                     "       version of notmuch (%u).\n",
                                     database_path, version, NOTMUCH_DATABASE_VERSION));
                                     "       has a newer database format version (%u) than supported by this\n"
                                     "       version of notmuch (%u).\n",
                                     database_path, version, NOTMUCH_DATABASE_VERSION));
-           notmuch_database_destroy (notmuch);
-           notmuch = NULL;
            status = NOTMUCH_STATUS_FILE_ERROR;
            goto DONE;
        }
            status = NOTMUCH_STATUS_FILE_ERROR;
            goto DONE;
        }
@@ -414,8 +412,6 @@ _finish_open (notmuch_database_t *notmuch,
                                     "       requires features (%s)\n"
                                     "       not supported by this version of notmuch.\n",
                                     database_path, incompat_features));
                                     "       requires features (%s)\n"
                                     "       not supported by this version of notmuch.\n",
                                     database_path, incompat_features));
-           notmuch_database_destroy (notmuch);
-           notmuch = NULL;
            status = NOTMUCH_STATUS_FILE_ERROR;
            goto DONE;
        }
            status = NOTMUCH_STATUS_FILE_ERROR;
            goto DONE;
        }
@@ -489,8 +485,6 @@ _finish_open (notmuch_database_t *notmuch,
     } catch (const Xapian::Error &error) {
        IGNORE_RESULT (asprintf (&message, "A Xapian exception occurred opening database: %s\n",
                                 error.get_msg ().c_str ()));
     } catch (const Xapian::Error &error) {
        IGNORE_RESULT (asprintf (&message, "A Xapian exception occurred opening database: %s\n",
                                 error.get_msg ().c_str ()));
-       notmuch_database_destroy (notmuch);
-       notmuch = NULL;
        status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
     }
   DONE:
        status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
     }
   DONE:
@@ -559,10 +553,13 @@ notmuch_database_open_with_config (const char *database_path,
            free (message);
     }
 
            free (message);
     }
 
+    if (status && notmuch) {
+       notmuch_database_destroy (notmuch);
+       notmuch = NULL;
+    }
+
     if (database)
        *database = notmuch;
     if (database)
        *database = notmuch;
-    else
-       talloc_free (notmuch);
 
     if (notmuch)
        notmuch->open = true;
 
     if (notmuch)
        notmuch->open = true;
index 79bf5805d0a8b7d55d9710764f03698c0d9bffa5..32ec072a2f39296f7be405cb7f070ffbd6f71fff 100755 (executable)
@@ -862,7 +862,6 @@ cat <<EOF > c_tail3
 EOF
 
 test_begin_subtest "open: database set to null on missing config"
 EOF
 
 test_begin_subtest "open: database set to null on missing config"
-test_subtest_known_broken
 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
                                                          NOTMUCH_DATABASE_MODE_READ_ONLY,
 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
   notmuch_status_t st = notmuch_database_open_with_config(argv[1],
                                                          NOTMUCH_DATABASE_MODE_READ_ONLY,
@@ -876,7 +875,6 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "open: database set to null on missing config (env)"
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "open: database set to null on missing config (env)"
-test_subtest_known_broken
 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
 NOTMUCH_CONFIG="/nonexistent"
 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}
 old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
 NOTMUCH_CONFIG="/nonexistent"
 cat c_head3 - c_tail3 <<'EOF' | test_C ${MAIL_DIR}