diff --git a/Sources/ContainerizationOS/Path.swift b/Sources/ContainerizationOS/Path.swift index 0f7e2628..21a93a4f 100644 --- a/Sources/ContainerizationOS/Path.swift +++ b/Sources/ContainerizationOS/Path.swift @@ -21,14 +21,18 @@ import Foundation public struct Path { /// lookPath looks up an executable's path from $PATH public static func lookPath(_ name: String) -> URL? { - lookup(name, path: getPath()) + lookup(name, path: getCurrentPath()) + } + + public static func lookPath(_ name: String, path: String) -> URL? { + lookup(name, path: path) } // getEnv returns the default environment of the process // with the default $PATH added for the context of a macOS application bundle public static func getEnv() -> [String: String] { var env = ProcessInfo.processInfo.environment - env["PATH"] = getPath() + env["PATH"] = getCurrentPath() return env } @@ -58,14 +62,17 @@ public struct Path { } /// getPath returns $PATH for the current process - private static func getPath() -> String { + public static func getCurrentPath() -> String { let env = ProcessInfo.processInfo.environment return env["PATH"] ?? "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" } // findPath returns a string containing the 'PATH' environment variable - private static func findPath(_ env: [String]) -> String? { - env.first(where: { path in + public static func findPath(_ env: [String]?) -> String? { + guard let env = env else { + return nil + } + return env.first(where: { path in let split = path.split(separator: "=") return split.count == 2 && split[0] == "PATH" }) diff --git a/vminitd/Sources/vmexec/RunCommand.swift b/vminitd/Sources/vmexec/RunCommand.swift index 55010018..f4133ce5 100644 --- a/vminitd/Sources/vmexec/RunCommand.swift +++ b/vminitd/Sources/vmexec/RunCommand.swift @@ -138,7 +138,7 @@ struct RunCommand: ParsableCommand { try App.setPermissions(user: process.user) // Finally execve the container process. - try App.exec(process: process) + try App.exec(process: process, currentEnv: process.env) } private func execInNamespace(spec: ContainerizationOCI.Spec, log: Logger) throws { diff --git a/vminitd/Sources/vmexec/vmexec.swift b/vminitd/Sources/vmexec/vmexec.swift index 13e8e2a1..199a29ed 100644 --- a/vminitd/Sources/vmexec/vmexec.swift +++ b/vminitd/Sources/vmexec/vmexec.swift @@ -22,6 +22,7 @@ import ArgumentParser import ContainerizationError import ContainerizationOCI +import ContainerizationOS import Foundation import LCShim import Logging @@ -71,8 +72,14 @@ extension App { } } - static func exec(process: ContainerizationOCI.Process) throws { - let executable = strdup(process.args[0]) + static func exec(process: ContainerizationOCI.Process, currentEnv: [String]? = nil) throws { + // 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 executable = strdup(resolvedExecutable.path()) var argv = process.args.map { strdup($0) } argv += [nil]