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

Reply via email to