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]

Reply via email to