💾 Archived View for bbs.geminispace.org › s › Linux › 5066 captured on 2024-03-21 at 15:28:32. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2024-02-05)
-=-=-=-=-=-=-
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.
2023-09-02 · 7 months ago
🚀 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).
(gdb) info proc mappings process 144876 Mapped address spaces: Start Addr End Addr Size Offset Perms objfile 0x8048000 0x804a000 0x2000 0x0 rwxp /home/stack/src/nForth/nforth 0x87df000 0xa049000 0x186a000 0x0 rwxp [heap] 0xf7f75000 0xf7f79000 0x4000 0x0 r--p [vvar] 0xf7f79000 0xf7f7b000 0x2000 0x0 r-xp [vdso] 0xffc4e000 0xffc6f000 0x21000 0x0 rwxp [stack] (gdb)
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.