Commit 2eb46e8c authored by Hiroshi Ioka's avatar Hiroshi Ioka Committed by Alex Brainman

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: 's avatarAlex Brainman <alex.brainman@gmail.com>
parent 5a6f9735
......@@ -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)
}
}
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment