-
Notifications
You must be signed in to change notification settings - Fork 250
Description
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