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

[v3.3] backport rootless networking fixes #11281

Merged
merged 2 commits into from
Aug 19, 2021
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions libpod/networking_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,27 @@ func (r *RootlessCNI) Do(toRun func() error) error {
// the link target will be available in the mount ns.
// see: https://github.com/containers/podman/issues/10855
resolvePath := "/etc/resolv.conf"
resolvePath, err = filepath.EvalSymlinks(resolvePath)
if err != nil {
return err
for i := 0; i < 255; i++ {
// Do not use filepath.EvalSymlinks, we only want the first symlink under /run.
// If /etc/resolv.conf has more than one symlink under /run, e.g.
// -> /run/systemd/resolve/stub-resolv.conf -> /run/systemd/resolve/resolv.conf
// we would put the netns resolv.conf file to the last path. However this will
// break dns because the second link does not exists in the mount ns.
// see https://github.com/containers/podman/issues/11222
link, err := os.Readlink(resolvePath)
if err != nil {
// if there is no symlink exit
break
}
resolvePath = filepath.Join(filepath.Dir(resolvePath), link)
if strings.HasPrefix(resolvePath, "/run/") {
break
}
if i == 254 {
return errors.New("too many symlinks while resolving /etc/resolv.conf")
}
}
logrus.Debugf("The actual path of /etc/resolv.conf on the host is %q", resolvePath)
logrus.Debugf("The path of /etc/resolv.conf in the mount ns is %q", resolvePath)
// When /etc/resolv.conf on the host is a symlink to /run/systemd/resolve/stub-resolv.conf,
// we have to mount an empty filesystem on /run/systemd/resolve in the child namespace,
// so as to isolate the directory from the host mount namespace.
Expand Down
35 changes: 9 additions & 26 deletions pkg/rootlessport/rootlessport_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"net"
"os"
"os/exec"
"os/signal"
"path/filepath"

"github.com/containernetworking/plugins/pkg/ns"
Expand Down Expand Up @@ -106,30 +105,6 @@ func parent() error {
return err
}

exitC := make(chan os.Signal, 1)
defer close(exitC)

go func() {
sigC := make(chan os.Signal, 1)
signal.Notify(sigC, unix.SIGPIPE)
defer func() {
signal.Stop(sigC)
close(sigC)
}()

select {
case s := <-sigC:
if s == unix.SIGPIPE {
if f, err := os.OpenFile("/dev/null", os.O_WRONLY, 0755); err == nil {
unix.Dup2(int(f.Fd()), 1) // nolint:errcheck
unix.Dup2(int(f.Fd()), 2) // nolint:errcheck
f.Close()
}
}
case <-exitC:
}
}()

socketDir := filepath.Join(cfg.TmpDir, "rp")
err = os.MkdirAll(socketDir, 0700)
if err != nil {
Expand Down Expand Up @@ -251,8 +226,16 @@ outer:
go serve(socket, driver)
}

// write and close ReadyFD (convention is same as slirp4netns --ready-fd)
logrus.Info("ready")

// https://github.com/containers/podman/issues/11248
// Copy /dev/null to stdout and stderr to prevent SIGPIPE errors
if f, err := os.OpenFile("/dev/null", os.O_WRONLY, 0755); err == nil {
unix.Dup2(int(f.Fd()), 1) // nolint:errcheck
unix.Dup2(int(f.Fd()), 2) // nolint:errcheck
f.Close()
}
// write and close ReadyFD (convention is same as slirp4netns --ready-fd)
if _, err := readyW.Write([]byte("1")); err != nil {
return err
}
Expand Down
3 changes: 3 additions & 0 deletions test/system/500-networking.bats
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ load helpers
$IMAGE nc -l -n -v -p $myport
cid="$output"

# check that dns is working inside the container
run_podman exec $cid nslookup google.com

# emit random string, and check it
teststring=$(random_string 30)
echo "$teststring" | nc 127.0.0.1 $myport
Expand Down