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):
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)
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:
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:
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
Summary
kernel::multiboot()stores a dangling pointer inkernel::state().cmdlinewhen a multiboot command line is present.Location
src/kernel/multiboot.cpp(around line 184):kernel::state().cmdline = std::pmr::string(cmdline).data();kernel::state().cmdlineis aconst char*, butstd::pmr::string(cmdline)is a temporary destroyed at the end of the statement, so.data()does not remain valid.How to reproduce (compile-time)
Clang reports:
History
Commit
07bcb8f18(Sep 2024, part of #2273) replaced:kernel::state().cmdline = strdup(cmdline);The old
strduppath 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 insrc/platform/x86_pc/init_libc.cppfor env strings passed to__libc_start_main:Possible fix directions
.data()from a temporary), or_multiboot_free_begin()).Testing gap
nix-build unittests.nixcompiles this code but does not boot a multiboot image withMULTIBOOT_INFO_CMDLINE, so the runtime bug is easy to miss.Related: #2252, #2273