fix(windows): protect existing lifecycle child first

This commit is contained in:
2026-08-18 14:11:41 +02:00
parent ada3f9fc7f
commit afb0e21200
+25 -8
View File
@@ -50,14 +50,31 @@ type Transaction struct {
// Acquire obtains the shared lock used by backup, restore, Pi lifecycle and product updates. // Acquire obtains the shared lock used by backup, restore, Pi lifecycle and product updates.
func Acquire(installation config.Installation) (*Lock, error) { func Acquire(installation config.Installation) (*Lock, error) {
directory := installation.ControlDirectory() directory := installation.ControlDirectory()
// The lifecycle directory is also the restore staging parent. Protect both the shared parent := filepath.Dir(directory)
// .tht directory and this installation's child before any lock or staging artifact is // The lifecycle directory is also the restore staging parent. An existing Windows child
// created; chmod alone does not install an owner-only DACL on Windows. // must be protected before its parent: replacing the parent's inheritable ACL first can
if err := ensurePrivateLifecycleDirectory(filepath.Dir(directory)); err != nil { // remove the child's inherited owner authority before the child receives its protected DACL.
return nil, fmt.Errorf("protect lifecycle control parent: %w", err) // For a new installation the parent must instead exist before safe child creation.
} controlInfo, controlErr := os.Lstat(directory)
if err := ensurePrivateLifecycleDirectory(directory); err != nil { if controlErr == nil {
return nil, fmt.Errorf("protect lifecycle control directory: %w", err) if !controlInfo.IsDir() || controlInfo.Mode()&os.ModeSymlink != 0 {
return nil, errors.New("lifecycle control directory is not a regular directory")
}
if err := ensurePrivateLifecycleDirectory(directory); err != nil {
return nil, fmt.Errorf("protect lifecycle control directory: %w", err)
}
if err := ensurePrivateLifecycleDirectory(parent); err != nil {
return nil, fmt.Errorf("protect lifecycle control parent: %w", err)
}
} else if errors.Is(controlErr, os.ErrNotExist) {
if err := ensurePrivateLifecycleDirectory(parent); err != nil {
return nil, fmt.Errorf("protect lifecycle control parent: %w", err)
}
if err := ensurePrivateLifecycleDirectory(directory); err != nil {
return nil, fmt.Errorf("protect lifecycle control directory: %w", err)
}
} else {
return nil, errors.New("lifecycle control directory is unavailable")
} }
info, err := os.Lstat(directory) info, err := os.Lstat(directory)
if err != nil || !info.IsDir() || info.Mode()&os.ModeSymlink != 0 { if err != nil || !info.IsDir() || info.Mode()&os.ModeSymlink != 0 {