fix: Block creating files with non-existing parent directories using O_CREATE

This commit is contained in:
Felicitas Pojtinger
2022-01-12 22:39:00 +01:00
parent 5ed0eec75e
commit 3a0165895a
3 changed files with 34 additions and 20 deletions

View File

@@ -193,7 +193,7 @@ var serveFTPCmd = &cobra.Command{
) )
}, },
viper.GetBool(readOnlyFlag), viper.GetBool(readOnlyFlag),
true, // FTP requires read permission even if `O_WRONLY` is set if cache is enabled true, // FTP requires read permission even if `O_WRONLY` is set if cache is enabled, as the cache needs to read the written file
func(hdr *config.Header) { func(hdr *config.Header) {
jsonLogger.Trace("Header transform", hdr) jsonLogger.Trace("Header transform", hdr)

View File

@@ -34,7 +34,7 @@ type STFS struct {
compressionLevel string compressionLevel string
getFileBuffer func() (cache.WriteCache, func() error, error) getFileBuffer func() (cache.WriteCache, func() error, error)
readOnly bool readOnly bool
writeImpliesRead bool writePermImpliesReadPerm bool
ioLock sync.Mutex ioLock sync.Mutex
@@ -51,7 +51,7 @@ func NewSTFS(
compressionLevel string, compressionLevel string,
getFileBuffer func() (cache.WriteCache, func() error, error), getFileBuffer func() (cache.WriteCache, func() error, error),
readOnly bool, readOnly bool,
writeImpliesRead bool, writePermImpliesReadPerm bool,
onHeader func(hdr *config.Header), onHeader func(hdr *config.Header),
log logging.StructuredLogger, log logging.StructuredLogger,
@@ -65,7 +65,7 @@ func NewSTFS(
compressionLevel: compressionLevel, compressionLevel: compressionLevel,
getFileBuffer: getFileBuffer, getFileBuffer: getFileBuffer,
readOnly: readOnly, readOnly: readOnly,
writeImpliesRead: writeImpliesRead, writePermImpliesReadPerm: writePermImpliesReadPerm,
onHeader: onHeader, onHeader: onHeader,
log: log, log: log,
@@ -376,7 +376,7 @@ func (f *STFS) OpenFile(name string, flag int, perm os.FileMode) (afero.File, er
if (flag & O_ACCMODE) == os.O_RDONLY { if (flag & O_ACCMODE) == os.O_RDONLY {
flags.Read = true flags.Read = true
} else if (flag & O_ACCMODE) == os.O_WRONLY { } else if (flag & O_ACCMODE) == os.O_WRONLY {
if f.writeImpliesRead { if f.writePermImpliesReadPerm {
flags.Read = true flags.Read = true
} }
@@ -406,6 +406,21 @@ func (f *STFS) OpenFile(name string, flag int, perm os.FileMode) (afero.File, er
if err != nil { if err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
if !f.readOnly && flag&os.O_CREATE != 0 && flag&os.O_EXCL == 0 { if !f.readOnly && flag&os.O_CREATE != 0 && flag&os.O_EXCL == 0 {
if _, err := inventory.Stat(
f.metadata,
filepath.Dir(name),
false,
f.onHeader,
); err != nil {
if err == sql.ErrNoRows {
return nil, os.ErrNotExist
}
return nil, err
}
if err := f.mknodeWithoutLocking(false, name, perm, false, "", false); err != nil { if err := f.mknodeWithoutLocking(false, name, perm, false, "", false); err != nil {
return nil, err return nil, err
} }

View File

@@ -1114,15 +1114,14 @@ var openFileTests = []struct {
func(f afero.File) error { return nil }, func(f afero.File) error { return nil },
false, false,
}, },
// FIXME: STFS can create file in non-existent directory, which should not be possible {
// { "Can not open /mydir/test.txt if O_CREATE is set",
// "Can not open /mydir/test.txt if O_CREATE is set", openFileArgs{"/mydir/test.txt", os.O_CREATE, os.ModePerm},
// openFileArgs{"/mydir/test.txt", os.O_CREATE, os.ModePerm}, true,
// true, func(f afero.Fs) error { return nil },
// func(f afero.Fs) error { return nil }, func(f afero.File) error { return nil },
// func(f afero.File) error { return nil }, false,
// false, },
// },
{ {
"Can open /mydir/test.txt after creating it", "Can open /mydir/test.txt after creating it",
openFileArgs{"/mydir/test.txt", os.O_RDONLY, 0}, openFileArgs{"/mydir/test.txt", os.O_RDONLY, 0},