Skip to content

Force size 0 allocations to be size 1 allocations to avoid misreporting OOM - #2086

Closed
aitor-lunarg wants to merge 1 commit into
KhronosGroup:mainfrom
aitor-lunarg:fix-oom-report
Closed

aitor-lunarg wants to merge 1 commit into
KhronosGroup:mainfrom
aitor-lunarg:fix-oom-report

Conversation

@aitor-lunarg

@aitor-lunarg aitor-lunarg commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Commit message:

calloc or custom Vulkan host allocators can return null for size 0 allocations. Certain checks in the loader will report OOM if the pointer returned by the allocation calls is null even if the execution can continue without any issues. Fix this issue by requesting 1 byte instead of 0.

Found through CTS test dEQP-VK.api.device_init.enumerate_devices_alloc_leak.basic. Loader would report VK_ERROR_OUT_OF_HOST_MEMORY when the custom Vulkan host allocator returns null for size 0 allocations. Root cause lies in https://github.com/KhronosGroup/Vulkan-Loader/blob/main/loader/loader.c#L6043 which was made visible after #2076

The mentioned check expects that the returned pointer is not null. However, when requesting a size 0 allocation, according to https://man7.org/linux/man-pages/man3/calloc.3p.html

If the size of the space requested is 0, the behavior is implementation-defined:
either a null pointer shall be returned, or the behavior shall be
as if the size were some non-zero value, except that the behavior
is undefined if the returned pointer is used to access an object.

and the Vulkan spec in https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#memory-host:

If pfnAllocation returns NULL, and if the implementation is unable to continue correct processing of the current command without the requested allocation, it must treat this as a runtime error, and generate [VK_ERROR_OUT_OF_HOST_MEMORY](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#VkResult) at the appropriate time for the command in which the condition was detected, as described in [Return Codes](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#fundamentals-errorcodes).

If the implementation is able to continue correct processing of the current command without the requested allocation, then it may do so, and must not generate [VK_ERROR_OUT_OF_HOST_MEMORY](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#VkResult) as a result of this failed allocation.

Which means we could get a null pointer for a size 0 allocation. This does not mean the host run out of memory, and following what the Vulkan spec states, since the requested allocation is 0 even if we get a null pointer we should be able to continue execution.

This PR makes 0 size allocations into 1 size allocations so that we get a valid pointer. This way, we don't have to modify every single location where memory is requested and checks for non-null.

Alternatively, we could modify all memory allocation locations if this approach is a no-go.

…ng OOM

calloc or custom Vulkan host allocators can return null for size 0
allocations. Certain checks in the loader will report OOM if the pointer
returned by the allocation calls is null even if the execution can continue
without any issues. Fix this issue by requesting 1 byte instead of 0.
@ci-tester-lunarg

Copy link
Copy Markdown

CI Vulkan-Loader build queued with queue ID 172940.

@ci-tester-lunarg

Copy link
Copy Markdown

CI Vulkan-Loader build # 3916 running.

@ci-tester-lunarg

Copy link
Copy Markdown

CI Vulkan-Loader build queued with queue ID 172958.

@ci-tester-lunarg

Copy link
Copy Markdown

CI Vulkan-Loader build # 3917 running.

@ci-tester-lunarg

Copy link
Copy Markdown

CI Vulkan-Loader build # 3917 passed.

@charles-lunarg

Copy link
Copy Markdown
Collaborator

I am not in favor of this solution because it hides bad code just to minimize code changes.

The codebase just went through a large refactor to replace alloca with calloc/realloc. The rest of the code already operated under the presumption of not calling calloc/realloc with size zero. That said, there isn't a strict enforcement of this rule. I have had clang-tidy warn about it in the past using the option optin.portability.UnixAPI. Unfortunately, clang-tidy cannot find the issue you found nor the various issues claude found because it limits its search depth/breadth to a fixed amount. I believe because the loader goes through a few levels of indirection in the allocation calls, this hurts clang-tidy's chance of finding issues.

I am much more in favor of just biting the bullet and fixing the callsites to not have a size of zero.

@aitor-lunarg

Copy link
Copy Markdown
Contributor Author

I am much more in favor of just biting the bullet and fixing the callsites to not have a size of zero.

Agreed! Closing in favour of an upcoming PR handling these cases individually

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants