fix(backup): retain staging cleanup capability

This commit is contained in:
2026-08-18 10:50:56 +02:00
parent d43738eeae
commit 5f9a3ae066
9 changed files with 349 additions and 27 deletions
@@ -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