forked from TrueCloudLab/restic
fs: stricter enforcement to only call readdir on a directory
Use O_DIRECTORY to prevent opening any other than a directory in readdirnames.
This commit is contained in:
parent
f8031561f2
commit
b402e8a6fc
4 changed files with 33 additions and 2 deletions
|
@ -7,3 +7,6 @@ import "syscall"
|
|||
|
||||
// O_NOFOLLOW instructs the kernel to not follow symlinks when opening a file.
|
||||
const O_NOFOLLOW int = syscall.O_NOFOLLOW
|
||||
|
||||
// O_DIRECTORY instructs the kernel to only open directories.
|
||||
const O_DIRECTORY int = syscall.O_DIRECTORY
|
||||
|
|
|
@ -3,5 +3,10 @@
|
|||
|
||||
package fs
|
||||
|
||||
// TODO honor flags when opening files
|
||||
|
||||
// O_NOFOLLOW is a noop on Windows.
|
||||
const O_NOFOLLOW int = 0
|
||||
|
||||
// O_DIRECTORY is a noop on Windows.
|
||||
const O_DIRECTORY int = 0
|
||||
|
|
|
@ -64,9 +64,10 @@ func ResetPermissions(path string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Readdirnames returns a list of file in a directory. Flags are passed to fs.OpenFile. O_RDONLY is implied.
|
||||
// Readdirnames returns a list of file in a directory. Flags are passed to fs.OpenFile.
|
||||
// O_RDONLY and O_DIRECTORY are implied.
|
||||
func Readdirnames(filesystem FS, dir string, flags int) ([]string, error) {
|
||||
f, err := filesystem.OpenFile(dir, O_RDONLY|flags, 0)
|
||||
f, err := filesystem.OpenFile(dir, O_RDONLY|O_DIRECTORY|flags, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("openfile for readdirnames failed: %w", err)
|
||||
}
|
||||
|
|
22
internal/fs/file_unix_test.go
Normal file
22
internal/fs/file_unix_test.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
//go:build unix
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/errors"
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
)
|
||||
|
||||
func TestReaddirnamesFifo(t *testing.T) {
|
||||
// should not block when reading from a fifo instead of a directory
|
||||
tempdir := t.TempDir()
|
||||
fifoFn := filepath.Join(tempdir, "fifo")
|
||||
rtest.OK(t, mkfifo(fifoFn, 0o600))
|
||||
|
||||
_, err := Readdirnames(&Local{}, fifoFn, 0)
|
||||
rtest.Assert(t, errors.Is(err, syscall.ENOTDIR), "unexpected error %v", err)
|
||||
}
|
Loading…
Reference in a new issue