gnucash stable: xaccAccountDeleteAllTransactions: Avoid UAF crashes

John Ralls jralls at code.gnucash.org
Fri Mar 7 18:46:29 EST 2025


Updated	 via  https://github.com/Gnucash/gnucash/commit/90662d72 (commit)
	from  https://github.com/Gnucash/gnucash/commit/0e15e12e (commit)



commit 90662d72a2857cbc1300bc8c5f8a526cd296b784
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 7 15:42:17 2025 -0800

    xaccAccountDeleteAllTransactions: Avoid UAF crashes
    
    Chris Lam pointed out that the original algo would crash if a
    transaction had more than one split in the account being deleted.
    Deduplicate the transaction vector first to protect against that.
    
    Also suspend qof events for a 4x speedup.

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 5de4ec04b8..1228dec8ab 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -42,6 +42,7 @@
 #include "gnc-glib-utils.h"
 #include "gnc-lot.h"
 #include "gnc-pricedb.h"
+#include "qofevent.h"
 #include "qofinstance-p.h"
 #include "gnc-features.h"
 #include "guid.hpp"
@@ -1602,11 +1603,17 @@ xaccAccountDestroyAllTransactions(Account *acc)
 {
     auto priv = GET_PRIVATE(acc);
     std::vector<Transaction*> transactions;
+    transactions.reserve(priv->splits.size());
     std::transform(priv->splits.begin(), priv->splits.end(),
                    back_inserter(transactions),
                    [](auto split) { return split->parent; });
+    std::stable_sort(transactions.begin(), transactions.end());
+    transactions.erase(std::unique(transactions.begin(), transactions.end()),
+                       transactions.end());
+    qof_event_suspend();
     std::for_each(transactions.rbegin(), transactions.rend(),
                   [](auto trans) { xaccTransDestroy (trans); });
+    qof_event_resume();
 }
 
 /********************************************************************\
@@ -4621,7 +4628,7 @@ xaccAccountSetReconcilePostponeBalance (Account *acc, gnc_numeric balance)
 void
 xaccAccountClearReconcilePostpone (Account *acc)
 {
-    set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE}, {});
+    set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE, "balance"}, {});
 }
 
 /********************************************************************\



Summary of changes:
 libgnucash/engine/Account.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)



More information about the gnucash-changes mailing list