fix: Block creating files with non-existing parent directories using O_CREATE
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ type STFS struct {
|
|||||||
|
|
||||||
metadata config.MetadataConfig
|
metadata config.MetadataConfig
|
||||||
|
|
||||||
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,
|
||||||
@@ -62,10 +62,10 @@ func NewSTFS(
|
|||||||
|
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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},
|
||||||
|
|||||||
Reference in New Issue
Block a user