From 91f683a9994e02c29f85cd3aede807bb6ebee93f Mon Sep 17 00:00:00 2001 From: tequ Date: Mon, 30 Jun 2025 13:17:24 +0900 Subject: [PATCH] add sanity checks --- src/ripple/app/hook/impl/applyHook.cpp | 14 ++++++++++++++ src/ripple/app/tx/impl/SetHook.cpp | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/ripple/app/hook/impl/applyHook.cpp b/src/ripple/app/hook/impl/applyHook.cpp index f600af44a..94e4b87b6 100644 --- a/src/ripple/app/hook/impl/applyHook.cpp +++ b/src/ripple/app/hook/impl/applyHook.cpp @@ -1521,6 +1521,11 @@ set_state_cache( stateMap.modified_entry_count++; + // sanity check + if (view.rules().enabled(featureExtendedHookState) && + availableForReserves < hookStateScale) + return INTERNAL_ERROR; + stateMap[acc] = { availableForReserves - hookStateScale, namespaceCount, @@ -1555,6 +1560,10 @@ set_state_cache( namespaceCount++; } + if (view.rules().enabled(featureExtendedHookState) && + availableForReserves < hookStateScale) + return INTERNAL_ERROR; + availableForReserves -= hookStateScale; stateMap.modified_entry_count++; } @@ -1572,6 +1581,11 @@ set_state_cache( { if (!canReserveNew) return RESERVE_INSUFFICIENT; + + if (view.rules().enabled(featureExtendedHookState) && + availableForReserves < hookStateScale) + return INTERNAL_ERROR; + availableForReserves -= hookStateScale; stateMap.modified_entry_count++; } diff --git a/src/ripple/app/tx/impl/SetHook.cpp b/src/ripple/app/tx/impl/SetHook.cpp index 150897e9d..d2378d894 100644 --- a/src/ripple/app/tx/impl/SetHook.cpp +++ b/src/ripple/app/tx/impl/SetHook.cpp @@ -924,6 +924,15 @@ SetHook::destroyNamespace( view.erase(sleItem); } + if (view.rules().enabled(featureExtendedHookState) && + oldStateCount < toDelete.size()) + { + JLOG(ctx.j.fatal()) << "HookSet(" << hook::log::NSDELETE_COUNT << ")[" + << HS_ACC() << "]: DeleteState " + << "stateCount less than zero (overflow)"; + return tefBAD_LEDGER; + } + uint32_t stateCount = oldStateCount - toDelete.size(); if (stateCount > oldStateCount) { @@ -940,7 +949,18 @@ SetHook::destroyNamespace( sleAccount->setFieldU32(sfHookStateCount, stateCount); if (ctx.rules.enabled(fixNSDelete)) + { + auto const ownerCount = sleAccount->getFieldU32(sfOwnerCount); + if (view.rules().enabled(featureExtendedHookState) && + ownerCount < toDelete.size() * scale) + { + JLOG(ctx.j.fatal()) << "HookSet(" << hook::log::NSDELETE_COUNT + << ")[" << HS_ACC() << "]: DeleteState " + << "OwnerCount less than zero (overflow)"; + return tefBAD_LEDGER; + } adjustOwnerCount(view, sleAccount, -toDelete.size() * scale, ctx.j); + } if (!partialDelete && sleAccount->isFieldPresent(sfHookNamespaces)) hook::removeHookNamespaceEntry(*sleAccount, ns);