fix(windows): lock claim validation boundary
This commit is contained in:
@@ -10,6 +10,10 @@ import (
|
|||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func lockCanonicalPrivateClaimOperation() func() {
|
||||||
|
return func() {}
|
||||||
|
}
|
||||||
|
|
||||||
func claimCanonicalPrivateRegular(source, claim string) (bool, error) {
|
func claimCanonicalPrivateRegular(source, claim string) (bool, error) {
|
||||||
directory, sourceName, err := openCanonicalParentDirectory(source)
|
directory, sourceName, err := openCanonicalParentDirectory(source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ import (
|
|||||||
// another's bounded external-contention retry while its validated parent handle is retained.
|
// another's bounded external-contention retry while its validated parent handle is retained.
|
||||||
var windowsPrivateClaimOperationMu sync.Mutex
|
var windowsPrivateClaimOperationMu sync.Mutex
|
||||||
|
|
||||||
|
func lockCanonicalPrivateClaimOperation() func() {
|
||||||
|
windowsPrivateClaimOperationMu.Lock()
|
||||||
|
return windowsPrivateClaimOperationMu.Unlock
|
||||||
|
}
|
||||||
|
|
||||||
type windowsPrivateRegular struct {
|
type windowsPrivateRegular struct {
|
||||||
parents *windowsParentHandles
|
parents *windowsParentHandles
|
||||||
handle windows.Handle
|
handle windows.Handle
|
||||||
@@ -54,8 +59,6 @@ func openWindowsPrivateRegular(path string, links uint32) (*windowsPrivateRegula
|
|||||||
}
|
}
|
||||||
|
|
||||||
func claimCanonicalPrivateRegular(source, claim string) (claimed bool, resultErr error) {
|
func claimCanonicalPrivateRegular(source, claim string) (claimed bool, resultErr error) {
|
||||||
windowsPrivateClaimOperationMu.Lock()
|
|
||||||
defer windowsPrivateClaimOperationMu.Unlock()
|
|
||||||
directory, sourceName, claimName, err := openWindowsPrivateClaimDirectory(source, claim)
|
directory, sourceName, claimName, err := openWindowsPrivateClaimDirectory(source, claim)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, ErrUnsafeFile
|
return false, ErrUnsafeFile
|
||||||
@@ -70,8 +73,6 @@ func claimCanonicalPrivateRegular(source, claim string) (claimed bool, resultErr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func readCanonicalPrivateClaim(source, claim string, maximum int64) (contents []byte, found bool, resultErr error) {
|
func readCanonicalPrivateClaim(source, claim string, maximum int64) (contents []byte, found bool, resultErr error) {
|
||||||
windowsPrivateClaimOperationMu.Lock()
|
|
||||||
defer windowsPrivateClaimOperationMu.Unlock()
|
|
||||||
directory, sourceName, claimName, err := openWindowsPrivateClaimDirectory(source, claim)
|
directory, sourceName, claimName, err := openWindowsPrivateClaimDirectory(source, claim)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, ErrUnsafeFile
|
return nil, false, ErrUnsafeFile
|
||||||
@@ -104,8 +105,6 @@ func openWindowsPrivateClaimDirectory(source, claim string) (PrivateDirectoryHan
|
|||||||
}
|
}
|
||||||
|
|
||||||
func removeCanonicalPrivateClaim(source, claim string) (removed bool, resultErr error) {
|
func removeCanonicalPrivateClaim(source, claim string) (removed bool, resultErr error) {
|
||||||
windowsPrivateClaimOperationMu.Lock()
|
|
||||||
defer windowsPrivateClaimOperationMu.Unlock()
|
|
||||||
directory, sourceName, claimName, err := openWindowsPrivateClaimDirectory(source, claim)
|
directory, sourceName, claimName, err := openWindowsPrivateClaimDirectory(source, claim)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, ErrUnsafeFile
|
return false, ErrUnsafeFile
|
||||||
|
|||||||
@@ -354,6 +354,8 @@ func RemoveCanonicalPrivateRegular(path string) error {
|
|||||||
// ClaimCanonicalPrivateRegular atomically creates a second, explicit private hard link to one
|
// ClaimCanonicalPrivateRegular atomically creates a second, explicit private hard link to one
|
||||||
// existing record. It is used only for digest-named, single-use OIDC state claims.
|
// existing record. It is used only for digest-named, single-use OIDC state claims.
|
||||||
func ClaimCanonicalPrivateRegular(source, claim string) (bool, error) {
|
func ClaimCanonicalPrivateRegular(source, claim string) (bool, error) {
|
||||||
|
unlock := lockCanonicalPrivateClaimOperation()
|
||||||
|
defer unlock()
|
||||||
if err := validateClaimPaths(source, claim); err != nil {
|
if err := validateClaimPaths(source, claim); err != nil {
|
||||||
return false, ErrUnsafeFile
|
return false, ErrUnsafeFile
|
||||||
}
|
}
|
||||||
@@ -363,6 +365,8 @@ func ClaimCanonicalPrivateRegular(source, claim string) (bool, error) {
|
|||||||
// ReadCanonicalPrivateClaim reads a verified two-link source/claim pair. found=false means the
|
// ReadCanonicalPrivateClaim reads a verified two-link source/claim pair. found=false means the
|
||||||
// state has already been consumed or a winning process is between its two removal steps.
|
// state has already been consumed or a winning process is between its two removal steps.
|
||||||
func ReadCanonicalPrivateClaim(source, claim string, maximum int64) ([]byte, bool, error) {
|
func ReadCanonicalPrivateClaim(source, claim string, maximum int64) ([]byte, bool, error) {
|
||||||
|
unlock := lockCanonicalPrivateClaimOperation()
|
||||||
|
defer unlock()
|
||||||
if maximum < 0 || maximum == int64(^uint64(0)>>1) || validateClaimPaths(source, claim) != nil {
|
if maximum < 0 || maximum == int64(^uint64(0)>>1) || validateClaimPaths(source, claim) != nil {
|
||||||
return nil, false, ErrUnsafeFile
|
return nil, false, ErrUnsafeFile
|
||||||
}
|
}
|
||||||
@@ -371,6 +375,8 @@ func ReadCanonicalPrivateClaim(source, claim string, maximum int64) ([]byte, boo
|
|||||||
|
|
||||||
// RemoveCanonicalPrivateClaim removes exactly a verified two-link source/claim pair.
|
// RemoveCanonicalPrivateClaim removes exactly a verified two-link source/claim pair.
|
||||||
func RemoveCanonicalPrivateClaim(source, claim string) (bool, error) {
|
func RemoveCanonicalPrivateClaim(source, claim string) (bool, error) {
|
||||||
|
unlock := lockCanonicalPrivateClaimOperation()
|
||||||
|
defer unlock()
|
||||||
if err := validateClaimPaths(source, claim); err != nil {
|
if err := validateClaimPaths(source, claim); err != nil {
|
||||||
return false, ErrUnsafeFile
|
return false, ErrUnsafeFile
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user