casaroli opened a new pull request, #21395: URL: https://github.com/apache/nuttx/pull/21395
## Summary With `CONFIG_ARCH_TEXT_VBASE`, `CONFIG_ARCH_DATA_VBASE` and `CONFIG_ARCH_HEAP_VBASE` set, `up_addrenv_create()` of arm64, RISC-V and x86_64 maps the text at the text base, the data after the reserved page at the data base, and the heap at the heap base, whatever their sizes. A text larger than its window is mapped over the reserved page and the data, and a data region larger than its window over the heap. `exec()` does not fail: the loader writes into the wrong pages and two regions use the same virtual addresses. Example: rv-virt:knsh64 (1 MiB data window) and a program with 1280 KiB of `.bss`. The program fills its `.bss` and a heap block, and stops on an assertion in `mm_free()`; its parent stops on the same assertion, and an ostest started after it fails (`fork()` returns `ENOMEM`): ``` nsh> winspawn winbss dump_assert_info: Assertion failed : at file: mm_heap/mm_free.c:243 task: winbss process: winbss 0xc000001a dump_assert_info: Assertion failed : at file: mm_heap/mm_free.c:243 task: winspawn process: winspawn 0xc00000e6 ``` This PR makes `up_addrenv_create()` of arm64, RISC-V and x86_64 return `-ENOMEM` when the text does not end before the data base or the data does not end before the heap base, so that `exec()` and `posix_spawn()` fail with `ENOMEM`. The heap is already limited to its window. ARMv7-A (`arm_addrenv_create_region()`) and the ESP32-S3 (`alloc_region()`) check each region against its window already (they return `-E2BIG`). The check is compiled only when the three bases are set and in this order; without fixed windows (for example qemu-armv8a:knsh, `CONFIG_ARCH_TEXT_VBASE=0`) the regions follow each other and nothing changes. ## Impact Kernel builds with fixed address windows on arm64, RISC-V and x86_64: a program that does not fit is refused with `ENOMEM` instead of running with overlapping regions. Programs that fit are not affected. No API change. The documentation (`Documentation/os/memory/addrenv.rst`) already says that `up_addrenv_create()` returns a negated errno value on failure. ## Testing Test programs: `winbss.c` (1280 KiB of `.bss`; fills it and a heap block, then checks both), `wintext.c` (1280 KiB of read-only data with a known value in every page, and a `.data` word), `winspawn.c` (starts them with `posix_spawnp()`: PASS when each one either exits with status 0 or is refused with `ENOMEM`). | Configuration | master 3ec6adc63f5 | this PR | |---|---|---| | rv-virt:knsh64 (QEMU TCG; text 0xC0000000, data 0xC0100000, heap 0xC0200000), `winspawn winbss` | `mm_free()` assertion in winbss and winspawn; ostest after it: `fork()` `ENOMEM`, status 256 | winbss refused with `ENOMEM`: PASS; ostest status 0 | | qemu-armv8a:knsh (HVF) with the same windows (`CONFIG_ARCH_TEXT_VBASE=0xC0000000`, `TEXT_NPAGES=256`, `DATA_VBASE=0xC0100000`, `DATA_NPAGES=256`, `HEAP_VBASE=0xC0200000`, `HEAP_NPAGES=128`), `winspawn` | winbss: `mm_free()` assertion in winbss and winspawn; ostest after it: `fork()` `ENOMEM`, status 256 | winbss and wintext refused with `ENOMEM`: PASS; ostest status 0 | | same, `winspawn wintext` | kernel data abort (permission fault at 0xc0100008, the reserved page), panic | (in the row above) | | qemu-armv8a:knsh as configured (no fixed windows), `winspawn` | both run, exit status 0: PASS; ostest status 0 | both run, exit status 0: PASS; ostest status 0 | | qemu-armv8a:nsh (flat) | ostest status 0 | ostest status 0 | (On rv-virt:knsh64 only winbss was run. qemu-armv8a:knsh programs are relocatable, so both cases reach the loader there.) Builds with `EXTRAFLAGS="-Wno-cpp -Werror"`, no new warnings: qemu-armv8a:knsh (no fixed windows: the check is not compiled) and qemu-armv8a:knsh with the fixed windows above (arm64, compiled), qemu-armv8a:nsh (flat), rv-virt:knsh64 and rv-virt:knsh (RISC-V 64 and 32 bits, compiled), qemu-intel64:knsh_romfs (x86_64, compiled; text window 512 KiB, data window 448 KiB; with `-Wno-error=shadow` for a libm warning of this host compiler), qemu-armv7a:knsh and esp32s3-devkit:kernel_oct (not changed). qemu-intel64:knsh_romfs was built but not run. The tests ran on master 3ec6adc63f5; the branch is rebased on 0e22bd5bd98 (the new commits touch no file of this PR). `tools/checkpatch.sh -c -u -m -g` passes. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
