From 2eb46e8c57c4dab0197ca82d9899fa1356500fc0 Mon Sep 17 00:00:00 2001 From: Hiroshi Ioka Date: Thu, 18 Aug 2016 16:10:28 +0900 Subject: [PATCH] os: prevent infinite symlink loop of Stat on Windows The Windows version of Stat calls Readlink iteratively until reaching a non-symlink file. If the given file is a circular symlink, It never stops. This CL defines the maximum number of symlink loop count. If the loop count will exceed that number, Stat will return error. Fixes #16538 Change-Id: Ia9f3f2259a8d32801461c5041cc24a34f9f81009 Reviewed-on: https://go-review.googlesource.com/27580 TryBot-Result: Gobot Gobot Reviewed-by: Alex Brainman --- src/os/os_test.go | 23 +++++++++++++++++++++++ src/os/stat_windows.go | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/os/os_test.go b/src/os/os_test.go index 0c4042a4bf..fb392b52cd 100644 --- a/src/os/os_test.go +++ b/src/os/os_test.go @@ -1812,3 +1812,26 @@ func TestRemoveAllRace(t *testing.T) { close(hold) // let workers race to remove root wg.Wait() } + +func TestStatSymlinkLoop(t *testing.T) { + testenv.MustHaveSymlink(t) + + defer chtmpdir(t)() + + err := Symlink("x", "y") + if err != nil { + t.Fatal(err) + } + defer Remove("y") + + err = Symlink("y", "x") + if err != nil { + t.Fatal(err) + } + defer Remove("x") + + _, err = Stat("x") + if perr, ok := err.(*PathError); !ok || perr.Err != syscall.ELOOP { + t.Errorf("expected *PathError with ELOOP, got %T: %v\n", err, err) + } +} diff --git a/src/os/stat_windows.go b/src/os/stat_windows.go index 3c433b1579..c14abc7c41 100644 --- a/src/os/stat_windows.go +++ b/src/os/stat_windows.go @@ -61,7 +61,7 @@ func (file *File) Stat() (FileInfo, error) { func Stat(name string) (FileInfo, error) { var fi FileInfo var err error - for { + for i := 0; i < 255; i++ { fi, err = Lstat(name) if err != nil { return fi, err @@ -74,6 +74,7 @@ func Stat(name string) (FileInfo, error) { return fi, err } } + return nil, &PathError{"Stat", name, syscall.ELOOP} } // Lstat returns the FileInfo structure describing the named file. -- 2.48.1