From b6721ab6b01e58b8802163a16e9652b7edd048d8 Mon Sep 17 00:00:00 2001 From: Stefan van Kessel Date: Wed, 4 Oct 2023 06:21:36 +0200 Subject: [PATCH] fix: asan stack-use-after-scope in soci::use with rvalues (#4676) Address a stack-use-after-scope issue when using rvalues with `soci::use`. Replace rvalues with lvalues to ensure the scope extends beyond the end of the expression. The issue arises from `soci` taking a reference to the rvalue without copying its value or extending its lifetime. `soci` references rvalues in `soci::use_container` and then the address in `soci_use_type`. For types like `int`, memory access post-lifetime is unlikely to cause issues. However, for `std::string`, the backing heap memory can be freed and potentially reused, leading to a potential segmentation fault. This was detected on x86_64 using clang-15 with asan. asan confirms resolution of the issue. Fix #4675 --- src/ripple/app/rdb/impl/UnitaryShard.cpp | 12 +++++++----- src/ripple/app/rdb/impl/Wallet.cpp | 7 ++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/ripple/app/rdb/impl/UnitaryShard.cpp b/src/ripple/app/rdb/impl/UnitaryShard.cpp index 37cbfd55ac3..ab1758b4852 100644 --- a/src/ripple/app/rdb/impl/UnitaryShard.cpp +++ b/src/ripple/app/rdb/impl/UnitaryShard.cpp @@ -175,6 +175,11 @@ updateLedgerDBs( auto const sParentHash{to_string(ledger->info().parentHash)}; auto const sDrops{to_string(ledger->info().drops)}; + auto const closingTime{ + ledger->info().closeTime.time_since_epoch().count()}; + auto const prevClosingTime{ + ledger->info().parentCloseTime.time_since_epoch().count()}; + auto const closeTimeRes{ledger->info().closeTimeResolution.count()}; auto const sAccountHash{to_string(ledger->info().accountHash)}; auto const sTxHash{to_string(ledger->info().txHash)}; @@ -190,11 +195,8 @@ updateLedgerDBs( ":closingTime, :prevClosingTime, :closeTimeRes," ":closeFlags, :accountSetHash, :transSetHash);", soci::use(sHash), soci::use(ledgerSeq), soci::use(sParentHash), - soci::use(sDrops), - soci::use(ledger->info().closeTime.time_since_epoch().count()), - soci::use( - ledger->info().parentCloseTime.time_since_epoch().count()), - soci::use(ledger->info().closeTimeResolution.count()), + soci::use(sDrops), soci::use(closingTime), + soci::use(prevClosingTime), soci::use(closeTimeRes), soci::use(ledger->info().closeFlags), soci::use(sAccountHash), soci::use(sTxHash); diff --git a/src/ripple/app/rdb/impl/Wallet.cpp b/src/ripple/app/rdb/impl/Wallet.cpp index 25a06bbd97a..3715c4c7458 100644 --- a/src/ripple/app/rdb/impl/Wallet.cpp +++ b/src/ripple/app/rdb/impl/Wallet.cpp @@ -205,19 +205,20 @@ insertPeerReservation( PublicKey const& nodeId, std::string const& description) { + auto const sNodeId = toBase58(TokenType::NodePublic, nodeId); session << "INSERT INTO PeerReservations (PublicKey, Description) " "VALUES (:nodeId, :desc) " "ON CONFLICT (PublicKey) DO UPDATE SET " "Description=excluded.Description", - soci::use(toBase58(TokenType::NodePublic, nodeId)), - soci::use(description); + soci::use(sNodeId), soci::use(description); } void deletePeerReservation(soci::session& session, PublicKey const& nodeId) { + auto const sNodeId = toBase58(TokenType::NodePublic, nodeId); session << "DELETE FROM PeerReservations WHERE PublicKey = :nodeId", - soci::use(toBase58(TokenType::NodePublic, nodeId)); + soci::use(sNodeId); } bool