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);

Reply via email to