From cbc03d7040681a6a737300473ca0d9092208a746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=84=B1=EA=B7=BC?= <117553364+ParkSeongGeun@users.noreply.github.com> Date: Mon, 12 Jan 2026 11:15:18 +0900 Subject: [PATCH] Fix: resolve relative executable paths against workingDirectory in vmexec (#473) - Fixes the root cause for apple/container#962. Signed-off-by: ParkSeongGeun --- vminitd/Sources/vmexec/vmexec.swift | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/vminitd/Sources/vmexec/vmexec.swift b/vminitd/Sources/vmexec/vmexec.swift index 3286d4e7..99abce11 100644 --- a/vminitd/Sources/vmexec/vmexec.swift +++ b/vminitd/Sources/vmexec/vmexec.swift @@ -68,20 +68,33 @@ extension App { throw App.Errno(stage: "exec", info: "process args cannot be empty") } - // lookup executable - let path = Path.findPath(currentEnv) ?? Path.getCurrentPath() - guard let resolvedExecutable = Path.lookPath(process.args[0], path: path) else { - throw App.Failure(message: "failed to find target executable \(process.args[0])") + let executableArg = process.args[0] + let resolvedExecutable: URL + + if executableArg.contains("/") { + if executableArg.hasPrefix("/") { + resolvedExecutable = URL(fileURLWithPath: executableArg) + } else { + resolvedExecutable = URL(fileURLWithPath: process.cwd).appendingPathComponent(executableArg).standardized + } + + guard FileManager.default.fileExists(atPath: resolvedExecutable.path) else { + throw App.Failure(message: "failed to find target executable \(executableArg)") + } + } else { + let path = Path.findPath(currentEnv) ?? Path.getCurrentPath() + guard let found = Path.lookPath(executableArg, path: path) else { + throw App.Failure(message: "failed to find target executable \(executableArg)") + } + resolvedExecutable = found } - let executable = strdup(resolvedExecutable.path()) + let executable = strdup(resolvedExecutable.path) var argv = process.args.map { strdup($0) } argv += [nil] - let env = process.env.map { strdup($0) } + [nil] let cwd = process.cwd - // switch cwd guard chdir(cwd) == 0 else { throw App.Errno(stage: "chdir(cwd)", info: "failed to change directory to '\(cwd)'") }