summaryrefslogtreecommitdiffstats
path: root/Tests
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-03-18 13:51:46 (GMT)
committerBrad King <brad.king@kitware.com>2020-03-19 10:41:39 (GMT)
commit8affe9aa336b873e9c8e40ec5911ffe23c2ef03a (patch)
tree0d2b79f86c604c23d3ceff99a69a93fcb9b6c38a /Tests
parent1ec72e09471287630cf142d8587a9b8d9abad629 (diff)
downloadCMake-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 'Tests')
-rw-r--r--Tests/RunCMake/export/Repeat.cmake5
-rw-r--r--Tests/RunCMake/export/Repeat/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/export/RunCMakeTest.cmake1
3 files changed, 8 insertions, 0 deletions
diff --git a/Tests/RunCMake/export/Repeat.cmake b/Tests/RunCMake/export/Repeat.cmake
new file mode 100644
index 0000000..f3262e7
--- /dev/null
+++ b/Tests/RunCMake/export/Repeat.cmake
@@ -0,0 +1,5 @@
+add_library(foo INTERFACE)
+export(TARGETS foo FILE foo.cmake)
+export(TARGETS foo FILE foo.cmake)
+add_subdirectory(Repeat)
+include(CMakePackageConfigHelpers)
diff --git a/Tests/RunCMake/export/Repeat/CMakeLists.txt b/Tests/RunCMake/export/Repeat/CMakeLists.txt
new file mode 100644
index 0000000..b37f6ca
--- /dev/null
+++ b/Tests/RunCMake/export/Repeat/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(bar INTERFACE)
+export(TARGETS bar FILE ${CMAKE_BINARY_DIR}/foo.cmake)
diff --git a/Tests/RunCMake/export/RunCMakeTest.cmake b/Tests/RunCMake/export/RunCMakeTest.cmake
index 4d2f217..df35d95 100644
--- a/Tests/RunCMake/export/RunCMakeTest.cmake
+++ b/Tests/RunCMake/export/RunCMakeTest.cmake
@@ -2,6 +2,7 @@ include(RunCMake)
run_cmake(CustomTarget)
run_cmake(Empty)
+run_cmake(Repeat)
run_cmake(TargetNotFound)
run_cmake(AppendExport)
run_cmake(OldIface)