multiboot cmdline stores dangling pointer after pmr::string change (#2273)

#2368 · open · 0 comments

View on GitHub ↗

uadhran

## Summary `kernel::multiboot()` stores a dangling pointer in `kernel::state().cmdline` when a multiboot command line is present. ## Location `src/kernel/multiboot.cpp` (around line 184): ```cpp kernel::state().cmdline = std::pmr::string(cmdline).data(); ``` `kernel::state().cmdline` is a `const char*`, but `std::pmr::string(cmdline)` is a temporary destroyed at the end of the statement, so `.data()` does not remain valid. ## How to reproduce (compile-time) ``` nix-build unittests.nix ``` Clang reports: ``` multiboot.cpp:184:31: warning: object backing the pointer kernel::state().cmdline will be destroyed at the end of the full-expression [-Wdangling-assignment-gsl] ``` ## History Commit `07bcb8f18` (Sep 2024, part of #2273) replaced: ```cpp kernel::state().cmdline = strdup(cmdline); ``` The old `strdup` path caused early-boot malloc/brk activity before libc was ready (see #2252). The pmr::string change addressed that, but storing `.data()` from a temporary introduces a lifetime bug instead. ## Related pattern The same temporary `.data()` pattern exists in `src/platform/x86_pc/init_libc.cpp` for env strings passed to `__libc_start_main`: ```cpp argv[2] = std::pmr::string("LC_CTYPE=C").data(); argv[3] = std::pmr::string("LC_ALL=C").data(); argv[4] = std::pmr::string("USER=root").data(); ``` ## Possible fix directions - Store owned/stable storage for cmdline (not `.data()` from a temporary), or - Use the multiboot-provided cmdline pointer directly if its lifetime is guaranteed for the kernel (IncludeOS already accounts for cmdline memory in `_multiboot_free_begin()`). ## Testing gap `nix-build unittests.nix` compiles this code but does not boot a multiboot image with `MULTIBOOT_INFO_CMDLINE`, so the runtime bug is easy to miss. Related: #2252, #2273

Comments