]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
profile-count: Don't dump through a temporary buffer [PR111960]
authorJakub Jelinek <jakub@redhat.com>
Thu, 22 Feb 2024 12:07:25 +0000 (13:07 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 22 Feb 2024 12:07:25 +0000 (13:07 +0100)
The profile_count::dump (char *, struct function * = NULL) const;
method has a single caller, the
profile_count::dump (FILE *f, struct function *fun) const;
method and for that going through a temporary buffer is just slower
and opens doors for buffer overflows, which is exactly why this P1
was filed.
The buffer size is 64 bytes, the previous maximum
"%" PRId64 " (%s)"
would print up to 61 bytes in there (19 bytes for arbitrary uint64_t:61
bitfield printed as signed, "estimated locally, globally 0 adjusted"
i.e. 38 bytes longest %s and 4 other characters).
Now, after the r14-2389 changes, it can be
19 + 38 plus 11 other characters + %.4f, which is worst case
309 chars before decimal point, decimal point and 4 digits after it,
so total 382 bytes.

So, either we could bump the buffer[64] to buffer[400], or the following
patch just drops the indirection through buffer and prints it directly to
stream.  After all, having APIs which fill in some buffer without passing
down the size of the buffer is just asking for buffer overflows over time.

2024-02-22  Jakub Jelinek  <jakub@redhat.com>

PR ipa/111960
* profile-count.h (profile_count::dump): Remove overload with
char * first argument.
* profile-count.cc (profile_count::dump): Change overload with char *
first argument which uses sprintf into the overfload with FILE *
first argument and use fprintf instead.  Remove overload which wrapped
it.

gcc/profile-count.cc
gcc/profile-count.h

index 0cb1220e07850c3573e6ef19bbfbd156fa3da9de..b26f38e33e474583affe18ded37bc820c50f3863 100644 (file)
@@ -84,34 +84,24 @@ const char *profile_quality_display_names[] =
   "precise"
 };
 
-/* Dump THIS to BUFFER.  */
+/* Dump THIS to F.  */
 
 void
-profile_count::dump (char *buffer, struct function *fun) const
+profile_count::dump (FILE *f, struct function *fun) const
 {
   if (!initialized_p ())
-    sprintf (buffer, "uninitialized");
+    fprintf (f, "uninitialized");
   else if (fun && initialized_p ()
           && fun->cfg
           && ENTRY_BLOCK_PTR_FOR_FN (fun)->count.initialized_p ())
-    sprintf (buffer, "%" PRId64 " (%s, freq %.4f)", m_val,
+    fprintf (f, "%" PRId64 " (%s, freq %.4f)", m_val,
             profile_quality_display_names[m_quality],
             to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (fun)->count).to_double ());
   else
-    sprintf (buffer, "%" PRId64 " (%s)", m_val,
+    fprintf (f, "%" PRId64 " (%s)", m_val,
             profile_quality_display_names[m_quality]);
 }
 
-/* Dump THIS to F.  */
-
-void
-profile_count::dump (FILE *f, struct function *fun) const
-{
-  char buffer[64];
-  dump (buffer, fun);
-  fputs (buffer, f);
-}
-
 /* Dump THIS to stderr.  */
 
 void
index b773b4ec47c25d0d3ea4acb78f6b180992cf7a71..b3d776475e2ca1376e61fe08e4eed364d2c0b2db 100644 (file)
@@ -1299,9 +1299,6 @@ public:
   /* Output THIS to F.  */
   void dump (FILE *f, struct function *fun = NULL) const;
 
-  /* Output THIS to BUFFER.  */
-  void dump (char *buffer, struct function *fun = NULL) const;
-
   /* Print THIS to stderr.  */
   void debug () const;