From 56c6a9ac077c6e7823a82803aaed5305a36f39b8 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Mon, 27 May 2024 15:05:43 +0200 Subject: [PATCH] libnetwork: fix rexec env check for rootlessnetns For some unknown reason the podman container image sets the _CONTAINERS_USERNS_CONFIGURED env to an empty value. I don't know what the purpose of this is but is will trigger the check here which is wrong when the container is privileged. To fix this check that the value is set to done like it is by the reexec logic. Also make sure the lock dir uses the same condition to stay consistent. Fixes containers/podman#22791 Signed-off-by: Paul Holzinger --- common/libnetwork/cni/network.go | 24 ++++++++++++++--------- common/libnetwork/netavark/network.go | 28 ++++++++++++++------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/common/libnetwork/cni/network.go b/common/libnetwork/cni/network.go index 94d13f7a0f..7e001fab0e 100644 --- a/common/libnetwork/cni/network.go +++ b/common/libnetwork/cni/network.go @@ -82,9 +82,23 @@ type InitConfig struct { // NewCNINetworkInterface creates the ContainerNetwork interface for the CNI backend. // Note: The networks are not loaded from disk until a method is called. func NewCNINetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { + var netns *rootlessnetns.Netns + var err error + // Do not use unshare.IsRootless() here. We only care if we are running re-exec in the userns, + // IsRootless() also returns true if we are root in a userns which is not what we care about and + // causes issues as this slower more complicated rootless-netns logic should not be used as root. + val, ok := os.LookupEnv(unshare.UsernsEnvName) + useRootlessNetns := ok && val == "done" + if useRootlessNetns { + netns, err = rootlessnetns.New(conf.RunDir, rootlessnetns.CNI, conf.Config) + if err != nil { + return nil, err + } + } + // root needs to use a globally unique lock because there is only one host netns lockPath := defaultRootLockPath - if unshare.IsRootless() { + if useRootlessNetns { lockPath = filepath.Join(conf.CNIConfigDir, "cni.lock") } @@ -112,14 +126,6 @@ func NewCNINetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { defaultSubnetPools = config.DefaultSubnetPools } - var netns *rootlessnetns.Netns - if unshare.IsRootless() { - netns, err = rootlessnetns.New(conf.RunDir, rootlessnetns.CNI, conf.Config) - if err != nil { - return nil, err - } - } - cni := libcni.NewCNIConfig(conf.Config.Network.CNIPluginDirs.Values, &cniExec{}) n := &cniNetwork{ cniConfigDir: conf.CNIConfigDir, diff --git a/common/libnetwork/netavark/network.go b/common/libnetwork/netavark/network.go index d79fdff43a..6ec4a9d15b 100644 --- a/common/libnetwork/netavark/network.go +++ b/common/libnetwork/netavark/network.go @@ -96,9 +96,23 @@ type InitConfig struct { // NewNetworkInterface creates the ContainerNetwork interface for the netavark backend. // Note: The networks are not loaded from disk until a method is called. func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { + var netns *rootlessnetns.Netns + var err error + // Do not use unshare.IsRootless() here. We only care if we are running re-exec in the userns, + // IsRootless() also returns true if we are root in a userns which is not what we care about and + // causes issues as this slower more complicated rootless-netns logic should not be used as root. + val, ok := os.LookupEnv(unshare.UsernsEnvName) + useRootlessNetns := ok && val == "done" + if useRootlessNetns { + netns, err = rootlessnetns.New(conf.NetworkRunDir, rootlessnetns.Netavark, conf.Config) + if err != nil { + return nil, err + } + } + // root needs to use a globally unique lock because there is only one host netns lockPath := defaultRootLockPath - if unshare.IsRootless() { + if useRootlessNetns { lockPath = filepath.Join(conf.NetworkConfigDir, "netavark.lock") } @@ -134,18 +148,6 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { defaultSubnetPools = config.DefaultSubnetPools } - var netns *rootlessnetns.Netns - // Do not use unshare.IsRootless() here. We only care if we are running re-exec in the userns, - // IsRootless() also returns true if we are root in a userns which is not what we care about and - // causes issues as this slower more complicated rootless-netns logic should not be used as root. - _, useRootlessNetns := os.LookupEnv(unshare.UsernsEnvName) - if useRootlessNetns { - netns, err = rootlessnetns.New(conf.NetworkRunDir, rootlessnetns.Netavark, conf.Config) - if err != nil { - return nil, err - } - } - n := &netavarkNetwork{ networkConfigDir: conf.NetworkConfigDir, networkRunDir: conf.NetworkRunDir,