90 lines
2.6 KiB
Diff
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;
|
|
|