Summary
All four overloads of Filter::ApplyStencil only clamp ncomp against the total number of components in the source MultiFab/FArrayBox (Filter/Filter.cpp:41,82,201,255). When callers pass a non-zero scomp/dcomp to filter a subset of components, the code happily iterates over ncomp entries even if scomp + ncomp > src.nComp() or dcomp + ncomp > dst.nComp(). The default ncomp=10000 makes this especially easy to trigger. The out-of-bounds reads/writes are undefined behaviour and can trample unrelated data the moment we filter a sub-range near the end of a MultiFab.
Impact
Charge/current filtering in WarpX::ApplyFilterandSumBoundaryRho already exercises the non-zero scomp path; today it relies on manually keeping ncomp within bounds. Any future refactoring (or user code) that passes ncomp greater than the remaining components will corrupt the MultiFab on both CPU and GPU backends. The bug also silently returns garbage because there is no assert or guard.
Fix
Clip ncomp relative to both scomp and dcomp for every overload, and bail out early if nothing remains to filter. This keeps existing callers working while making the API safe for partial-component filtering.
Patch
@@ Filter::ApplyStencil (MultiFab&, GPU path)
- ncomp = std::min(ncomp, srcmf.nComp());
+ ncomp = std::min(ncomp, srcmf.nComp() - scomp);
+ ncomp = std::min(ncomp, dstmf.nComp() - dcomp);
+ if (ncomp <= 0) { return; }
@@ Filter::ApplyStencil (FArrayBox&, GPU path)
- ncomp = std::min(ncomp, srcfab.nComp());
+ ncomp = std::min(ncomp, srcfab.nComp() - scomp);
+ ncomp = std::min(ncomp, dstfab.nComp() - dcomp);
+ if (ncomp <= 0) { return; }
@@ Filter::ApplyStencil (MultiFab&, CPU path)
- ncomp = std::min(ncomp, srcmf.nComp());
+ ncomp = std::min(ncomp, srcmf.nComp() - scomp);
+ ncomp = std::min(ncomp, dstmf.nComp() - dcomp);
+ if (ncomp <= 0) { return; }
@@ Filter::ApplyStencil (FArrayBox&, CPU path)
- ncomp = std::min(ncomp, srcfab.nComp());
+ ncomp = std::min(ncomp, srcfab.nComp() - scomp);
+ ncomp = std::min(ncomp, dstfab.nComp() - dcomp);
+ if (ncomp <= 0) { return; }
Prepared by Codex
Summary
All four overloads of
Filter::ApplyStencilonly clampncompagainst the total number of components in the source MultiFab/FArrayBox (Filter/Filter.cpp:41,82,201,255). When callers pass a non-zeroscomp/dcompto filter a subset of components, the code happily iterates overncompentries even ifscomp + ncomp > src.nComp()ordcomp + ncomp > dst.nComp(). The defaultncomp=10000makes this especially easy to trigger. The out-of-bounds reads/writes are undefined behaviour and can trample unrelated data the moment we filter a sub-range near the end of a MultiFab.Impact
Charge/current filtering in
WarpX::ApplyFilterandSumBoundaryRhoalready exercises the non-zeroscomppath; today it relies on manually keepingncompwithin bounds. Any future refactoring (or user code) that passesncompgreater than the remaining components will corrupt the MultiFab on both CPU and GPU backends. The bug also silently returns garbage because there is no assert or guard.Fix
Clip
ncomprelative to bothscompanddcompfor every overload, and bail out early if nothing remains to filter. This keeps existing callers working while making the API safe for partial-component filtering.Patch
Prepared by Codex