Re: Is this change in mmap() behavior intentional or a bug?

From: Bakul Shah <bakul_at_iitbombay.org>
Date: Wed, 09 Apr 2025 01:37:25 UTC
On Apr 8, 2025, at 6:03 PM, Konstantin Belousov <kostikbel@gmail.com> wrote:
> 
> On Tue, Apr 08, 2025 at 03:46:27PM -0700, Bakul Shah wrote:
>> The attached program works on FreeBSD-12.1 but fails on
>> FreeBSD-14 or later.
>> 
>> The idea is to mmap an anon page and then keep writing to every
>> Nth word until given number of times. Attempts to write beyond
>> the allocated space will trap and in the signal handler we
>> allocate one more page.
> 
>> Since we are allocating pages to
>> appear in the virtual address space (and since no other code
>> allocates space) we should get a continuous range of pages.
> This is generally not true, the spec never provided such guarantees.
> If you need the second and subsequent mappings at the specific address,
> use MAP_FIXED.
> 
> The change in the behavior is called ASLR, and some people even claimed
> that it is for good.

I believe the intent for the original wording was to cover the case
when a given address is *not* aligned to a page boundary, not for ASLR
(which didn't raise its head until much later). IMHO if a page aligned
address is given mmap() should *strive* to provide just that. ASLR
should apply only when the given address is 0.

MAP_FIXED has some additional semantics such as replacing any previous
mapping, which can create its own confusing behavior. Now one has to
add MAP_EXCL as well I suppose. Still, at least there is a work around.

Thanks for your response.

Bakul

> 
>> 
>> Usage: a.out [-v] count [incr [val [addr]]]
>> 
>> On 12.1:
>> $ ./a.out -v 4 0x800
>> count=4, val=0x12345678, addr=0x100000, incr=0x800
>> 0x100000: 12345678
>> 0x100800: 12345679
>> 0x101000: 1234567a
>> 0x101800: 1234567b
>> 2 allocs
>> 
>> On 14.2-stable:
>> $ ./a.out -v 4 0x800
>> count=4, val=0x12345678, addr=0x75d000, incr=0x800
>> 0x75d000: 12345678
>> 0x75d800: 12345679
>> mmap: want 0x75e000, got 0x8210ae000
>> 
>> Looking at /proc/$pid/map (just after the first mmap) shows
>> there is a huge gap after the allocated page. Also, each time
>> this is run, a page is allocated at a different virtual address (unlike on 12.1).
>> 
>> This appears like a bug but I thought I'd ask here first.
>> 
>> Thanks for any insight!
>> 
>> -- bakul
>> 
>> PS: added code to pause after the first mmap.
>> 
> 
>