Address Randomization Tribulations

So, I have a tiny 32-bit application (a Forth) taking up about 4K, written in fasm. Pure minimalism, including an iffy elf header that fasm creates, with a fixed load address. More on that later.

It's been unstable, and I tracked the instability down to the initial memory allocation. Right at the start I add my desired memory size to the code base (the top label in asm code), and invoke `brk` system call. This worked as long as I allocated a largish amount, but failed on anything smaller than 16MB or so. Furthermore, it failed intermittently.

After much painful debugging I realized that even though the system is always loaded at the address in the header (0x08048000), due to address randomization, Linux thinks it is elsewhere. Asking brk for say 64K (0x0805800) will often be below the current break, and often entirely below the randomized space it thinks the program is in, causing a SEGFAULT shortly thereafter.

This seems like a bug - the loader should either abide by the forced address requested, or not allow a fixed load -- not load at requested address but pretend it is elsewhere in the memory space.

Has anyone encountered such nonsense? I kind of doubt it because most people use gcc and a proper linker, not barely-supported 32-bit architecture with a really bizzare assembler. But worth asking.

Posted in: s/Linux

๐Ÿš€ stack

2023-09-02 ยท 3 years ago

1 Comment

๐Ÿš€ stack [OP] ยท 2023-09-03 at 20:23:

I was completery right.

Tried with gdb (yuck), after `set disable-randomization off`, to turn randomization on, because gdb turns randomization off by default (wasting a bunch of my time, but kind of almost doesn't make no sense, pun intended).

So, nforth loads at 0x0804800-0x0804A00, but when heap is expanded up, it starts at 0x087DF000 and goes to 0x0A04900. So the memory space is not contiguous, and the entire idea of sysbreak is bullshit, in this particular case.