From ef20c9dc1909296ee67b3cd477d3d58c30d74e16 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Mon, 15 May 2023 13:50:48 -0700 Subject: [PATCH] Drop capabilities when they are not needed Without this fix, the sandbox process continues running with CAP_SYS_ADMIN and CAP_CHROOT: CapInh: 0000000000240000 CapPrm: 0000000000240000 CapEff: 0000000000240000 CapBnd: 000001ffffffffff CapAmb: 0000000000240000 We need to add CAP_SETPCAP to be able to clean the bounding set. Unfortunately, gocapability doesn't report an error in this case: https://github.com/syndtr/gocapability/blob/master/capability/capability_linux.go#L446 PiperOrigin-RevId: 532214156 --- runsc/cmd/cmd.go | 4 ++++ runsc/sandbox/sandbox.go | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/runsc/cmd/cmd.go b/runsc/cmd/cmd.go index 3c726bd24..a46dc0e55 100644 --- a/runsc/cmd/cmd.go +++ b/runsc/cmd/cmd.go @@ -89,6 +89,10 @@ func callSelfAsNobody(args []string) error { if _, _, err := unix.RawSyscall(unix.SYS_SETUID, uintptr(nobody), 0, 0); err != 0 { return fmt.Errorf("error setting gid: %v", err) } + // Drop all capabilities. + if err := applyCaps(&specs.LinuxCapabilities{}); err != nil { + return fmt.Errorf("error dropping capabilities: %w", err) + } binPath := specutils.ExePath diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 1703e4f7f..91f530005 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -881,7 +881,12 @@ func (s *Sandbox) createSandboxProcess(conf *config.Config, args *Args, startSyn // A sandbox process will construct an empty root for itself, so it has // to have CAP_SYS_ADMIN and CAP_SYS_CHROOT capabilities. - cmd.SysProcAttr.AmbientCaps = append(cmd.SysProcAttr.AmbientCaps, uintptr(capability.CAP_SYS_ADMIN), uintptr(capability.CAP_SYS_CHROOT)) + cmd.SysProcAttr.AmbientCaps = append(cmd.SysProcAttr.AmbientCaps, + uintptr(capability.CAP_SYS_ADMIN), + uintptr(capability.CAP_SYS_CHROOT), + // CAP_SETPCAP is required to clear the bounding set. + uintptr(capability.CAP_SETPCAP), + ) } else { return fmt.Errorf("can't run sandbox process as user nobody since we don't have CAP_SETUID or CAP_SETGID")