Hi, Could you try the attached patch? There is no use after free in the code as far as I can tell. But I modified the code to avoid triggering the gcc warning. I don't have gcc-12 so let me know if this works for you.
On Tue, Jun 7, 2022 at 1:26 AM Stephane Eranian <eran...@googlemail.com> wrote: > > Hi, > > Thanks for the report, > > I will fix this in the coming days. > > On Sat, Jun 4, 2022 at 10:08 AM Vitaly Chikunov <v...@altlinux.org> wrote: > > > > Stephane, > > > > There is compile failure on GCC 12.1.1: > > > > pfmlib_perf_event_pmu.c: In function 'perf_table_alloc_event': > > pfmlib_perf_event_pmu.c:293:47: error: pointer may be used after > > 'realloc' [-Werror=use-after-free] > > 293 | perf_pe_free = new_pe + (perf_pe_free - perf_pe); > > | ^ > > pfmlib_perf_event_pmu.c:289:18: note: call to 'realloc' here > > 289 | new_pe = realloc(perf_pe, perf_pe_count * > > sizeof(perf_event_t)); > > | > > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > In function 'perf_table_alloc_umask', > > inlined from 'gen_tracepoint_table' at pfmlib_perf_event_pmu.c:457:10: > > pfmlib_perf_event_pmu.c:329:47: error: pointer may be used after > > 'realloc' [-Werror=use-after-free] > > 329 | perf_um_free = new_um + (perf_um_free - perf_um); > > | ^ > > pfmlib_perf_event_pmu.c:325:18: note: call to 'realloc' here > > 325 | new_um = realloc(perf_um, perf_um_count * > > sizeof(*new_um)); > > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > cc1: all warnings being treated as errors > > > > Also, pointer arithmetic on unallocated region are, perhaps, undefined > > behavior by C standard. So even though this math looks safe on x86 this > > should be fixed anyway to be more portable. > > > > Thanks, > >
From a7b26272d8327ad1c001456a18518a0ac65dc2bb Mon Sep 17 00:00:00 2001 From: Stephane Eranian <eran...@gmail.com> Date: Wed, 8 Jun 2022 06:55:36 -0700 Subject: [PATCH] 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 <v...@altlinux.org> Signed-off-by: Stephane Eranian <eran...@gmail.com> --- lib/pfmlib_perf_event_pmu.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/pfmlib_perf_event_pmu.c b/lib/pfmlib_perf_event_pmu.c index c3386aaf4330..637c5b105559 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_event_t *new_pe; perf_event_t *p; + size_t num_free; /* * if we need to allocate an event and we have not yet @@ -286,11 +287,20 @@ perf_table_alloc_event(void) 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; -- 2.25.1
_______________________________________________ perfmon2-devel mailing list perfmon2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/perfmon2-devel