9ec9d0c49c
The function used to do two things: 1) Walk the directory tree in a manner safe from symlink attacks 2) Open the final component in the mode requested by the caller This change drops (2), which was only used once, and lets the caller handle it. This simplifies the function and makes it fit for reuse in forward mode in openBackingPath(), and for using O_PATH on Linux.
49 lines
1.1 KiB
Go
49 lines
1.1 KiB
Go
package syscallcompat
|
|
|
|
import (
|
|
"os"
|
|
"syscall"
|
|
"testing"
|
|
)
|
|
|
|
func TestOpenNofollow(t *testing.T) {
|
|
err := os.MkdirAll(tmpDir+"/d1/d2/d3", 0700)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Create a file
|
|
dirfd, err := OpenDirNofollow(tmpDir, "d1/d2/d3")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
fd, err := Openat(dirfd, "f1", syscall.O_RDWR|syscall.O_CREAT|syscall.O_EXCL, 0600)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
syscall.Close(fd)
|
|
_, err = os.Stat(tmpDir + "/d1/d2/d3/f1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Replace "d1" with a symlink - open should fail with ELOOP
|
|
err = os.Rename(tmpDir+"/d1", tmpDir+"/d1.renamed")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
os.Symlink(tmpDir+"/d1.renamed", tmpDir+"/d1")
|
|
fd, err = OpenDirNofollow(tmpDir, "d1/d2/d3")
|
|
if err == nil {
|
|
t.Fatalf("should have failed")
|
|
}
|
|
if err != syscall.ELOOP && err != syscall.ENOTDIR {
|
|
t.Errorf("expected ELOOP or ENOTDIR, got %v", err)
|
|
}
|
|
// Check to see that the base dir can be opened as well
|
|
fd, err = OpenDirNofollow(tmpDir, "")
|
|
if err != nil {
|
|
t.Errorf("cannot open base dir: %v", err)
|
|
} else {
|
|
syscall.Close(fd)
|
|
}
|
|
}
|