https://gcc.gnu.org/g:004198aa24e60ae9e81554a17d9b10c7beb4a759
commit r14-12112-g004198aa24e60ae9e81554a17d9b10c7beb4a759 Author: David Malcolm <[email protected]> Date: Wed Feb 19 09:46:43 2025 -0500 input: give file_cache_slot its own copy of the file path [PR118919] input.cc's file_cache was borrowing copies of the file name. This could lead to use-after-free when writing out sarif output from Fortran, which frees its filenames before the sarif output is fully written out. Fix by taking a copy in file_cache_slot. gcc/ChangeLog: PR other/118919 * input.cc (file_cache_slot::m_file_path): Make non-const. (file_cache_slot::evict): Free m_file_path. (file_cache_slot::create): Store a copy of file_path if non-null. (file_cache_slot::~file_cache_slot): Free m_file_path. Signed-off-by: David Malcolm <[email protected]> (cherry picked from commit ee6619b1246b38cfb36f6efd931a6f475a9033c7) Diff: --- gcc/input.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gcc/input.cc b/gcc/input.cc index 9f5228d255c0..8d12ee9097d3 100644 --- a/gcc/input.cc +++ b/gcc/input.cc @@ -120,10 +120,8 @@ public: unsigned m_use_count; /* The file_path is the key for identifying a particular file in - the cache. - For libcpp-using code, the underlying buffer for this field is - owned by the corresponding _cpp_file within the cpp_reader. */ - const char *m_file_path; + the cache. This copy is owned by the slot. */ + char *m_file_path; FILE *m_fp; @@ -367,6 +365,7 @@ file_cache::missing_trailing_newline_p (const char *file_path) void file_cache_slot::evict () { + free (m_file_path); m_file_path = NULL; if (m_fp) fclose (m_fp); @@ -462,7 +461,7 @@ file_cache_slot::create (const file_cache::input_context &in_context, const char *file_path, FILE *fp, unsigned highest_use_count) { - m_file_path = file_path; + m_file_path = file_path ? xstrdup (file_path) : nullptr; if (m_fp) fclose (m_fp); m_fp = fp; @@ -556,6 +555,7 @@ file_cache_slot::file_cache_slot () file_cache_slot::~file_cache_slot () { + free (m_file_path); if (m_fp) { fclose (m_fp);
