Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SETUID/SETGID not required for changing user #6083

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 21 additions & 3 deletions pkg/libcontainer/nsinit/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,33 @@ func setupNetwork(container *libcontainer.Container, context libcontainer.Contex
// and working dir, and closes any leaky file descriptors
// before execing the command inside the namespace
func FinalizeNamespace(container *libcontainer.Container) error {
if err := capabilities.DropCapabilities(container); err != nil {
return fmt.Errorf("drop capabilities %s", err)
}
if err := system.CloseFdsFrom(3); err != nil {
return fmt.Errorf("close open file descriptors %s", err)
}

// drop capabilities in bounding set before changing user
if err := capabilities.DropBoundingSet(container); err != nil {
return fmt.Errorf("drop bounding set %s", err)
}

// preserve existing capabilities while we change users
if err := system.SetKeepCaps(); err != nil {
return fmt.Errorf("set keep caps %s", err)
}

if err := SetupUser(container.User); err != nil {
return fmt.Errorf("setup user %s", err)
}

if err := system.ClearKeepCaps(); err != nil {
return fmt.Errorf("clear keep caps %s", err)
}

// drop all other capabilities
if err := capabilities.DropCapabilities(container); err != nil {
return fmt.Errorf("drop capabilities %s", err)
}

if container.WorkingDir != "" {
if err := system.Chdir(container.WorkingDir); err != nil {
return fmt.Errorf("chdir to %s %s", container.WorkingDir, err)
Expand Down
19 changes: 19 additions & 0 deletions pkg/libcontainer/security/capabilities/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ import (

const allCapabilityTypes = capability.CAPS | capability.BOUNDS

// DropBoundingSet drops the capability bounding set to those specified in the
// container configuration.
func DropBoundingSet(container *libcontainer.Container) error {
c, err := capability.NewPid(os.Getpid())
if err != nil {
return err
}

keep := getEnabledCapabilities(container)
c.Clear(capability.BOUNDS)
c.Set(capability.BOUNDS, keep...)

if err := c.Apply(capability.BOUNDS); err != nil {
return err
}

return nil
}

// DropCapabilities drops all capabilities for the current process expect those specified in the container configuration.
func DropCapabilities(container *libcontainer.Container) error {
c, err := capability.NewPid(os.Getpid())
Expand Down
16 changes: 16 additions & 0 deletions pkg/system/calls_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ func GetParentDeathSignal() (int, error) {
return sig, nil
}

func SetKeepCaps() error {
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 1, 0); err != 0 {
return err
}

return nil
}

func ClearKeepCaps() error {
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 0, 0); err != 0 {
return err
}

return nil
}

func Setctty() error {
if _, _, err := syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0); err != 0 {
return err
Expand Down