Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code that does auto &state_object = *Get<>(handle); risks use after free bugs. #7975

Closed
jeremyg-lunarg opened this issue May 8, 2024 · 2 comments · Fixed by #8023
Closed
Assignees
Labels
Bug Something isn't working

Comments

@jeremyg-lunarg
Copy link
Contributor

jeremyg-lunarg commented May 8, 2024

Validation code must hold a reference to any state objects it is using. This pattern avoids that and risks use after free bugs from invalid applications. Current list of places this is happening. There could be others that aren't easily findable with grep.

:~/src/Vulkan-ValidationLayers>git grep "\*Get<"
layers/best_practices/bp_cmd_buffer.cpp:    const auto& query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_descriptor.cpp:    const auto &src_set = *Get<vvl::DescriptorSet>(update.srcSet);
layers/core_checks/cc_descriptor.cpp:    const auto &dst_set = *Get<vvl::DescriptorSet>(update.dstSet);
layers/core_checks/cc_descriptor.cpp:        const auto &set_node = *Get<vvl::DescriptorSet>(dst_set);
layers/core_checks/cc_device_memory.cpp:            !HasExternalMemoryImportSupport(*Get<vvl::Image>(dedicated_image), VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)) {
layers/core_checks/cc_device_memory.cpp:            !HasExternalMemoryImportSupport(*Get<vvl::Buffer>(dedicated_buffer), VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)) {
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(query_obj.pool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_render_pass.cpp:    const auto &rp_state = *Get<vvl::RenderPass>(pRenderPassBegin->renderPass);
layers/core_checks/cc_render_pass.cpp:    const auto &fb_state = *Get<vvl::Framebuffer>(pRenderPassBegin->framebuffer);
layers/core_checks/cc_render_pass.cpp:                const auto &view_state = *Get<vvl::ImageView>(image_views[i]);
layers/core_checks/cc_render_pass.cpp:    const auto &framebuffer_state = *Get<vvl::Framebuffer>(begin_info.framebuffer);
layers/core_checks/cc_render_pass.cpp:    const auto &image_view_state = *Get<vvl::ImageView>(attachment_info.imageView);

Note that this does not mean you can never use references to state objects, it just means some part of the call stack must hold shared_ptr and it can call other functions passing a reference, eg:

auto &state_object = *Get<>(handle);
skip = ValidateSomething(*state_object);
@jeremyg-lunarg
Copy link
Contributor Author

For a concrete example see #7974

@spencer-lunarg spencer-lunarg self-assigned this May 8, 2024
@spencer-lunarg spencer-lunarg added the Bug Something isn't working label May 9, 2024
@spencer-lunarg
Copy link
Contributor

so for the query, we were already dereferencing these all without bound checking ever, so I moved these to be like this

layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(query_obj.pool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);
layers/core_checks/cc_query.cpp:    const auto &query_pool_state = *Get<vvl::QueryPool>(queryPool);

so these are all called directly form the vulkan chassis function

for example in PreCallValidateGetQueryPoolResults we do this, but there is a corresponding NegativeQuery. GetQueryPoolResultsWithoutQueryPool test for it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants