mirror of
				https://github.com/NVIDIA/nvidia-container-toolkit
				synced 2025-06-26 18:18:24 +00:00 
			
		
		
		
	Extend fields we inspect in the runc spec to include linux capabilities
This also includes a helper to look through the capabilities contained in the spec to determine if the container is privileged or not. Signed-off-by: Kevin Klues <kklues@nvidia.com>
This commit is contained in:
		
							parent
							
								
									d4ff0416d8
								
							
						
					
					
						commit
						05012e7b7f
					
				| @ -26,6 +26,10 @@ const ( | |||||||
| 	defaultDriverCapabilities = "utility" | 	defaultDriverCapabilities = "utility" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const ( | ||||||
|  | 	capSysAdmin = "CAP_SYS_ADMIN" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| type nvidiaConfig struct { | type nvidiaConfig struct { | ||||||
| 	Devices            string | 	Devices            string | ||||||
| 	DriverCapabilities string | 	DriverCapabilities string | ||||||
| @ -47,7 +51,17 @@ type Root struct { | |||||||
| 
 | 
 | ||||||
| // github.com/opencontainers/runtime-spec/blob/v1.0.0/specs-go/config.go#L30-L57
 | // github.com/opencontainers/runtime-spec/blob/v1.0.0/specs-go/config.go#L30-L57
 | ||||||
| type Process struct { | type Process struct { | ||||||
| 	Env []string `json:"env,omitempty"` | 	Env          []string           `json:"env,omitempty"` | ||||||
|  | 	Capabilities *LinuxCapabilities `json:"capabilities,omitempty" platform:"linux"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // https://github.com/opencontainers/runtime-spec/blob/v1.0.0/specs-go/config.go#L61
 | ||||||
|  | type LinuxCapabilities struct { | ||||||
|  | 	Bounding    []string `json:"bounding,omitempty" platform:"linux"` | ||||||
|  | 	Effective   []string `json:"effective,omitempty" platform:"linux"` | ||||||
|  | 	Inheritable []string `json:"inheritable,omitempty" platform:"linux"` | ||||||
|  | 	Permitted   []string `json:"permitted,omitempty" platform:"linux"` | ||||||
|  | 	Ambient     []string `json:"ambient,omitempty" platform:"linux"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // We use pointers to structs, similarly to the latest version of runtime-spec:
 | // We use pointers to structs, similarly to the latest version of runtime-spec:
 | ||||||
| @ -124,6 +138,31 @@ func loadSpec(path string) (spec *Spec) { | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func isPrivileged(caps *LinuxCapabilities) bool { | ||||||
|  | 	if caps == nil { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	hasCapSysAdmin := func(caps []string) bool { | ||||||
|  | 		for _, c := range caps { | ||||||
|  | 			if c == capSysAdmin { | ||||||
|  | 				return true | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// We only make sure that the bounding capabibility set has
 | ||||||
|  | 	// CAP_SYS_ADMIN. This allows us to make sure that the container was
 | ||||||
|  | 	// actually started as '--privileged', but also allow non-root users to
 | ||||||
|  | 	// access the priviliged NVIDIA capabilities.
 | ||||||
|  | 	if !hasCapSysAdmin(caps.Bounding) { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func getDevices(env map[string]string) *string { | func getDevices(env map[string]string) *string { | ||||||
| 	gpuVars := []string{envNVVisibleDevices} | 	gpuVars := []string{envNVVisibleDevices} | ||||||
| 	if envSwarmGPU != nil { | 	if envSwarmGPU != nil { | ||||||
| @ -158,7 +197,7 @@ func getRequirements(env map[string]string) []string { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Mimic the new CUDA images if no capabilities or devices are specified.
 | // Mimic the new CUDA images if no capabilities or devices are specified.
 | ||||||
| func getNvidiaConfigLegacy(env map[string]string) *nvidiaConfig { | func getNvidiaConfigLegacy(env map[string]string, privileged bool) *nvidiaConfig { | ||||||
| 	var devices string | 	var devices string | ||||||
| 	if d := getDevices(env); d == nil { | 	if d := getDevices(env); d == nil { | ||||||
| 		// Environment variable unset: default to "all".
 | 		// Environment variable unset: default to "all".
 | ||||||
| @ -200,18 +239,20 @@ func getNvidiaConfigLegacy(env map[string]string) *nvidiaConfig { | |||||||
| 
 | 
 | ||||||
| 	return &nvidiaConfig{ | 	return &nvidiaConfig{ | ||||||
| 		Devices:            devices, | 		Devices:            devices, | ||||||
|  | 		MigConfigDevices:   migConfigDevices, | ||||||
|  | 		MigMonitorDevices:  migMonitorDevices, | ||||||
| 		DriverCapabilities: driverCapabilities, | 		DriverCapabilities: driverCapabilities, | ||||||
| 		Requirements:       requirements, | 		Requirements:       requirements, | ||||||
| 		DisableRequire:     disableRequire, | 		DisableRequire:     disableRequire, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func getNvidiaConfig(env map[string]string) *nvidiaConfig { | func getNvidiaConfig(env map[string]string, privileged bool) *nvidiaConfig { | ||||||
| 	legacyCudaVersion := env[envCUDAVersion] | 	legacyCudaVersion := env[envCUDAVersion] | ||||||
| 	cudaRequire := env[envNVRequireCUDA] | 	cudaRequire := env[envNVRequireCUDA] | ||||||
| 	if len(legacyCudaVersion) > 0 && len(cudaRequire) == 0 { | 	if len(legacyCudaVersion) > 0 && len(cudaRequire) == 0 { | ||||||
| 		// Legacy CUDA image detected.
 | 		// Legacy CUDA image detected.
 | ||||||
| 		return getNvidiaConfigLegacy(env) | 		return getNvidiaConfigLegacy(env, privileged) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var devices string | 	var devices string | ||||||
| @ -266,11 +307,12 @@ func getContainerConfig(hook HookConfig) (config containerConfig) { | |||||||
| 	s := loadSpec(path.Join(b, "config.json")) | 	s := loadSpec(path.Join(b, "config.json")) | ||||||
| 
 | 
 | ||||||
| 	env := getEnvMap(s.Process.Env, hook.NvidiaContainerCLI) | 	env := getEnvMap(s.Process.Env, hook.NvidiaContainerCLI) | ||||||
|  | 	privileged := isPrivileged(s.Process.Capabilities) | ||||||
| 	envSwarmGPU = hook.SwarmResource | 	envSwarmGPU = hook.SwarmResource | ||||||
| 	return containerConfig{ | 	return containerConfig{ | ||||||
| 		Pid:    h.Pid, | 		Pid:    h.Pid, | ||||||
| 		Rootfs: s.Root.Path, | 		Rootfs: s.Root.Path, | ||||||
| 		Env:    env, | 		Env:    env, | ||||||
| 		Nvidia: getNvidiaConfig(env), | 		Nvidia: getNvidiaConfig(env, privileged), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user