@@ -935,6 +935,10 @@ public actor SandboxService {
935935 soft: $0. soft
936936 )
937937 }
938+ czConfig. process. capabilities = try Self . effectiveCapabilities (
939+ capAdd: config. capAdd,
940+ capDrop: config. capDrop
941+ )
938942 switch process. user {
939943 case . raw( let name) :
940944 czConfig. process. user = . init(
@@ -981,6 +985,10 @@ public actor SandboxService {
981985 soft: $0. soft
982986 )
983987 }
988+ proc. capabilities = try Self . effectiveCapabilities (
989+ capAdd: containerConfig. capAdd,
990+ capDrop: containerConfig. capDrop
991+ )
984992 switch config. user {
985993 case . raw( let name) :
986994 proc. user = . init(
@@ -1003,6 +1011,37 @@ public actor SandboxService {
10031011 return proc
10041012 }
10051013
1014+ /// Compute effective Linux capabilities from the OCI default set, capAdd, and capDrop.
1015+ /// Steps are processed in order, so later steps override earlier ones:
1016+ /// 1. If "ALL" in capDrop, start empty; otherwise start from OCI defaults.
1017+ /// 2. If "ALL" in capAdd, replace with all caps (overriding step 1); otherwise add individual caps.
1018+ /// 3. Remove individual capDrop entries (skipping "ALL" sentinel).
1019+ private static func effectiveCapabilities( capAdd: [ String] , capDrop: [ String] ) throws -> Containerization. LinuxCapabilities {
1020+ // Step 1: Determine base set
1021+ var caps : Set < CapabilityName >
1022+ if capDrop. contains ( " ALL " ) {
1023+ caps = [ ]
1024+ } else {
1025+ caps = Set ( Containerization . LinuxCapabilities. defaultOCICapabilities. effective)
1026+ }
1027+
1028+ // Step 2: Process adds
1029+ if capAdd. contains ( " ALL " ) {
1030+ caps = Set ( CapabilityName . allCases)
1031+ } else {
1032+ for name in capAdd {
1033+ caps. insert ( try CapabilityName ( rawValue: name) )
1034+ }
1035+ }
1036+
1037+ // Step 3: Remove individual drops (skip "ALL" sentinel)
1038+ for name in capDrop where name != " ALL " {
1039+ caps. remove ( try CapabilityName ( rawValue: name) )
1040+ }
1041+
1042+ return Containerization . LinuxCapabilities ( capabilities: Array ( caps) )
1043+ }
1044+
10061045 private nonisolated func closeHandle( _ handle: Int32) throws {
10071046 guard close ( handle) == 0 else {
10081047 guard let errCode = POSIXErrorCode ( rawValue: errno) else {
0 commit comments