fix(fs, model): improve symlink resilience in file shortcut (#10739)
Ensure file was a file before the shortcut as well as after... (This was implied when talking to a correct implementation, but not enforced.) Make our file opening operations safe by default by ensuring the last path component is not a symlink. --------- Signed-off-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
+3
-18
@@ -241,15 +241,7 @@ func (f *BasicFilesystem) DirNames(name string) ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *BasicFilesystem) Open(name string) (File, error) {
|
func (f *BasicFilesystem) Open(name string) (File, error) {
|
||||||
rootedName, err := f.rooted(name)
|
return f.OpenFile(name, os.O_RDONLY, 0)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fd, err := os.Open(rootedName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return basicFile{fd, name}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *BasicFilesystem) OpenFile(name string, flags int, mode FileMode) (File, error) {
|
func (f *BasicFilesystem) OpenFile(name string, flags int, mode FileMode) (File, error) {
|
||||||
@@ -257,6 +249,7 @@ func (f *BasicFilesystem) OpenFile(name string, flags int, mode FileMode) (File,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
flags |= alwaysOpenFlags // enforce extra bits in flags
|
||||||
fd, err := os.OpenFile(rootedName, flags, os.FileMode(mode))
|
fd, err := os.OpenFile(rootedName, flags, os.FileMode(mode))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -265,15 +258,7 @@ func (f *BasicFilesystem) OpenFile(name string, flags int, mode FileMode) (File,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *BasicFilesystem) Create(name string) (File, error) {
|
func (f *BasicFilesystem) Create(name string) (File, error) {
|
||||||
rootedName, err := f.rooted(name)
|
return f.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o666)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fd, err := os.Create(rootedName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return basicFile{fd, name}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*BasicFilesystem) Walk(_ string, _ WalkFunc) error {
|
func (*BasicFilesystem) Walk(_ string, _ WalkFunc) error {
|
||||||
|
|||||||
@@ -14,8 +14,11 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const alwaysOpenFlags = syscall.O_NOFOLLOW // never open symlinks as the final path component
|
||||||
|
|
||||||
func (f *BasicFilesystem) CreateSymlink(target, name string) error {
|
func (f *BasicFilesystem) CreateSymlink(target, name string) error {
|
||||||
name, err := f.rooted(name)
|
name, err := f.rooted(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import (
|
|||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const alwaysOpenFlags = 0 // no extra flags
|
||||||
|
|
||||||
var errNotSupported = errors.New("symlinks not supported")
|
var errNotSupported = errors.New("symlinks not supported")
|
||||||
|
|
||||||
func (BasicFilesystem) ReadSymlink(path string) (string, error) {
|
func (BasicFilesystem) ReadSymlink(path string) (string, error) {
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ loop:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if hasCurFile && file.BlocksEqual(curFile) {
|
if hasCurFile && curFile.Type == file.Type && file.BlocksEqual(curFile) {
|
||||||
// We are supposed to copy the entire file, and then fetch nothing. We
|
// We are supposed to copy the entire file, and then fetch nothing. We
|
||||||
// are only updating metadata, so we don't actually *need* to make the
|
// are only updating metadata, so we don't actually *need* to make the
|
||||||
// copy.
|
// copy.
|
||||||
|
|||||||
Reference in New Issue
Block a user