Skip to content

Commit e283e02

Browse files
Use container's environment when starting the init process (#329)
Fixes an issue first described in apple/container#740. Previously the initial process of the container was using vminitd's environment variables to find the target executable. This PR updates the code to use the container's configured environment for the initial process instead. The behavior of an exec in a container should be the same as before. Signed-off-by: Kathryn Baldauf <[email protected]>
1 parent 6e96cdb commit e283e02

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

Sources/ContainerizationOS/Path.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ import Foundation
2121
public struct Path {
2222
/// lookPath looks up an executable's path from $PATH
2323
public static func lookPath(_ name: String) -> URL? {
24-
lookup(name, path: getPath())
24+
lookup(name, path: getCurrentPath())
25+
}
26+
27+
public static func lookPath(_ name: String, path: String) -> URL? {
28+
lookup(name, path: path)
2529
}
2630

2731
// getEnv returns the default environment of the process
2832
// with the default $PATH added for the context of a macOS application bundle
2933
public static func getEnv() -> [String: String] {
3034
var env = ProcessInfo.processInfo.environment
31-
env["PATH"] = getPath()
35+
env["PATH"] = getCurrentPath()
3236
return env
3337
}
3438

@@ -58,14 +62,17 @@ public struct Path {
5862
}
5963

6064
/// getPath returns $PATH for the current process
61-
private static func getPath() -> String {
65+
public static func getCurrentPath() -> String {
6266
let env = ProcessInfo.processInfo.environment
6367
return env["PATH"] ?? "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
6468
}
6569

6670
// findPath returns a string containing the 'PATH' environment variable
67-
private static func findPath(_ env: [String]) -> String? {
68-
env.first(where: { path in
71+
public static func findPath(_ env: [String]?) -> String? {
72+
guard let env = env else {
73+
return nil
74+
}
75+
return env.first(where: { path in
6976
let split = path.split(separator: "=")
7077
return split.count == 2 && split[0] == "PATH"
7178
})

vminitd/Sources/vmexec/RunCommand.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ struct RunCommand: ParsableCommand {
138138
try App.setPermissions(user: process.user)
139139

140140
// Finally execve the container process.
141-
try App.exec(process: process)
141+
try App.exec(process: process, currentEnv: process.env)
142142
}
143143

144144
private func execInNamespace(spec: ContainerizationOCI.Spec, log: Logger) throws {

vminitd/Sources/vmexec/vmexec.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import ArgumentParser
2323
import ContainerizationError
2424
import ContainerizationOCI
25+
import ContainerizationOS
2526
import Foundation
2627
import LCShim
2728
import Logging
@@ -71,8 +72,14 @@ extension App {
7172
}
7273
}
7374

74-
static func exec(process: ContainerizationOCI.Process) throws {
75-
let executable = strdup(process.args[0])
75+
static func exec(process: ContainerizationOCI.Process, currentEnv: [String]? = nil) throws {
76+
// lookup executable
77+
let path = Path.findPath(currentEnv) ?? Path.getCurrentPath()
78+
guard let resolvedExecutable = Path.lookPath(process.args[0], path: path) else {
79+
throw App.Failure(message: "Failed to find target executable \(process.args[0])")
80+
}
81+
82+
let executable = strdup(resolvedExecutable.path())
7683
var argv = process.args.map { strdup($0) }
7784
argv += [nil]
7885

0 commit comments

Comments
 (0)