1
0
mirror of https://github.com/golang/go synced 2024-11-23 14:00:03 -07:00

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 <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
Hiroshi Ioka 2016-08-18 16:10:28 +09:00 committed by Alex Brainman
parent 5a6f973565
commit 2eb46e8c57
2 changed files with 25 additions and 1 deletions

View File

@ -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)
}
}

View File

@ -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.