-
-
Notifications
You must be signed in to change notification settings - Fork 966
fsnotify can crash on windows if raw.FileNameLength exceeds syscall.MAX_PATH #318
Copy link
Copy link
Closed
Description
Before reporting an issue, please ensure you are using the latest release of fsnotify.
Yeah
Which operating system (GOOS) and version are you using?
Windows: go 1.12, windows 10
Please describe the issue that occurred.
panic: runtime error: slice bounds out of range
goroutine 765 [running, locked to thread]:
filesync_daemon/fsnotify.(*Watcher).readEvents(0xc000c78f40)
/home/builder/go/src/filesync_daemon/fsnotify/windows.go:456 +0xfb1
created by filesync_daemon/fsnotify.NewWatcher
/home/builder/go/src/filesync_daemon/fsnotify/windows.go:46 +0x21c
On windows, when we try to extract the event path name from the OS, we create a buf with length as syscall.MAX_PATH (https://github.com/fsnotify/fsnotify/blob/master/windows.go#L454).
However, it is possible to create a file name whose length exceeds this.
So, can we instead of using a fixed syscall.MAX_PATH buf, we create a buf that is the size of the path name based on the raw.FileNameLength like the following?
size := int(raw.FileNameLength / 2)
var buf []uint16
sh := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
sh.Data = uintptr(unsafe.Pointer(&raw.FileName))
sh.Len = size
sh.Cap = size
name := syscall.UTF16ToString(buf)
Code to create a long path dir exceeding syscall.MAX_PATH:
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package main
import (
"crypto/rand"
"encoding/hex"
fmt "fmt"
"os"
"path/filepath"
)
func RandString(bytes int) string {
buf := make([]byte, bytes)
_, err := rand.Read(buf)
if err != nil {
return ""
}
return hex.EncodeToString(buf[:])[:len(buf)]
}
func main() {
longPath := ""
for i := 0; i < 10; i++ {
longPath = filepath.Join(longPath, RandString(26))
}
parentDir := "C:/Users/hangk/Downloads/temp"
fmt.Println(longPath)
err := os.MkdirAll(filepath.Join(parentDir, longPath), 0700)
fmt.Println(err)
}
Now if we enable recursive watch on windows here: https://github.com/fsnotify/fsnotify/blob/master/windows.go#L350 by changing flag false to true, fsnotify will crash.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels