Hi,
There was a recent bug filed in Fedora Rawhide that libpfm fails to build with
GCC 12 (https://bugzilla.redhat.com/show_bug.cgi?id=2045823). GCC is doing
some additional analysis of the code and doesn't like pointers to be used after
they are possibly freed:
gcc -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches
-pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2
-Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
-fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64
-mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection
-fcf-protection -O2 -flto=auto -ffat-lto-objects -fexceptions -g
-grecord-gcc-switches -pipe -Wall -Werror=format-security
-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS
-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -g -Wall
-Werror -Wextra -Wno-unused-parameter -I.
-I/home/wcohen/rpmbuild/BUILD/libpfm-4.12.0/include -DCONFIG_PFMLIB_DEBUG
-DCONFIG_PFMLIB_OS_LINUX -O2 -flto=auto -ffat-lto-objects -fexceptions -g
-grecord-gcc-switches -pipe -Wall -Werror=format-security
-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS
-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -g -Wall
-Werror -Wextra -Wno-unused-parameter -I.
-I/home/wcohen/rpmbuild/BUILD/libpfm-4.12.0/lib/../include
-DCONFIG_PFMLIB_DEBUG -DCONFIG_PFMLIB_OS_LINUX -D_REENTRANT -I.
-fvisibility=hidden -DCONFIG_PFMLIB_ARCH_X86 -DCONFIG_PFMLIB_ARCH_X86_64 -I. -c
pfmlib_perf_event_pmu.c
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
make[1]: *** [/home/wcohen/rpmbuild/BUILD/libpfm-4.12.0/lib/../rules.mk:30:
pfmlib_perf_event_pmu.o] Error 1
make[1]: Leaving directory '/home/wcohen/rpmbuild/BUILD/libpfm-4.12.0/lib'
make: *** [Makefile:49: all] Error 2
error: Bad exit status from /var/tmp/rpm-tmp.OFeziw (%build)
The logic is a bit convoluted in the perf_table_alloc_event and
perf_table_alloc_umask. Why not compute perf_pe_end and perf_um_end directly
from the values passed into the realloc? Maybe something like the attached
patch to address this.
-Will
diff -up libpfm-4.12.0/lib/pfmlib_perf_event_pmu.c.gcc12 libpfm-4.12.0/lib/pfmlib_perf_event_pmu.c
--- libpfm-4.12.0/lib/pfmlib_perf_event_pmu.c.gcc12 2021-12-16 16:29:42.000000000 -0500
+++ libpfm-4.12.0/lib/pfmlib_perf_event_pmu.c 2022-01-25 20:20:13.095174345 -0500
@@ -268,6 +268,7 @@ perf_table_alloc_event(void)
{
perf_event_t *new_pe;
perf_event_t *p;
+ int perf_pe_used;
/*
* if we need to allocate an event and we have not yet
@@ -285,13 +286,14 @@ retry:
return perf_pe_free++;
perf_pe_count += PERF_ALLOC_EVENT_COUNT;
+ perf_pe_used = 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_end = perf_pe_free + PERF_ALLOC_EVENT_COUNT;
+ perf_pe_free = new_pe + perf_pe_used;
+ perf_pe_end = new_pe + perf_pe_count;
perf_pe = new_pe;
goto retry;
@@ -315,19 +317,21 @@ static perf_umask_t *
perf_table_alloc_umask(void)
{
perf_umask_t *new_um;
+ int perf_um_used;
retry:
if (perf_um_free < perf_um_end)
return perf_um_free++;
perf_um_count += PERF_ALLOC_UMASK_COUNT;
+ perf_um_used = 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_end = perf_um_free + PERF_ALLOC_UMASK_COUNT;
+ perf_um_free = new_um + perf_um_used;
+ perf_um_end = new_um + perf_um_count;
perf_um = new_um;
goto retry;
_______________________________________________
perfmon2-devel mailing list
perfmon2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel