fix(backup): retain staging cleanup capability
This commit is contained in:
@@ -201,6 +201,48 @@ func (directory *unixPrivateDirectory) CreateRegular(name string, contents []byt
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (directory *unixPrivateDirectory) CreateRegularFile(name string) (*os.File, bool, error) {
|
||||
if directory.Validate() != nil || !validPrivateLeafName(name) {
|
||||
return nil, false, ErrUnsafeFile
|
||||
}
|
||||
descriptor, err := unix.Openat(directory.descriptor, name,
|
||||
unix.O_RDWR|unix.O_CREAT|unix.O_EXCL|unix.O_CLOEXEC|unix.O_NOFOLLOW, 0o600)
|
||||
if errors.Is(err, unix.EEXIST) {
|
||||
if _, existingErr := requirePrivateUnixRootRegularAt(directory.descriptor, name, 1); existingErr != nil || directory.Validate() != nil {
|
||||
return nil, false, ErrUnsafeFile
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, false, ErrUnsafeFile
|
||||
}
|
||||
file := os.NewFile(uintptr(descriptor), "tht-safeio-private-root-stream")
|
||||
if file == nil {
|
||||
_ = unix.Close(descriptor)
|
||||
_ = unix.Unlinkat(directory.descriptor, name, 0)
|
||||
return nil, false, ErrUnsafeFile
|
||||
}
|
||||
failed := true
|
||||
defer func() {
|
||||
if failed {
|
||||
_ = file.Close()
|
||||
_ = unix.Unlinkat(directory.descriptor, name, 0)
|
||||
}
|
||||
}()
|
||||
if unix.Fchmod(descriptor, 0o600) != nil {
|
||||
return nil, false, ErrUnsafeFile
|
||||
}
|
||||
var stat unix.Stat_t
|
||||
if unix.Fstat(descriptor, &stat) != nil || !privateUnixRootRegular(&stat, 1) {
|
||||
return nil, false, ErrUnsafeFile
|
||||
}
|
||||
if directory.Validate() != nil || unix.Fsync(directory.descriptor) != nil {
|
||||
return nil, false, ErrUnsafeFile
|
||||
}
|
||||
failed = false
|
||||
return file, true, nil
|
||||
}
|
||||
|
||||
func (directory *unixPrivateDirectory) ReadRegular(name string, maximum int64) ([]byte, bool, error) {
|
||||
if directory.Validate() != nil || !validPrivateLeafName(name) || maximum < 0 || maximum == int64(^uint64(0)>>1) {
|
||||
return nil, false, ErrUnsafeFile
|
||||
|
||||
Reference in New Issue
Block a user