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>
This commit is contained in:
Damien Neil 2025-03-27 16:22:38 -07:00
parent b17a99d6fc
commit cfc784a152
2 changed files with 30 additions and 0 deletions

View File

@ -226,6 +226,9 @@ func doInRoot[T any](r *Root, name string, f func(parent sysfdType, name string)
return ret, errPathEscapes return ret, errPathEscapes
} }
parts = slices.Delete(parts, i-count, end) parts = slices.Delete(parts, i-count, end)
if len(parts) == 0 {
parts = []string{"."}
}
i = 0 i = 0
if dirfd != rootfd { if dirfd != rootfd {
syscall.Close(dirfd) syscall.Close(dirfd)

View File

@ -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) { func TestOpenInRoot(t *testing.T) {
dir := makefs(t, []string{ dir := makefs(t, []string{
"file", "file",