fix(auth): pin native auth storage operations
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package safeio
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// PrivateDirectoryHandle pins one private directory for the duration of a storage operation.
|
||||
// Implementations use descriptor-relative operations on POSIX and retained no-delete handles on
|
||||
// Windows. Callers must close every returned child before releasing its parent.
|
||||
type PrivateDirectoryHandle interface {
|
||||
Close() error
|
||||
Validate() error
|
||||
OpenChild(name string, ensure bool) (PrivateDirectoryHandle, bool, error)
|
||||
CreateRegular(name string, contents []byte) (bool, error)
|
||||
ReadRegular(name string, maximum int64) ([]byte, bool, error)
|
||||
ReplaceRegular(name string, contents []byte) error
|
||||
RemoveRegular(name string) (bool, error)
|
||||
ListPage(maximumEntries int, afterName string, validName func(string) bool, validLinks func(string, uint64) bool) (PrivateDirectoryPage, error)
|
||||
ClaimRegular(source, claim string) (bool, error)
|
||||
ReadClaim(source, claim string, maximum int64) ([]byte, bool, error)
|
||||
RemoveClaim(source, claim string) (bool, error)
|
||||
}
|
||||
|
||||
// OpenPrivateDirectory validates or creates the final private directory while retaining the
|
||||
// opened canonical directory handle. With ensure=false, found=false means the final component is
|
||||
// absent but its already-opened parent proves the same operation could safely create it.
|
||||
func OpenPrivateDirectory(path string, ensure bool) (PrivateDirectoryHandle, bool, error) {
|
||||
if err := ValidateCanonicalPath(path); err != nil {
|
||||
return nil, false, ErrUnsafeFile
|
||||
}
|
||||
return openPrivateDirectory(path, ensure)
|
||||
}
|
||||
|
||||
func validPrivateLeafName(name string) bool {
|
||||
return name != "" && name != "." && name != ".." && !strings.ContainsAny(name, "\\/:\x00")
|
||||
}
|
||||
|
||||
var privateDirectoryTestHook struct {
|
||||
sync.RWMutex
|
||||
hook func(string)
|
||||
}
|
||||
|
||||
// SetPrivateDirectoryTestHookForTest installs a deterministic race hook for internal package
|
||||
// tests. It has no production effect unless a test explicitly installs one.
|
||||
func SetPrivateDirectoryTestHookForTest(hook func(string)) func() {
|
||||
privateDirectoryTestHook.Lock()
|
||||
previous := privateDirectoryTestHook.hook
|
||||
privateDirectoryTestHook.hook = hook
|
||||
privateDirectoryTestHook.Unlock()
|
||||
return func() {
|
||||
privateDirectoryTestHook.Lock()
|
||||
privateDirectoryTestHook.hook = previous
|
||||
privateDirectoryTestHook.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// NotifyPrivateDirectoryTestHookForTest marks an internal retained-root boundary. It is called
|
||||
// only by storage code and lets tests install deterministic directory replacement races.
|
||||
func NotifyPrivateDirectoryTestHookForTest(stage string) {
|
||||
privateDirectoryTestHook.RLock()
|
||||
hook := privateDirectoryTestHook.hook
|
||||
privateDirectoryTestHook.RUnlock()
|
||||
if hook != nil {
|
||||
hook(stage)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user