Skip to content

fix: keep CompileOptions includer alive across copy and move#1544

Open
Sakura-501 wants to merge 1 commit intogoogle:mainfrom
Sakura-501:fix-compileoptions-includer-uaf
Open

fix: keep CompileOptions includer alive across copy and move#1544
Sakura-501 wants to merge 1 commit intogoogle:mainfrom
Sakura-501:fix-compileoptions-includer-uaf

Conversation

@Sakura-501
Copy link
Copy Markdown

Summary

This fixes a use after free in shaderc::CompileOptions when a custom includer is configured through SetIncluder() and the options object is later copied or moved before preprocessing or compilation reaches #include.

Vulnerability details

SetIncluder() stores the includer callback state in two places:

  • the C++ wrapper keeps ownership in CompileOptions::includer_;
  • the underlying C options object stores raw callback function pointers plus include_user_data.

Before this change, copying CompileOptions only cloned options_, and moving it only transferred options_. The registered include_user_data therefore kept pointing at an includer owned by a different CompileOptions instance. Once that source object was destroyed, any later #include preprocessing path could call through a dangling pointer and trigger a heap use after free.

Both copy and move paths were affected. A remote shader compilation service that registers a custom includer and passes CompileOptions by value could be crashed with a single shader containing #include.

Fix

  • store the C++ includer in a std::shared_ptr so its lifetime can safely span copied CompileOptions objects;
  • re-register the include callbacks after copy and move so the underlying C options object always uses the current include_user_data;
  • clear the callbacks when SetIncluder(nullptr) is used;
  • add regression tests that prove the includer remains alive after the source CompileOptions instance is destroyed and that preprocessing with #include still succeeds.

Verification

  • cmake --build build-test --target check-copyright -j4
  • ./build-test/libshaderc/shaderc_shaderc_cpp_test

CompileOptions stores include callbacks inside the cloned or moved C options object but originally kept the C++ includer under unique ownership. Copying only cloned options_ and moving only transferred options_, so the registered include user_data pointer could outlive the owning CompileOptions object and become dangling after destruction.

Keep the includer alive across copies and moves by storing it in a shared_ptr and re-registering the callback user_data whenever CompileOptions is copied or moved. Add regression tests that verify the includer remains alive after the source object is destroyed and that preprocessing with #include still succeeds.
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.

1 participant