`PrimeSieveBig()` can access past the final bucket at segment boundaries
@jwood000 is already working on this.
Since Oct 31, 2026.
Assessment
This issue has not been assessed yet.
Description
PrimeSieveBig() can schedule a composite beyond the requested upper bound into a bucket that does not exist, causing undefined behavior.
In
myRange includes the final requested position:
const int myRange = (maxNum - lowerBnd) + 1;
However, scheduling permits idx <= myRange + 1. The final valid requested offset is myRange - 1. Near a segment boundary, those extra positions can produce divTest == numCacheSegs, followed by an invalid access:
myBuckets[divTest].push_back(idx);
Reproduction
The following standalone program reproduces the problem using fixed thread/cache parameters:
#include "src/Eratosthenes.cpp"
int main() {
std::vector<std::vector<double>> chunks(1);
std::vector<double> output;
bool parallel = false;
PrimeSieve::PrimeSieveMain(
chunks, output,
1037517761278999LL, 1037517761279999LL,
parallel, 1, 10, 1
);
}
Save as /tmp/sieve-bucket-repro.cpp, then compile and run from the repository root:
clang++ -std=c++11 -O1 -g \
-fsanitize=address,undefined -fno-omit-frame-pointer \
-I. -Iinst/include /tmp/sieve-bucket-repro.cpp \
-o /tmp/sieve-bucket-repro
/tmp/sieve-bucket-repro
Apple Clang 17 with AddressSanitizer confirmed a container-overflow in this native path.
Why this input triggers it
- The segment size is 19,219,200, and one bucket is allocated.
- The requested maximum has segment-relative offset
segSize - 1. - The sieving prime 10,000,019 schedules the multiple
10000019 × 103751579 = 1037517761280001. - That multiple has offset
segSize + 1, which the current limit admits. - The resulting access is
myBuckets[1], although only bucket0exists.
Public R dispatch depends on detected core/thread settings, so the native reproduction fixes those parameters explicitly.
Expected behavior and follow-up
- Restrict scheduling to the inclusive requested interval and allocated buckets.
- Add regression coverage around aligned final-segment boundaries.
- Verify expected output and run the regression under sanitizers.
- Keep this correctness fix separate from sieve performance changes.
- Dominant language
- C++
- Stars
- 51
- Forks
- 5
- Avg merge
- 5h 49m
- Merged PRs (30d)
- 7
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from jwood000/RcppAlgos
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
-
Non-repeated and non-duplicated combinations from groups with varying sizes that contain overlapsOpenenhancement
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
Multiset partitionsOpen
Difficulty 3/5 1-2 days Newbie friendliness 30/100
-
Combinatorial Iterators not working parallelMay be free again @jwood000 claimed this 1696 days ago, and no pull request is open. Openenhancement
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
All issues in jwood000/RcppAlgos
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
ROCm/AMDMIGraphX#5490 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
arvidn/libtorrent#9126 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Sunrisepeak/mcpp-language-server#80 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
xiaoyifang/goldendict-ng#3148 ·
Maintainers usually reply within 1 day