Skip to content

SharcResolveEntry: recovery linear probe reads past capacity for entries in the last SHARC_LINEAR_PROBE_WINDOW_SIZE slots (OOB read, device lost) #5

Description

@halukoral

Version: SHaRC v1.8.0, GLSL path, SHARC_ENABLE_RESPONSIVE_LIGHTING=1, SHARC_ENABLE_SH_ENCODING=1. Observed on Windows, RTX 4090, driver 610.74, Vulkan 1.3.

Summary

In SharcResolveEntry, the sampleNumPrev == 0 recovery path probes forward blindly:

for (uint i = entryIndex + 1; i < entryIndex + 1 + SHARC_LINEAR_PROBE_WINDOW_SIZE; ++i)
{
    HashGridKey hashKeyOld = BUFFER_AT_OFFSET(sharcParameters.hashGridData.hashEntriesBuffer, i);
    ...
    resolvedData = BUFFER_AT_OFFSET(sharcParameters.resolvedBuffer, i);
    ...
}

An application is allowed to allocate exactly capacity entries per buffer (that is what the samples do). For entries in the last SHARC_LINEAR_PROBE_WINDOW_SIZE slots of the table this loop reads up to SHARC_LINEAR_PROBE_WINDOW_SIZE elements past the end of both hashEntriesBuffer and resolvedBuffer. HashGridGetBaseSlot clamps normal bucket probes into range, but this entry-relative probe has no such clamp.

With buffer-device-address access (GLSL buffer_reference) there is no robustness backstop, so once the high table slots become occupied (dense cache) the read crosses the allocation's last page and the device is lost. Before the high slots fill up, the loop breaks early on empty keys (HASH_GRID_LIMIT_EMPTY_SLOTS), which is why the bug hides in light scenes.

Suggested fix

uint probeEnd = min(entryIndex + 1 + SHARC_LINEAR_PROBE_WINDOW_SIZE,
                    sharcParameters.hashGridData.capacity);
for (uint i = entryIndex + 1; i < probeEnd; ++i)

(Alternatively, document that applications must over-allocate SHARC_LINEAR_PROBE_WINDOW_SIZE extra slots, as the GetBaseSlot comment already suggests for HASH_GRID_HASH_MAP_BUCKET_SIZE - 1 — but the clamp seems strictly safer.)

Found while root-causing repeated VK_ERROR_DEVICE_LOST in a dense dynamic scene (sceneScale 100, capacity 2^22); a second, independent OOB in the update pass was reported separately (see the SHARC_CACHE_INDEX_BIT_MASK/HASH_GRID_INVALID_CACHE_INDEX issue).

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