Skip to content

Commit 4af1cc0

Browse files
fix: improve error message when binding to privileged ports (fixes apple#978) (apple#1031)
- The container fails to start with a generic "permission denied" error when attempting to publish privileged ports (ports below 1024) without root privileges. This provides a confusing user experience as the error doesn't explain why permission was denied.
1 parent 21facf0 commit 4af1cc0

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

Sources/Services/ContainerSandboxService/Server/SandboxService.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,17 @@ public actor SandboxService {
748748
log: self.log
749749
)
750750
}
751-
return try await forwarder.run().get()
751+
do {
752+
return try await forwarder.run().get()
753+
} catch let error as IOError where error.errnoCode == EACCES {
754+
if let port = proxyAddress.port, port < 1024 {
755+
throw ContainerizationError(
756+
.invalidArgument,
757+
message: "Permission denied while binding to host port \(port). Binding to ports below 1024 requires root privileges."
758+
)
759+
}
760+
throw error
761+
}
752762
}
753763
}
754764
}

Tests/CLITests/Subcommands/Run/TestCLIRunCommand.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,4 +712,29 @@ class TestCLIRunCommand: CLITest {
712712

713713
return trimmedOutput
714714
}
715+
716+
@Test func testPrivilegedPortError() throws {
717+
try #require(geteuid() != 0)
718+
719+
let name = getTestName()
720+
let privilegedPort = 80
721+
let (_, _, error, status) = try run(arguments: [
722+
"run",
723+
"--name", name,
724+
"--publish", "127.0.0.1:\(privilegedPort):80",
725+
alpine,
726+
])
727+
defer {
728+
try? doRemove(name: name, force: true)
729+
}
730+
#expect(status != 0, "Command should have failed")
731+
#expect(
732+
error.contains("Permission denied while binding to host port \(privilegedPort)"),
733+
"Error message should mention permission denied for the port. Got: \(error)"
734+
)
735+
#expect(
736+
error.contains("root privileges"),
737+
"Error message should mention root privileges requirement. Got: \(error)"
738+
)
739+
}
715740
}

0 commit comments

Comments
 (0)