From a0782531b8270f0fdb3f3e09b4ce544d5d1eef14 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 22 Feb 2024 13:07:25 +0100 Subject: [PATCH] profile-count: Don't dump through a temporary buffer [PR111960] 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 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 | 32 +++++++++++--------------------- gcc/profile-count.h | 3 --- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/gcc/profile-count.cc b/gcc/profile-count.cc index 0cb1220e078..b26f38e33e4 100644 --- a/gcc/profile-count.cc +++ b/gcc/profile-count.cc @@ -84,32 +84,22 @@ const char *profile_quality_display_names[] = "precise" }; -/* Dump THIS to BUFFER. */ - -void -profile_count::dump (char *buffer, struct function *fun) const -{ - if (!initialized_p ()) - sprintf (buffer, "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, - 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, - 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); + if (!initialized_p ()) + fprintf (f, "uninitialized"); + else if (fun && initialized_p () + && fun->cfg + && ENTRY_BLOCK_PTR_FOR_FN (fun)->count.initialized_p ()) + 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 + fprintf (f, "%" PRId64 " (%s)", m_val, + profile_quality_display_names[m_quality]); } /* Dump THIS to stderr. */ diff --git a/gcc/profile-count.h b/gcc/profile-count.h index b773b4ec47c..b3d776475e2 100644 --- a/gcc/profile-count.h +++ b/gcc/profile-count.h @@ -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;