Skip to content

[CUDA][srad_v2] Out-of-bounds neighbor reads occur before boundary correction #12

Description

@FeiSa200

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions