The srad_v2 CUDA implementation in this repository contains global-memory out-of-bounds reads in srad_cuda_1 and srad_cuda_2.
The kernels compute neighbor indices and immediately use them to load data from global memory. For boundary blocks, some of these indices fall outside the underlying allocation. The code only replaces the corresponding shared-memory values with valid boundary values after the
loads have already occurred.
I detected these invalid reads during memory-safety testing and subsequently confirmed the issue from the source-level index calculations.
Affected Code
File: cuda/srad_v2/srad_kernel.cu
In srad_cuda_1, neighbor values are loaded before the boundary condition is handled:
north[ty][tx] = J_cuda[index_n];
south[ty][tx] = J_cuda[index_s];
if (by == 0) {
north[ty][tx] = J_cuda[BLOCK_SIZE * bx + tx];
} else if (by == gridDim.y - 1) {
south[ty][tx] =
J_cuda[cols * BLOCK_SIZE * (gridDim.y - 1)
+ BLOCK_SIZE * bx
+ cols * (BLOCK_SIZE - 1) + tx];
}
A similar pattern occurs in srad_cuda_2:
south_c[ty][tx] = C_cuda[index_s];
if (by == gridDim.y - 1) {
south_c[ty][tx] =
C_cuda[cols * BLOCK_SIZE * (gridDim.y - 1)
+ BLOCK_SIZE * bx
+ cols * (BLOCK_SIZE - 1) + tx];
}
Root Cause
The device arrays contain exactly:
rows * cols
elements, so the valid index range is:
0 ... rows * cols - 1
For the top block row (by == 0), index_n is negative, causing a read before the beginning of J_cuda.
For the bottom block row (by == gridDim.y - 1), the south-neighbor index satisfies:
index_s >= rows * cols
and therefore accesses memory beyond the end of the allocation.
For example, with:
rows = 128
cols = 128
the allocation contains:
128 * 128 = 16384
floating-point elements, corresponding to:
16384 * sizeof(float) = 65536 bytes
The first invalid south-neighbor access can therefore occur at:
base + 65536
which is exactly the first address beyond the allocation.
The later boundary correction only overwrites the value stored in shared memory. It cannot undo the out-of-bounds global-memory read
that has already occurred.
The same issue also affects the corresponding neighbor accesses in srad_cuda_2.
The
srad_v2CUDA implementation in this repository contains global-memory out-of-bounds reads insrad_cuda_1andsrad_cuda_2.The kernels compute neighbor indices and immediately use them to load data from global memory. For boundary blocks, some of these indices fall outside the underlying allocation. The code only replaces the corresponding shared-memory values with valid boundary values after the
loads have already occurred.
I detected these invalid reads during memory-safety testing and subsequently confirmed the issue from the source-level index calculations.
Affected Code
File:
cuda/srad_v2/srad_kernel.cuIn
srad_cuda_1, neighbor values are loaded before the boundary condition is handled:A similar pattern occurs in srad_cuda_2:
Root Cause
The device arrays contain exactly:
rows * colselements, so the valid index range is:
0 ... rows * cols - 1For the top block row (
by == 0),index_nis negative, causing a read before the beginning ofJ_cuda.For the bottom block row (
by == gridDim.y - 1), the south-neighbor index satisfies:index_s >= rows * colsand therefore accesses memory beyond the end of the allocation.
For example, with:
rows = 128cols = 128the allocation contains:
128 * 128 = 16384floating-point elements, corresponding to:
16384 * sizeof(float) = 65536 bytesThe first invalid south-neighbor access can therefore occur at:
base + 65536which is exactly the first address beyond the allocation.
The later boundary correction only overwrites the value stored in shared memory. It cannot undo the out-of-bounds global-memory read
that has already occurred.
The same issue also affects the corresponding neighbor accesses in
srad_cuda_2.