mirror of
https://github.com/restic/restic.git
synced 2024-12-23 00:07:25 +00:00
fs: fix race condition in get/set security descriptor
Calling `Load()` twice for an atomic variable can return different values each time. This resulted in trying to read the security descriptor with high privileges, but then not entering the code path to switch to low privileges when another thread has already done so concurrently.
This commit is contained in:
parent
1931beab8e
commit
6fbfccc2d3
1 changed files with 8 additions and 4 deletions
|
@ -48,13 +48,15 @@ func GetSecurityDescriptor(filePath string) (securityDescriptor *[]byte, err err
|
|||
|
||||
var sd *windows.SECURITY_DESCRIPTOR
|
||||
|
||||
if lowerPrivileges.Load() {
|
||||
// store original value to avoid unrelated changes in the error check
|
||||
useLowerPrivileges := lowerPrivileges.Load()
|
||||
if useLowerPrivileges {
|
||||
sd, err = getNamedSecurityInfoLow(filePath)
|
||||
} else {
|
||||
sd, err = getNamedSecurityInfoHigh(filePath)
|
||||
}
|
||||
if err != nil {
|
||||
if !lowerPrivileges.Load() && isHandlePrivilegeNotHeldError(err) {
|
||||
if !useLowerPrivileges && isHandlePrivilegeNotHeldError(err) {
|
||||
// If ERROR_PRIVILEGE_NOT_HELD is encountered, fallback to backups/restores using lower non-admin privileges.
|
||||
lowerPrivileges.Store(true)
|
||||
sd, err = getNamedSecurityInfoLow(filePath)
|
||||
|
@ -109,14 +111,16 @@ func SetSecurityDescriptor(filePath string, securityDescriptor *[]byte) error {
|
|||
sacl = nil
|
||||
}
|
||||
|
||||
if lowerPrivileges.Load() {
|
||||
// store original value to avoid unrelated changes in the error check
|
||||
useLowerPrivileges := lowerPrivileges.Load()
|
||||
if useLowerPrivileges {
|
||||
err = setNamedSecurityInfoLow(filePath, dacl)
|
||||
} else {
|
||||
err = setNamedSecurityInfoHigh(filePath, owner, group, dacl, sacl)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if !lowerPrivileges.Load() && isHandlePrivilegeNotHeldError(err) {
|
||||
if !useLowerPrivileges && isHandlePrivilegeNotHeldError(err) {
|
||||
// If ERROR_PRIVILEGE_NOT_HELD is encountered, fallback to backups/restores using lower non-admin privileges.
|
||||
lowerPrivileges.Store(true)
|
||||
err = setNamedSecurityInfoLow(filePath, dacl)
|
||||
|
|
Loading…
Reference in a new issue