Re: [PATCH v2] perf test amd ibs: avoid using executable heap
From: Ondrej Mosnacek
Date: Thu Jul 09 2026 - 10:42:30 EST
On Wed, Jul 1, 2026 at 8:43 AM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
>
> On Wed, Jul 01, 2026 at 08:23:21AM +0200, Ondrej Mosnacek wrote:
> > Making [parts of] the heap executable is dangerous and is blocked by
> > SELinux on Fedora/RHEL even for an unconfined user. Replace the malloc()
> > + mprotect() combo with just mmap(), creating a private anonymous rwx
> > mapping, which only requires the more commonly allowed "execmem"
>
> I do not understand. Ultimately malloc() will have to use mmap() to get
> the memory too. So how is malloc() + mprotect() considered more
> dangerous?
>
> > permission under SELinux (things like JIT or regex compilation need it
> > as well). mmap() with MAP_ANONYMOUS will give us a zeroed mapping that
> > begins on a page boundary, so the result is equivalent to the original
> > code even without a memset() or the page-alignment dance.
>
> I would argue that having RWX is a problem, you really want RW->RO->RX
> transitions, so even with mmap() you want to combine with mprotect().
>
> Obviously this doesn't matter for this test case, but any halfway sane
> JIT should really avoid keeping RWX mappings around.
You're right, an RWX mapping in the heap range isn't really worse than
an mmap()-returned anonymous RWX mapping. I think the key difference
is that executable ranges in the heap are much less common, so can be
treated as a sign of malware and denied more strictly in the policy.
The "execmem" permission is triggered on any anonymous executable (or
file-backed private writable-executable) mapping, which would apply
even for well-implemented JITs and thus can't be restricted as
broadly.
So the point is just to not do the more weird thing (which will get
you blocked under SELinux even under unconfined_t), so that the test
can be run on a SELinux-enforcing machine without workarounds. In
hindsight, I should have thought about it more deeply and phrase it
better in the commit message, sorry.
>
> > Verified that the test still passes on a machine with an AMD CPU that
> > has the "ibs" CPU flag.
> >
> > Fixes: 35db59fa8ea2 ("perf test amd ibs: Add sample period unit test")
> > Signed-off-by: Ondrej Mosnacek <omosnace@xxxxxxxxxx>
>
> The patch is obviously good, simpler is more better and all that. But
> the justification really smells.
>
> Acked-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
>
> If and when we get AMD to support IBT, this thing will need more
> changes, but alas.
>
> > ---
> >
> > v2: fix mmap() failure check (found by sashiko-bot)
> >
> > tools/perf/arch/x86/tests/amd-ibs-period.c | 20 ++++++--------------
> > 1 file changed, 6 insertions(+), 14 deletions(-)
> >
> > diff --git a/tools/perf/arch/x86/tests/amd-ibs-period.c b/tools/perf/arch/x86/tests/amd-ibs-period.c
> > index 6a92b3a23ed7a..32713f8fcd5c8 100644
> > --- a/tools/perf/arch/x86/tests/amd-ibs-period.c
> > +++ b/tools/perf/arch/x86/tests/amd-ibs-period.c
> > @@ -46,7 +46,6 @@ static int dummy_workload_1(unsigned long count)
> > {
> > int (*func)(void);
> > int ret = 0;
> > - char *p;
> > char insn1[] = {
> > 0xb8, 0x01, 0x00, 0x00, 0x00, /* mov 1,%eax */
> > 0xc3, /* ret */
> > @@ -59,18 +58,11 @@ static int dummy_workload_1(unsigned long count)
> > 0xcc, /* int 3 */
> > };
> >
> > - p = calloc(2, page_size);
> > - if (!p) {
> > - printf("malloc() failed. %m");
> > - return 1;
> > - }
> > -
> > - func = (void *)((unsigned long)(p + page_size - 1) & ~(page_size - 1));
> > -
> > - ret = mprotect(func, page_size, PROT_READ | PROT_WRITE | PROT_EXEC);
> > - if (ret) {
> > - printf("mprotect() failed. %m");
> > - goto out;
> > + func = mmap(NULL, page_size, PROT_READ | PROT_WRITE | PROT_EXEC,
> > + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> > + if (func == MAP_FAILED) {
> > + pr_debug("mmap() failed. %m\n");
> > + return -1;
> > }
> >
> > if (count < 100000)
> > @@ -93,7 +85,7 @@ static int dummy_workload_1(unsigned long count)
> > }
> >
> > out:
> > - free(p);
> > + munmap(func, page_size);
> > return ret;
> > }
> >
> > --
> > 2.54.0
> >
>
--
Ondrej Mosnacek
Senior Software Engineer, Linux Security - SELinux kernel
Red Hat, Inc.