fix(windows): tolerate concurrent auth claims

This commit is contained in:
2026-08-18 14:21:11 +02:00
parent 824245d285
commit 455fffb299
2 changed files with 75 additions and 6 deletions
@@ -953,16 +953,35 @@ func windowsRelativeClaimAbsentOrOrphan(directory *windowsPrivateDirectory, sour
return false, ErrUnsafeFile
}
const windowsClaimSharingRetries = 100
func openWindowsPrivateClaimSource(directory windows.Handle, source string) (*windowsPrivateRegularAt, error) {
for attempt := 0; ; attempt++ {
value, err := openWindowsPrivateRegularAt(
directory,
source,
windows.FILE_GENERIC_READ|windows.FILE_GENERIC_WRITE|windows.DELETE,
1,
)
if !errors.Is(err, windows.ERROR_SHARING_VIOLATION) &&
!errors.Is(err, windows.STATUS_SHARING_VIOLATION) {
return value, err
}
if attempt == windowsClaimSharingRetries {
return nil, err
}
time.Sleep(time.Millisecond)
}
}
func (directory *windowsPrivateDirectory) ClaimRegular(source, claim string) (bool, error) {
if directory.Validate() != nil || !validPrivateLeafName(source) || !validPrivateLeafName(claim) {
return false, ErrUnsafeFile
}
value, err := openWindowsPrivateRegularAt(
directory.handle,
source,
windows.FILE_GENERIC_READ|windows.FILE_GENERIC_WRITE|windows.DELETE,
1,
)
// A concurrent winner temporarily holds the source with DELETE access and deliberately
// without FILE_SHARE_DELETE. Wait only for that specific, bounded contention before
// observing the resulting pair or absence below. Persistent sharing remains unsafe.
value, err := openWindowsPrivateClaimSource(directory.handle, source)
if err != nil {
pair, pairErr := windowsRelativeClaimPairExists(directory, source, claim)
if pairErr == nil && pair {