aquasecurity / aquasecurity/tracee

stack_pivot: false positives on Go 1.26 binaries due to heap base randomization

Open
#5,246 2 comments 1 reaction 1 assignee Claimed by @josedonizetti View on GitHub
kind/bug
Dominant language
Go
Stars
4.6k
Forks
507
Avg merge
2d 8h
Merged PRs (30d)
9

Description

## Description

Go 1.26 introduces heap base address randomization on 64-bit platforms ([release notes](https://go.dev/doc/go1.26)). This breaks the `stack_pivot` detector's Go
heap recognition, causing false positive events for any Go 1.26 binary running on a monitored system.

## Root Cause

The eBPF function `vma_is_golang_heap()` in `pkg/ebpf/c/common/memory.h` identifies Go heap arenas by checking if the VMA address falls in the
`0xc000000000–0xff00000000` range (x86_64). This works because Go has historically allocated heap arenas at deterministic addresses starting at `0xc000000000`.

Go 1.26 randomizes the heap base address as a security hardening measure. The arenas can now start at addresses outside the expected range, so
`vma_is_golang_heap()` returns false and the VMA is classified as `VMA_ANON` instead.

Since goroutine stacks live on the Go heap, the `check_stack_pivot()` function sees a syscall with SP pointing to anonymous memory (not the OS thread stack) and
emits a stack pivot event — a false positive.

## Impact

Any Go 1.26 binary running on a system monitored by tracee will generate false positive `stack_pivot` events. This will worsen as Go 1.26 adoption increases, and
the `GOEXPERIMENT=norandomizedheapbase64` opt-out is expected to be removed in a future Go release.

## Reproduction

Build any Go 1.26 program and run it under tracee with the `stack_pivot` event enabled. Goroutine syscalls will trigger false positives with `vma_type=anonymous`.

The E2E test `e2e-stack_pivot` reproduces this reliably — the `ds_writer` Go test helper gets flagged.

## Current Workaround

Tracee is built with `GOEXPERIMENT=norandomizedheapbase64` to disable heap randomization in its own binaries and test helpers. This does not fix detection for
external Go 1.26 processes.

see https://github.com/aquasecurity/tracee/pull/5244

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.