diff --git a/CHANGELOG.md b/CHANGELOG.md index 76874f4d41..062ea24ba1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - Fix regression from 4.1.5 that overwrites source image runscript, environment etc. in build from local image. +- Avoid error in CNI network setup with newer versions of iptables that include + a setuid caller check. ## 4.2.1 \[2024-09-13\] diff --git a/internal/pkg/runtime/engine/singularity/cleanup_linux.go b/internal/pkg/runtime/engine/singularity/cleanup_linux.go index baf888546c..86f4c79ee2 100644 --- a/internal/pkg/runtime/engine/singularity/cleanup_linux.go +++ b/internal/pkg/runtime/engine/singularity/cleanup_linux.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2021, Sylabs Inc. All rights reserved. +// Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. // This software is licensed under a 3-clause BSD license. Please consult the // LICENSE.md file distributed with the sources of this project regarding your // rights to use or distribute this software. @@ -77,7 +77,7 @@ func (e *EngineOperations) CleanupContainer(ctx context.Context, _ error, _ sysc privileged := false // If a CNI configuration was allowed as non-root (or fakeroot) if net != "none" && os.Geteuid() != 0 { - priv.Escalate() + priv.EscalateRealEffective() privileged = true } sylog.Debugf("Cleaning up CNI network config %s", net) diff --git a/internal/pkg/runtime/engine/singularity/container_linux.go b/internal/pkg/runtime/engine/singularity/container_linux.go index e09e227e13..16d50a6377 100644 --- a/internal/pkg/runtime/engine/singularity/container_linux.go +++ b/internal/pkg/runtime/engine/singularity/container_linux.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2023, Sylabs Inc. All rights reserved. +// Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. // Copyright (c) Contributors to the Apptainer project, established as // Apptainer a Series of LF Projects LLC. // This software is licensed under a 3-clause BSD license. Please consult the @@ -2398,7 +2398,7 @@ func (c *container) prepareNetworkSetup(system *mount.System, pid int) (func(con } } if euid != 0 { - priv.Escalate() + priv.EscalateRealEffective() defer priv.Drop() } } diff --git a/internal/pkg/util/priv/priv_linux.go b/internal/pkg/util/priv/priv_linux.go index 59ba5baa93..bfe3967235 100644 --- a/internal/pkg/util/priv/priv_linux.go +++ b/internal/pkg/util/priv/priv_linux.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2022, Sylabs Inc. All rights reserved. +// Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. // This software is licensed under a 3-clause BSD license. Please consult the // LICENSE.md file distributed with the sources of this project regarding your // rights to use or distribute this software. @@ -6,25 +6,32 @@ package priv import ( - "os" "runtime" "syscall" + + "github.com/sylabs/singularity/v4/pkg/sylog" + "golang.org/x/sys/unix" ) -// Escalate escalates privileges of the thread or process. -// Since Go 1.16 syscall.Setresuid is an all-thread operation. -// A runtime.LockOSThread operation remains for older versions of Go. -func Escalate() error { +// EscalateRealEffective escalates real and effective uid of the thread or +// process to root (0). The current real uid is set as the saved set-user-ID. +// Since Go 1.16 syscall.Setresuid is an all-thread operation. A +// runtime.LockOSThread operation remains for older versions of Go. +func EscalateRealEffective() error { runtime.LockOSThread() - uid := os.Getuid() - return syscall.Setresuid(uid, 0, uid) + uid, _, _ := unix.Getresuid() + sylog.Debugf("Escalate r/e/s: %d/%d/%d", 0, 0, uid) + return syscall.Setresuid(0, 0, uid) } -// Drop drops privileges of the thread or process. -// Since Go 1.16 syscall.Setresuid is an all-thread operation. -// A runtime.LockOSThread operation remains for older versions of Go. +// Drop drops privileges of the thread or process. The real and effective uid +// are set to the value of the saved set-user-ID. The saved set-user-ID is +// returned to 0 to allow escalation in future. Since Go 1.16 syscall.Setresuid +// is an all-thread operation. A runtime.LockOSThread operation remains for +// older versions of Go. func Drop() error { defer runtime.UnlockOSThread() - uid := os.Getuid() + _, _, uid := unix.Getresuid() + sylog.Debugf("Drop r/e/s: %d/%d/%d", uid, uid, 0) return syscall.Setresuid(uid, uid, 0) } diff --git a/pkg/network/network_linux.go b/pkg/network/network_linux.go index b9a74134e1..5b214b79ad 100644 --- a/pkg/network/network_linux.go +++ b/pkg/network/network_linux.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019, Sylabs Inc. All rights reserved. +// Copyright (c) 2018-2024, Sylabs Inc. All rights reserved. // This software is licensed under a 3-clause BSD license. Please consult the // LICENSE.md file distributed with the sources of this project regarding your // rights to use or distribute this software. @@ -22,6 +22,7 @@ import ( cnitypes "github.com/containernetworking/cni/pkg/types/100" "github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator" "github.com/sylabs/singularity/v4/internal/pkg/util/env" + "github.com/sylabs/singularity/v4/pkg/sylog" ) type netError string @@ -451,12 +452,15 @@ func (m *Setup) DelNetworks(ctx context.Context) error { } func (m *Setup) command(ctx context.Context, command string) error { - if m.envPath != "" { - backupEnv := os.Environ() - os.Clearenv() - os.Setenv("PATH", m.envPath) - defer env.SetFromList(backupEnv) + if m.envPath == "" { + sylog.Debugf("Network envPath is unset. Setting PATH to a safe default.") + m.envPath = "/bin:/sbin:/usr/bin:/usr/sbin" } + sylog.Debugf("Network envPath: %s", m.envPath) + backupEnv := os.Environ() + os.Clearenv() + os.Setenv("PATH", m.envPath) + defer env.SetFromList(backupEnv) config := &libcni.CNIConfig{Path: []string{m.cniPath.Plugin}}