]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
input: give file_cache_slot its own copy of the file path [PR118919]
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 19 Feb 2025 14:46:43 +0000 (09:46 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Tue, 21 Oct 2025 00:50:54 +0000 (20:50 -0400)
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 <dmalcolm@redhat.com>
(cherry picked from commit ee6619b1246b38cfb36f6efd931a6f475a9033c7)

gcc/input.cc

index 9f5228d255c0aecb63058c5f50aa22507f481d10..8d12ee9097d3d7729a20b9f8c762b6e13e57e334 100644 (file)
@@ -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);