From fa7217f74de31f949e386efea1713df195a91900 Mon Sep 17 00:00:00 2001 From: Damien Neil <dneil@google.com> Date: Thu, 27 Mar 2025 16:22:38 -0700 Subject: [PATCH] [release-branch.go1.24] os: avoid panic in Root when symlink references the root We would panic when opening a symlink ending in .., where the symlink references the root itself. For #73081 Fixes #73082 Change-Id: I7dc3f041ca79df7942feec58c197fde6881ecae5 Reviewed-on: https://go-review.googlesource.com/c/go/+/661416 Reviewed-by: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> (cherry picked from commit cfc784a152ebbc4fc0b8bf13c02e0f6eb9c980bd) Reviewed-on: https://go-review.googlesource.com/c/go/+/662315 --- src/os/root_openat.go | 3 +++ src/os/root_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/os/root_openat.go b/src/os/root_openat.go index a03208b4c17..6fc02a1a071 100644 --- a/src/os/root_openat.go +++ b/src/os/root_openat.go @@ -146,6 +146,9 @@ func doInRoot[T any](r *Root, name string, f func(parent sysfdType, name string) return ret, errPathEscapes } parts = slices.Delete(parts, i-count, end) + if len(parts) == 0 { + parts = []string{"."} + } i = 0 if dirfd != rootfd { syscall.Close(dirfd) diff --git a/src/os/root_test.go b/src/os/root_test.go index cbb985b2cee..6f6f6cc8267 100644 --- a/src/os/root_test.go +++ b/src/os/root_test.go @@ -1176,6 +1176,33 @@ func TestRootRaceRenameDir(t *testing.T) { } } +func TestRootSymlinkToRoot(t *testing.T) { + dir := makefs(t, []string{ + "d/d => ..", + }) + root, err := os.OpenRoot(dir) + if err != nil { + t.Fatal(err) + } + defer root.Close() + if err := root.Mkdir("d/d/new", 0777); err != nil { + t.Fatal(err) + } + f, err := root.Open("d/d") + if err != nil { + t.Fatal(err) + } + defer f.Close() + names, err := f.Readdirnames(-1) + if err != nil { + t.Fatal(err) + } + slices.Sort(names) + if got, want := names, []string{"d", "new"}; !slices.Equal(got, want) { + t.Errorf("root contains: %q, want %q", got, want) + } +} + func TestOpenInRoot(t *testing.T) { dir := makefs(t, []string{ "file", -- GitLab