# parseCmdLine() wraps multi-word Linux-unikernel args in unescaped single quotes, corrupting urunit's boot-cmdline argument parsing when an arg itself contains a quote
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
- #898 di @Anand-240 — chiusa senza merge
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 76/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Tranquilla
- Stack tecnologico
- go
- Ambito
- operating-systems
Direzione di ricerca
Inizia da pkg/unikontainers/unikernels/linux.go, leggendo parseCmdLine() insieme a CommandString() e alla riproduzione citata. Segui come Process.Args diventa il parametro di avvio init= del guest, quindi verifica che gli argomenti contenenti sia spazi bianchi sia un apostrofo singolo rimangano recuperabili da urunit senza modificare gli altri argomenti. Il lavoro è completato quando il caso riprodotto del unikernel Linux preserva i confini originali degli argomenti oppure restituisce un errore chiaro.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
What happened:
When urunc runs a Linux-based unikernel guest (the linux unikernel type, driven by the urunit init process), it builds the guest's init= boot-parameter string by joining Process.Args from the OCI spec. To let urunit recover which whitespace-separated tokens belong to one original argument, parseCmdLine() wraps any argument containing a space in single quotes, via plain string concatenation, with no escaping of quote characters already present in the argument.
Root cause:
pkg/unikontainers/unikernels/linux.go:248-272:
func (l *Linux) parseCmdLine(cmdLine []string) error {
if len(cmdLine) == 0 {
return fmt.Errorf("no init was specified")
}
// Wrap multi-word arguments in quotes for urunit compatibility.
normalizedArgs := make([]string, len(cmdLine))
for i, arg := range cmdLine {
arg = strings.TrimSpace(arg)
if strings.Contains(arg, " ") {
normalizedArgs[i] = "'" + arg + "'"
} else {
normalizedArgs[i] = arg
}
}
l.App = normalizedArgs[0]
if len(normalizedArgs) > 1 {
l.Command = strings.Join(normalizedArgs[1:], " ")
} else {
l.Command = ""
}
return nil
}
l.App/l.Command are then concatenated unescaped into the guest kernel boot parameters in CommandString() at pkg/unikontainers/unikernels/linux.go:124-126:
if l.App != "" {
initParams := rdinit + "init=" + l.App + " -- " + l.Command
bootParams += " " + initParams
}
If an argument contains both a space and a single quote, for example sh -c "echo it's fine", the naive "'" + arg + "'" wrap produces 'echo it's fine', an unbalanced 3-quote sequence instead of 2. This corrupts the quote-delimited token stream urunit parses out of /proc/cmdline to reconstruct argv for the guest's init process.
What you expected to happen:
Arguments containing a single quote should be safely escaped when embedded in the boot cmdline (or rejected with a clear error), so the guest's init process always receives exactly the arguments the user specified.
How to reproduce:
- Build a Linux-unikernel-type urunc container (bima image using
urunitas init) with an OCI specprocess.argsentry containing a space and a single quote, e.g.["/urunit", "sh", "-c", "echo it's broken"]. - Run the container with
urunc create/urunc run. - Inspect the guest's
/proc/cmdline(or the argv urunit actually launches): theinit=... -- ...segment contains'sh' 'echo it's broken', an unbalanced quote sequence, instead of the two intended tokens. - Observe urunit either fails to parse the cmdline correctly or launches init with a different, wrong argument split than what was configured.
Impact:
Silent corruption of the command actually executed inside Linux-based unikernel guests whenever a workload's argument legitimately contains a single quote alongside whitespace (a common shell pattern, e.g. sh -c "it's ..."). Because the corrupted string is image-author-controlled and unescaped in a token-boundary-sensitive parser, the damage isn't confined to that one argument's text, it shifts where the parser believes subsequent arguments start and end, so containers can run the wrong command with no error surfaced to the user.
Suggested fix:
Escape embedded single quotes when wrapping an argument (shell-style ' to '\''), or reject arguments containing quote characters with a clear error until proper escaping is implemented.
Environment:
- urunc version: main branch
- Hypervisor backend: any hypervisor used with the
linuxunikernel type (QEMU, Firecracker, Cloud Hypervisor), the bug is in the shared guest driver, not hypervisor-specific code - OS: Linux
PROOF IT IS REAL:
- Verified current code directly:
pkg/unikontainers/unikernels/linux.golines 248-272 (parseCmdLine) and 124-126 (CommandString) match exactly as quoted above, no escaping of quote characters exists anywhere in the file, onlystrings.TrimSpace. - This is distinct from the closed issue #666 ("QEMU Command Injection via OCI Annotation causing args.Command Split on Spaces"), which concerned
pkg/unikontainers/hypervisors/qemu.go'sBuildExecCmdsplittingcmdStringby spaces, confirmed that code now appendsargs.Commandas a single unsplit argument to-append, so that issue is already fixed and unrelated to this one, which is about howargs.Command's content gets built in the first place. - Not one of the 5 pre-existing local fix branches (tap fd leak, mountinfo unescape, pivot_root decision, block-volume rollback, exec-stub Argo hang), none touch
pkg/unikontainers/unikernels/. - Duplicate searches against open/closed issues and open/merged PRs for
parseCmdLine,normalizedArgs,wrap multi-word,quoting,single quote,escape argument,urunitreturned no matching prior report (only unrelated urunit topics like rlimits, graceful shutdown, and #666 above).
- Lingua principale
- Go
- Stelle
- 307
- Fork
- 219
- Merge medio
- 1g 19h
- PR unite (30g)
- 32
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di urunc-dev/urunc
-
Containers handed over to runc cannot be started, killed or deleted when urunc runs without --rootForse di nuovo libera @Daksha1611 l’ha presa 7 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
urunc-dev/urunc#1127 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
urunc-deploy cleanup never labels the node, so the cleanup DaemonSet does not runForse già presa @Sarthak-Shreshtha01 l’ha presa 9 giorni fa. Apertabug K8s/Tools
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
I maintainer di solito rispondono entro 1 giorno
-
FreeBSD: docs update and rootfs detectionForse già presa @yug105 l’ha presa 4 giorni fa. Apertadocumentation enhancement Storage
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
urunc-dev/urunc#1108 · 6 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Rumprun guests receive &, < and > as \u0026, \u003c and \u003eForse già presa @Sarthak-Shreshtha01 l’ha presa 15 giorni fa. Apertabug Guests
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
urunc-dev/urunc#1074 · 4 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Hooks run concurrently instead of in the listed orderForse già presa @anishmehta24 l’ha presa 20 giorni fa. ApertaCore enhancement OCI
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
urunc-dev/urunc#1066 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di urunc-dev/urunc
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
blinklabs-io/dingo#5636 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
JetBrains/youtrack-cli#130 ·
I maintainer di solito rispondono entro 1 giorno
-
kind/bug needs-triage sig/release
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
kubernetes/kubernetes#143392 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 61/100
I maintainer di solito rispondono entro 1 giorno
-
stage-fail
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
siyuan-note/bazaar#2405 ·
I maintainer di solito rispondono entro 1 giorno