This is an archive of the discontinued LLVM Phabricator instance.

[tidy] Fix possible use-after-free in IdentifierNamingCheck
ClosedPublic

Authored by kadircet on May 10 2023, 12:52 AM.

Details

Summary

CheckName retrieived during construction is a reference to keys stored
inside ClangTidyCheckFactories, which isn't guranteed to outlive the check.

Diff Detail

Event Timeline

kadircet created this revision.May 10 2023, 12:52 AM
Herald added a project: Restricted Project. · View Herald Transcript
kadircet requested review of this revision.May 10 2023, 12:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 10 2023, 12:52 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

see https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clang-tidy/ClangTidy.cpp#L638 for such a pattern, clangd also initializes checks with a similar approach.

hokein accepted this revision.May 10 2023, 1:42 AM

The fix looks good.

We also have a CheckName field in the base class ClangTidyCheck, however that's field is private, we can't not access, we could consider make it protected (I think that's probably out of the scope of this patch).

This revision is now accepted and ready to land.May 10 2023, 1:42 AM

see https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clang-tidy/ClangTidy.cpp#L638 for such a pattern, clangd also initializes checks with a similar approach.

In this example the factory outlives the check so there is no possible use after free.

In regard to this change, I think that this member can actually be removed entirely as we can get the name of the check using the getID virtual function.

The fix looks good.

We also have a CheckName field in the base class ClangTidyCheck, however that's field is private, we can't not access, we could consider make it protected (I think that's probably out of the scope of this patch).

See previous comment

kadircet updated this revision to Diff 520936.May 10 2023, 1:55 AM
  • Expose getID to tidy-checks and use it instead of storing checkname

see https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clang-tidy/ClangTidy.cpp#L638 for such a pattern, clangd also initializes checks with a similar approach.

In this example the factory outlives the check so there is no possible use after free.

Sorry you're right, I thought checks created in https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clang-tidy/ClangTidy.cpp#L660 would become part of the return value, but instead they're dropped on the floor.
but nevertheless, clangd has this pattern in https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clangd/ParsedAST.cpp#L479. I am happy to change the pattern in clangd as well, but I don't think there's anything requiring users to keep the "factory" around in the contract.

In regard to this change, I think that this member can actually be removed entirely as we can get the name of the check using the getID virtual function.

made it protected and used it instead.

This revision was automatically updated to reflect the committed changes.