Skip to content

Commit b24c9ea

Browse files
fix(relay): apply host Unix socket permissions
1 parent 72298de commit b24c9ea

2 files changed

Lines changed: 50 additions & 7 deletions

File tree

‎Sources/Containerization/UnixSocketRelay.swift‎

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,7 @@ extension UnixSocketRelay {
9090

9191
private func setupHostVsockDial() async throws {
9292
let hostConn = configuration.destination
93-
94-
let socketType = try UnixType(
95-
path: hostConn.path,
96-
unlinkExisting: true
97-
)
98-
let hostSocket = try Socket(type: socketType)
99-
try hostSocket.listen()
93+
let hostSocket = try Self.makeHostListener(configuration)
10094

10195
log?.info(
10296
"listening on host UDS",
@@ -130,6 +124,26 @@ extension UnixSocketRelay {
130124
}
131125
}
132126

127+
package static func makeHostListener(
128+
_ configuration: UnixSocketConfiguration
129+
) throws -> Socket {
130+
let socketType = try UnixType(
131+
path: configuration.destination.path,
132+
perms: configuration.permissions.map {
133+
mode_t($0.rawValue)
134+
},
135+
unlinkExisting: true
136+
)
137+
let socket = try Socket(type: socketType)
138+
do {
139+
try socket.listen()
140+
return socket
141+
} catch {
142+
try? socket.close()
143+
throw error
144+
}
145+
}
146+
133147
private func setupHostVsockListener() throws {
134148
let hostPath = configuration.source
135149

‎Tests/ContainerizationTests/UnixSocketRelayTests.swift‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,35 @@ import Musl
3131
#endif
3232

3333
struct UnixSocketRelayTests {
34+
@Test
35+
func outOfRelayAppliesRequestedHostSocketPermissions() throws {
36+
let root = URL(fileURLWithPath: "/tmp").appendingPathComponent(
37+
"containerization-relay-\(UUID())",
38+
isDirectory: true
39+
)
40+
try FileManager.default.createDirectory(
41+
at: root,
42+
withIntermediateDirectories: true
43+
)
44+
defer { try? FileManager.default.removeItem(at: root) }
45+
let socketPath = root.appendingPathComponent("service.sock")
46+
let configuration = UnixSocketConfiguration(
47+
source: URL(fileURLWithPath: "/run/service.sock"),
48+
destination: socketPath,
49+
permissions: .init(rawValue: 0o600),
50+
direction: .outOf
51+
)
52+
53+
let listener = try UnixSocketRelay.makeHostListener(configuration)
54+
defer { try? listener.close() }
55+
let permissions = try #require(
56+
FileManager.default.attributesOfItem(atPath: socketPath.path)[
57+
.posixPermissions
58+
] as? NSNumber
59+
)
60+
#expect(permissions.uint16Value == 0o600)
61+
}
62+
3463
private func socketPair() throws -> (connection: FileHandle, peer: FileHandle) {
3564
var fds: [Int32] = [-1, -1]
3665
#if canImport(Glibc)

0 commit comments

Comments
 (0)