guest-init: pass argv[0] when exec'ing cube-agent - #1451
dwin-gharibi wants to merge 1 commit into
Conversation
Signed-off-by: Dwin Gharibi <dwin.gharibi@email.kntu.ac.ir>
| let cmd = CString::new(CUBE_AGENT).expect("new cmd failed"); | ||
| let err = unistd::execvp(cmd.as_c_str(), &args).unwrap_err(); | ||
| let args = agent_argv(); | ||
| let err = unistd::execvp(args[0].as_c_str(), &args).unwrap_err(); |
There was a problem hiding this comment.
Potential gap — nix 0.26's execvp does not append a NULL terminator to argv. nix::unistd::execvp in the pinned nix 0.26.4 builds a Vec<*const c_char> from the slice and passes args_p.as_ptr() straight to libc::execvp without appending a terminating NULL (nix only fixed this in 0.29 via the CArray type). With this one-element slice, the kernel reads argv[1] from uninitialized heap memory right after the Vec's single pointer. If that slot is non-NULL garbage, the exec'd agent either receives bogus extra arguments (argc > 1) or the exec fails with EFAULT; it only reliably yields argc == 1 when the allocator hands back zeroed memory.
The new test covers agent_argv() construction only, not the exec path, and the PR explicitly defers /proc/1/cmdline verification to e2e territory. Since the entire point of this change is that argv is correct in the guest, please verify in a booted guest that /proc/1/cmdline actually shows cube-agent, and consider either upgrading nix to >= 0.29 or calling libc::execvp directly with an explicitly NULL-terminated array (libc is already a dependency here).
Review: PR #1451 — guest-init: pass argv[0] when exec'ing cube-agentAI-generated review. Reviewed against base SummaryThe change is correct in direction and is a strict improvement. Previously The added unit test is a sensible regression guard: it asserts the vector has exactly one element and equals Findings1. [Medium / needs e2e verification] The fix may not reliably produce 2. [Nit] Redundant assertion in the test. Positive notes
VerdictApprove with follow-up: verify in a booted guest that |
Closes #1450.
Motivation
start_agentcalledexecvpwith an emptyVec<CString>, sonixbuiltargv = [NULL]andcube-agentstarted withargc == 0. POSIX expectsargv[0]to be the program name, and without it/proc/1/cmdlineinside the guest is empty — so nothing in the guest can identify PID 1 by name.What this changes
guest-init/src/main.rs:agent_argv()builds the one-element argument vector, andstart_agentpasses it toexecvp,using
args[0]as the program path so the path andargv[0]cannot drift apart.Extracting
agent_argvis what makes the behaviour testable —start_agentitself cannot be unittested because a successful
execvpreplaces the process.No comment changes.
Testing
New test
agent_argv_carries_program_namein the existingmod tests: asserts the vector has exactlyone element, that it equals
CUBE_AGENT, and that it is non-empty (the last one is the actualregression guard — an empty vector was the bug).
(9 before this change, 10 after.)
CI gates checked locally:
cargo fmt --check— clean (fmt-checkrunsmake fmtper component).cargo clippy --all-targets— no new warnings.cargo test --all— 10 passed.What this does not verify
The test covers argv construction, not the exec itself — asserting on
/proc/1/cmdlinewould need abooted guest, which is e2e territory. The mechanism between the two is
nix::unistd::execvp, whichpasses the slice through verbatim.
Risk / rollout
Very low. The agent does not read
argvfor configuration (it uses/proc/cmdline), so nothing changesfunctionally — only that PID 1 now has a name.