libpfm/libpfm-gcc12.patch
2022-06-21 12:07:42 -04:00

90 lines
2.6 KiB
Diff

commit a7b26272d8327ad1c001456a18518a0ac65dc2bb
Author: Stephane Eranian <eranian@gmail.com>
Date: Wed Jun 8 06:55:36 2022 -0700
avoid GCC-12 use-after-free warnings
gcc-12 seems to complain about bogus use-after-free situations in the
libpfm4 code:
p = realloc(q, ...)
if (!p)
return NULL
s = p + (q - z)
It complains because of the use of q after realloc in this case.
Yet q - z is just pointer artihmetic and is not dereferencing any
memory through the pointer q which may have been freed by realloc.
Fix is to pre-computer the delta before realloc to avoid using the
pointer after the call.
Reported-by: Vitaly Chikunov <vt@altlinux.org>
Signed-off-by: Stephane Eranian <eranian@gmail.com>
diff --git a/lib/pfmlib_perf_event_pmu.c b/lib/pfmlib_perf_event_pmu.c
index c3386aa..637c5b1 100644
--- a/lib/pfmlib_perf_event_pmu.c
+++ b/lib/pfmlib_perf_event_pmu.c
@@ -268,6 +268,7 @@ perf_table_alloc_event(void)
perf_table_alloc_event(void)
{
perf_event_t *new_pe;
+ size_t num_free;
retry:
if (perf_pe_free < perf_pe_end)
@@ -286,11 +287,20 @@ retry:
perf_pe_count += PERF_ALLOC_EVENT_COUNT;
+ /*
+ * compute number of free events left
+ * before realloc() to avoid compiler warning (use-after-free)
+ * even though we are simply doing pointer arithmetic and not
+ * dereferencing the perf_pe after realloc when it may be stale
+ * in case the memory was moved.
+ */
+ num_free = perf_pe_free - perf_pe;
+
new_pe = realloc(perf_pe, perf_pe_count * sizeof(perf_event_t));
if (!new_pe)
return NULL;
- perf_pe_free = new_pe + (perf_pe_free - perf_pe);
+ perf_pe_free = new_pe + num_free;
perf_pe_end = perf_pe_free + PERF_ALLOC_EVENT_COUNT;
perf_pe = new_pe;
@@ -315,18 +325,27 @@ static perf_umask_t *
perf_table_alloc_umask(void)
{
perf_umask_t *new_um;
+ size_t num_free;
retry:
if (perf_um_free < perf_um_end)
return perf_um_free++;
perf_um_count += PERF_ALLOC_UMASK_COUNT;
-
+
+ /*
+ * compute number of free unmasks left
+ * before realloc() to avoid compiler warning (use-after-free)
+ * even though we are simply doing pointer arithmetic and not
+ * dereferencing the perf_um after realloc when it may be stale
+ * in case the memory was moved.
+ */
+ num_free = perf_um_free - perf_um;
new_um = realloc(perf_um, perf_um_count * sizeof(*new_um));
if (!new_um)
return NULL;
- perf_um_free = new_um + (perf_um_free - perf_um);
+ perf_um_free = new_um + num_free;
perf_um_end = perf_um_free + PERF_ALLOC_UMASK_COUNT;
perf_um = new_um;