libnetwork/rootlessnetns: make mountns tree private

While this is a none issue normally because we run in a unprivileged
userns we cannot modify the host mounts in any way. However in case
where the rootless netns logic might be executed from a non userns
context we might change the mount tree if the mounts are shared which is
the systemd default. While this should never happen let's make sure we
never mess up the system by accident in case there are more bugs and
explicitly make our mount tree private.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger 2024-04-02 18:30:13 +02:00
parent 8b4ecddf95
commit 2589ef49aa
2 changed files with 9 additions and 2 deletions

View File

@ -5,7 +5,7 @@
skip = ./vendor,./.git #,bin,vendor,.git,go.sum,changelog.txt,.cirrus.yml,"RELEASE_NOTES.md,*.xz,*.gz,*.tar,*.tgz,bin2img,*ico,*.png,*.1,*.5,copyimg,*.orig,apidoc.go" skip = ./vendor,./.git #,bin,vendor,.git,go.sum,changelog.txt,.cirrus.yml,"RELEASE_NOTES.md,*.xz,*.gz,*.tar,*.tgz,bin2img,*ico,*.png,*.1,*.5,copyimg,*.orig,apidoc.go"
# Comma separated list of words to be ignored. Words must be lowercased. # Comma separated list of words to be ignored. Words must be lowercased.
ignore-words-list = clos,creat,ro,hastable,shouldnot ignore-words-list = clos,creat,ro,hastable,shouldnot,mountns
# Custom dictionary file that contains spelling corrections. # Custom dictionary file that contains spelling corrections.
# Run with option '--dictionary=-' to include also default dictionary. # Run with option '--dictionary=-' to include also default dictionary.

View File

@ -315,6 +315,13 @@ func (n *Netns) setupMounts() error {
return wrapError("create new mount namespace", err) return wrapError("create new mount namespace", err)
} }
// Ensure we mount private in our mountns to prevent accidentally
// overwriting the host mounts in case the default propagation is shared.
err = unix.Mount("", "/", "", unix.MS_PRIVATE|unix.MS_REC, "")
if err != nil {
return wrapError("make tree private in new mount namespace", err)
}
xdgRuntimeDir, err := homedir.GetRuntimeDir() xdgRuntimeDir, err := homedir.GetRuntimeDir()
if err != nil { if err != nil {
return fmt.Errorf("could not get runtime directory: %w", err) return fmt.Errorf("could not get runtime directory: %w", err)
@ -322,7 +329,7 @@ func (n *Netns) setupMounts() error {
newXDGRuntimeDir := n.getPath(xdgRuntimeDir) newXDGRuntimeDir := n.getPath(xdgRuntimeDir)
// 1. Mount the netns into the new run to keep them accessible. // 1. Mount the netns into the new run to keep them accessible.
// Otherwise cni setup will fail because it cannot access the netns files. // Otherwise cni setup will fail because it cannot access the netns files.
err = mountAndMkdirDest(xdgRuntimeDir, newXDGRuntimeDir, none, unix.MS_BIND|unix.MS_SHARED|unix.MS_REC) err = mountAndMkdirDest(xdgRuntimeDir, newXDGRuntimeDir, none, unix.MS_BIND|unix.MS_REC)
if err != nil { if err != nil {
return err return err
} }