Reconstructing mmaps from sysctl KERN_PROC_VMMAP

From: Paul Floyd <paulf2718_at_gmail.com>
Date: Mon, 12 Feb 2024 07:21:23 UTC
Hi

I'm having difficulty with one of the Valgrind developer mode options, 
"--sanity-level=3". With this option every time that there is a change 
to things that are memory mapped Valgrind will do a check that its 
internal memory map model is consistent with what the OS reports. It 
gets the OS mappings via sysctl KERN_PROC_VMMAP.

This breaks down for mappings done with MAP_STACK (which happens each 
time a thread is created). For mmap calls like this there will initially 
be two mappings, a 128k stack mapping and a 'length-128k' guard mapping. 
This first guard page is really the stack growth area, and the size of 
the stack growth chunks is controlled by sysctl KERN_SGROWSIZ. As the 
stack grows more sgrowsiz mappings get created, eating up the stack 
growth guard mapping.

Is there any way to work out that the split growth guard and sgrowsiz 
stack mappings call come from a single mmap MAP_STACK? Indeed, is the 
kernel capable of telling that these mappings came from the same mmap?

My only idea at the moment is to modify the checks so that if Valgrind 
sees an anon RW mapping in its model that matches a zero prot guard plus 
some number of sgrowsiz RW stack mappings that have the same size as the 
singkle anon RW mapping then it is probably OK. And if the size is 
THR_STACK_DEFAULT it's even more likely to be OK. Of course, users could 
change the thread stacksize and I suppose that if you try hard enough 
you can manually arrive at a mapping with multiple mmap calls that looks 
like a single mmap MAP_STACK.


A+
Paul