diff options
author | Brad King <brad.king@kitware.com> | 2020-03-18 13:51:46 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-03-19 10:41:39 (GMT) |
commit | 8affe9aa336b873e9c8e40ec5911ffe23c2ef03a (patch) | |
tree | 0d2b79f86c604c23d3ceff99a69a93fcb9b6c38a /Source/cmGlobalGenerator.h | |
parent | 1ec72e09471287630cf142d8587a9b8d9abad629 (diff) | |
download | CMake-8affe9aa336b873e9c8e40ec5911ffe23c2ef03a.zip CMake-8affe9aa336b873e9c8e40ec5911ffe23c2ef03a.tar.gz CMake-8affe9aa336b873e9c8e40ec5911ffe23c2ef03a.tar.bz2 |
export: Fix use-after-free on multiple calls overwriting same FILE
CMake 3.16 and below allow multiple `export()` calls with the same output
file even without using `APPEND`. The implementation worked by accident
by leaking memory. Refactoring in commit 5444a8095d (cmGlobalGenerator:
modernize memrory managemenbt, 2019-12-29, v3.17.0-rc1~239^2) cleaned up
that memory leak and converted it to a use-after-free instead.
The problem is caused by using the `cmGlobalGenerator::BuildExportSets`
map to own `cmExportBuildFileGenerator` instances. It can own only
one instance per output FILE name at a time, so repeating use of the
same file now frees the old `cmExportBuildFileGenerator` instance
and leaves the pointer in the `cmMakefile::ExportBuildFileGenerators`
vector dangling. Move ownership of the instances into `cmMakefile`'s
vector since its entries are not replaced on a repeat output FILE.
In future work we should introduce a policy to error out on this case.
For now simply fix the use-after-free to restore CMake <= 3.16 behavior.
Fixes: #20469
Diffstat (limited to 'Source/cmGlobalGenerator.h')
-rw-r--r-- | Source/cmGlobalGenerator.h | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index ba997b2..7dc4822 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -463,13 +463,12 @@ public: void ProcessEvaluationFiles(); - std::map<std::string, std::unique_ptr<cmExportBuildFileGenerator>>& - GetBuildExportSets() + std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets() { return this->BuildExportSets; } - void AddBuildExportSet(std::unique_ptr<cmExportBuildFileGenerator>); - void AddBuildExportExportSet(std::unique_ptr<cmExportBuildFileGenerator>); + void AddBuildExportSet(cmExportBuildFileGenerator* gen); + void AddBuildExportExportSet(cmExportBuildFileGenerator* gen); bool IsExportedTargetsFile(const std::string& filename) const; bool GenerateImportFile(const std::string& file); cmExportBuildFileGenerator* GetExportedTargetsFile( @@ -580,8 +579,7 @@ protected: std::set<std::string> InstallComponents; // Sets of named target exports cmExportSetMap ExportSets; - std::map<std::string, std::unique_ptr<cmExportBuildFileGenerator>> - BuildExportSets; + std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets; std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets; std::map<std::string, std::string> AliasTargets; |