From bcf18940688449cc9100fce44dd81c6f7f447d95 Mon Sep 17 00:00:00 2001 From: BAder82t <41265463+BAder82t@users.noreply.github.com> Date: Mon, 20 Apr 2026 02:30:02 +0200 Subject: [PATCH] fix: use-after-realloc in addManyNumbers (#517) ct_ptr is captured before the loop, but three4Two() can resize the NTL::Vec it points into, invalidating the pointer. Later iterations then read freed memory on ct_ptr->getContext().BPL(). Cache the threshold (3 * BPL()) before the loop and drop ct_ptr. Closes #517 --- src/binaryArith.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/binaryArith.cpp b/src/binaryArith.cpp index 6b90c34a6..7859b3c80 100644 --- a/src/binaryArith.cpp +++ b/src/binaryArith.cpp @@ -914,6 +914,12 @@ void addManyNumbers(CtPtrs& sum, bool bootstrappable = ct_ptr->getPubKey().isBootstrappable(); const EncryptedArray& ea = ct_ptr->getContext().getEA(); + // Cache the bit-per-level threshold before the loop: three4Two below may + // resize the NTL::Vec that ct_ptr points into, reallocating the + // underlying storage and leaving ct_ptr dangling. Dereferencing ct_ptr + // on a later iteration then reads freed memory (issue #517). + const long minCapacityThreshold = 3 * ct_ptr->getContext().BPL(); + ct_ptr = nullptr; long leftInQ = lsize(numbers); std::vector numPtrs(leftInQ); @@ -924,7 +930,7 @@ void addManyNumbers(CtPtrs& sum, while (leftInQ > 2) { // If any number is too low level, then bootstrap everything PtrMatrix_PtPtrVector wrapper(numPtrs); - if (findMinBitCapacity(wrapper) < 3 * ct_ptr->getContext().BPL()) { + if (findMinBitCapacity(wrapper) < minCapacityThreshold) { assertNotNull(unpackSlotEncoding, "unpackSlotEncoding must not be null"); assertTrue(bootstrappable,