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

Eval symlinks on XDG_RUNTIME_DIR #15918

Merged
merged 1 commit into from
Oct 31, 2022
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
4 changes: 4 additions & 0 deletions cmd/podman/registry/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ func setXdgDirs() error {
if _, found := os.LookupEnv("DBUS_SESSION_BUS_ADDRESS"); !found {
sessionAddr := filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "bus")
if _, err := os.Stat(sessionAddr); err == nil {
sessionAddr, err = filepath.EvalSymlinks(sessionAddr)
if err != nil {
return err
}
os.Setenv("DBUS_SESSION_BUS_ADDRESS", "unix:path="+sessionAddr)
}
}
Expand Down
8 changes: 7 additions & 1 deletion libpod/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,13 @@ func (r *Runtime) reset(ctx context.Context) error {
}
}

xdgRuntimeDir := filepath.Clean(os.Getenv("XDG_RUNTIME_DIR"))
xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR")
if xdgRuntimeDir != "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I think this is misleading because XDG is always, always going to be set very early on by config code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no change here if XDG_RUNTIME_DIR is not set or is set to "", Current code would not fail if XDG_RUNTIME_DIR=="" new code would, so I add his check.

xdgRuntimeDir, err = filepath.EvalSymlinks(xdgRuntimeDir)
if err != nil {
return err
}
}
_, prevError := r.store.Shutdown(true)
graphRoot := filepath.Clean(r.store.GraphRoot())
if graphRoot == xdgRuntimeDir {
Expand Down
6 changes: 5 additions & 1 deletion pkg/systemd/dbus.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ func dbusAuthRootlessConnection(createBus func(opts ...godbus.ConnOption) (*godb
func newRootlessConnection() (*dbus.Conn, error) {
return dbus.NewConnection(func() (*godbus.Conn, error) {
return dbusAuthRootlessConnection(func(opts ...godbus.ConnOption) (*godbus.Conn, error) {
path := filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "systemd/private")
path := filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "systemd", "private")
path, err := filepath.EvalSymlinks(path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, like above, I think you need an existence check before you EvalSymlinks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would the check do if it does not exists?

Still call
return godbus.Dial(fmt.Sprintf("unix:path=%s", path))
?

If the file does not exists EvalSymlinks will return that it does not exists.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know enough about this systemd/private path to comment. But:

  • old code: just returns a string with the path, whether the path exists or not (leave it to caller to deal with problems)
  • new code: barfs if path does not exist. This is new behavior. I don't know if it's good new behavior or bad new behavior... but it's a change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the old code will barf when godbus.Dial attempts to connect to a non existing socket
The new code will report the non existing socket earlier, as I read it.

if err != nil {
return nil, err
}
return godbus.Dial(fmt.Sprintf("unix:path=%s", path))
})
})
Expand Down
6 changes: 6 additions & 0 deletions pkg/util/utils_supported.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ func GetRuntimeDir() (string, error) {

rootlessRuntimeDirOnce.Do(func() {
runtimeDir := os.Getenv("XDG_RUNTIME_DIR")

if runtimeDir != "" {
rootlessRuntimeDir, rootlessRuntimeDirError = filepath.EvalSymlinks(runtimeDir)
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of made me nervous to return early, but AFAICT it's perfectly fine, no code paths are affected, and this actually seems cleaner. PR LGTM but this has too many ramifications for me.

}

uid := fmt.Sprintf("%d", rootless.GetRootlessUID())
if runtimeDir == "" {
tmpDir := filepath.Join("/run", "user", uid)
Expand Down
15 changes: 15 additions & 0 deletions test/system/500-networking.bats
Original file line number Diff line number Diff line change
Expand Up @@ -776,4 +776,19 @@ EOF
is "$output" ".*options ${dns_opt}" "--dns-option was added"
}

@test "podman rootless netns works when XDG_RUNTIME_DIR includes symlinks" {
# regression test for https://github.com/containers/podman/issues/14606
is_rootless || skip "only meaningful for rootless"

# Create a tmpdir symlink pointing to /run, and use it briefly
ln -s /run $PODMAN_TMPDIR/run
local tmp_run=$PODMAN_TMPDIR/run/user/$(id -u)
test -d $tmp_run || skip "/run/user/MYUID unavailable"

# This 'run' would previously fail with:
# IPAM error: failed to open database ....
XDG_RUNTIME_DIR=$tmp_run run_podman run --network bridge --rm $IMAGE ip a
assert "$output" =~ "eth0"
}

# vim: filetype=sh