Skip to content

Commit 3ac936c

Browse files
committed
fix(ebpf): fix insufficiently accurate detection of golang heaps
1 parent c922aaa commit 3ac936c

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

pkg/ebpf/c/common/memory.h

+13-4
Original file line numberDiff line numberDiff line change
@@ -176,25 +176,34 @@ statfunc bool vma_is_anon(struct vm_area_struct *vma)
176176
// The golang heap consists of arenas which are memory regions mapped using mmap.
177177
// When allocating areans, golang supplies mmap with an address hint, which is an
178178
// address that the kernel should place the mapping at.
179-
// Hints are constant and vary between architectures, see `mallocinit()` in
180-
// https://github.com/golang/go/blob/master/src/runtime/malloc.go
179+
// Hints for x86_64 begin at 0xc000000000 and for ARM64 at 0x4000000000.
181180
// From observation, when allocating arenas the MAP_FIXED flag is used which forces
182181
// the kernel to use the specified address or fail the mapping, so it is safe to
183182
// rely on the address pattern to determine if it belongs to a heap arena.
184-
#define GOLANG_ARENA_HINT_MASK 0x80ff00000000UL
183+
#define GOLANG_ARENA_HINT_MASK 0xffffffff00000000UL
185184
#if defined(bpf_target_x86)
186185
#define GOLANG_ARENA_HINT (0xc0UL << 32)
187186
#elif defined(bpf_target_arm64)
188187
#define GOLANG_ARENA_HINT (0x40UL << 32)
189188
#else
190189
#error Unsupported architecture
191190
#endif
191+
// We define a max hint that we assume golang allocations will never exceed.
192+
// This translates to the address 0xff00000000.
193+
// This means that we assume that a golang program will never allocate more than
194+
// 256GB of memory on x86_64, or 768GB on ARM64.
195+
#define GOLANG_ARENA_HINT_MAX (0xffUL << 32)
192196

193197
statfunc bool vma_is_golang_heap(struct vm_area_struct *vma)
194198
{
195199
u64 vm_start = BPF_CORE_READ(vma, vm_start);
196200

197-
return (vm_start & GOLANG_ARENA_HINT_MASK) == GOLANG_ARENA_HINT;
201+
// Check if the VMA address is in the range provided by golang heap arena address hints.
202+
// Of course, any program can also allocate memory at these addresses which will result
203+
// in a false positive for this check, so any caller of this function must make sure
204+
// that a false positive for this check is acceptable.
205+
return (vm_start & GOLANG_ARENA_HINT_MASK) >= GOLANG_ARENA_HINT &&
206+
(vm_start & GOLANG_ARENA_HINT_MASK) <= GOLANG_ARENA_HINT_MAX;
198207
}
199208

200209
statfunc bool vma_is_thread_stack(task_info_t *task_info, struct vm_area_struct *vma)

0 commit comments

Comments
 (0)