fix: ignore symlinks in backend filesystems (#9457)

fixes #9419
master
Harshavardhana 5 years ago committed by GitHub
parent f14bf25cb9
commit b1c0c32ba6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      cmd/posix-list-dir_other.go
  2. 2
      cmd/posix-list-dir_test.go
  3. 7
      cmd/posix-list-dir_unix.go
  4. 27
      cmd/posix-list-dir_windows.go

@ -21,10 +21,7 @@ package cmd
import ( import (
"io" "io"
"os" "os"
"path"
"strings" "strings"
"github.com/minio/minio/cmd/logger"
) )
// Return all the entries at the directory dirPath. // Return all the entries at the directory dirPath.
@ -111,25 +108,8 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
} }
} }
for _, fi := range fis { for _, fi := range fis {
// Stat symbolic link and follow to get the final value. // Not need to follow symlink.
if fi.Mode()&os.ModeSymlink == os.ModeSymlink { if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
var st os.FileInfo
st, err = os.Stat(path.Join(dirPath, fi.Name()))
if err != nil {
reqInfo := (&logger.ReqInfo{}).AppendTags("path", path.Join(dirPath, fi.Name()))
ctx := logger.SetReqInfo(GlobalContext, reqInfo)
logger.LogIf(ctx, err)
continue
}
// Append to entries if symbolic link exists and is valid.
if st.IsDir() {
entries = append(entries, fi.Name()+SlashSeparator)
} else if st.Mode().IsRegular() {
entries = append(entries, fi.Name())
}
if count > 0 {
remaining--
}
continue continue
} }
if fi.Mode().IsDir() { if fi.Mode().IsDir() {

@ -149,7 +149,7 @@ func setupTestReadDirSymlink(t *testing.T) (testResults []result) {
} }
// Add to entries. // Add to entries.
entries = append(entries, name1) entries = append(entries, name1)
entries = append(entries, name2) // Symlinks are ignored.
} }
if err := os.MkdirAll(filepath.Join(dir, "mydir"), 0777); err != nil { if err := os.MkdirAll(filepath.Join(dir, "mydir"), 0777); err != nil {
t.Fatalf("Unable to create \"mydir\", %s", err) t.Fatalf("Unable to create \"mydir\", %s", err)

@ -172,8 +172,8 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
// Fallback for filesystems (like old XFS) that don't // Fallback for filesystems (like old XFS) that don't
// support Dirent.Type and have DT_UNKNOWN (0) there // support Dirent.Type and have DT_UNKNOWN (0) there
// instead. // instead.
if typ == unexpectedFileMode || typ&os.ModeSymlink == os.ModeSymlink { if typ == unexpectedFileMode {
fi, err := os.Stat(pathJoin(dirPath, name)) fi, err := os.Lstat(pathJoin(dirPath, name))
if err != nil { if err != nil {
// It got deleted in the meantime, not found // It got deleted in the meantime, not found
// or returns too many symlinks ignore this // or returns too many symlinks ignore this
@ -186,6 +186,9 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
} }
typ = fi.Mode() & os.ModeType typ = fi.Mode() & os.ModeType
} }
if typ&os.ModeSymlink == os.ModeSymlink {
continue
}
if typ.IsRegular() { if typ.IsRegular() {
entries = append(entries, name) entries = append(entries, name)
} else if typ.IsDir() { } else if typ.IsDir() {

@ -121,17 +121,16 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
data := &syscall.Win32finddata{} data := &syscall.Win32finddata{}
for count != 0 { for count != 0 {
e := syscall.FindNextFile(syscall.Handle(d.Fd()), data) err = syscall.FindNextFile(syscall.Handle(d.Fd()), data)
if e != nil { if err != nil {
if e == syscall.ERROR_NO_MORE_FILES { if err == syscall.ERROR_NO_MORE_FILES {
break break
} else { } else {
err = &os.PathError{ return nil, &os.PathError{
Op: "FindNextFile", Op: "FindNextFile",
Path: dirPath, Path: dirPath,
Err: e, Err: err,
} }
return
} }
} }
name := syscall.UTF16ToString(data.FileName[0:]) name := syscall.UTF16ToString(data.FileName[0:])
@ -140,23 +139,7 @@ func readDirN(dirPath string, count int) (entries []string, err error) {
} }
switch { switch {
case data.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0: case data.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0:
// If its symbolic link, follow the link using os.Stat()
var fi os.FileInfo
fi, err = os.Stat(pathJoin(dirPath, name))
if err != nil {
// If file does not exist, we continue and skip it.
// Could happen if it was deleted in the middle while
// this list was being performed.
if os.IsNotExist(err) {
continue continue
}
return nil, err
}
if fi.IsDir() {
entries = append(entries, name+SlashSeparator)
} else if fi.Mode().IsRegular() {
entries = append(entries, name)
}
case data.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0: case data.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0:
entries = append(entries, name+SlashSeparator) entries = append(entries, name+SlashSeparator)
default: default:

Loading…
Cancel
Save