aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2025-03-27 16:22:38 -0700
committerDamien Neil <dneil@google.com>2025-03-27 22:25:37 -0700
commitcfc784a152ebbc4fc0b8bf13c02e0f6eb9c980bd (patch)
tree704a9f64706146db3440e73073eec1cc59da5faf /src
parentb17a99d6fca7f33bb821d450ebe67d6d4b3ea289 (diff)
downloadgo-cfc784a152ebbc4fc0b8bf13c02e0f6eb9c980bd.tar.xz
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. Fixes #73081 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>
Diffstat (limited to 'src')
-rw-r--r--src/os/root_openat.go3
-rw-r--r--src/os/root_test.go27
2 files changed, 30 insertions, 0 deletions
diff --git a/src/os/root_openat.go b/src/os/root_openat.go
index 6591825648..f67794cd72 100644
--- a/src/os/root_openat.go
+++ b/src/os/root_openat.go
@@ -226,6 +226,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 7db8ce0e58..7b8eae03a1 100644
--- a/src/os/root_test.go
+++ b/src/os/root_test.go
@@ -1596,6 +1596,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",