winpath

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

README

Windows path identity

winpath is the leaf Windows object-path service. It accepts only absolute local DOS drive paths (ordinary or \\?\C:\... spelling), opens without following the leaf reparse point, and derives the canonical DOS name and stable identity from the resulting handle.

The package deliberately rejects UNC, object-manager/device, GLOBALROOT, named-pipe, raw-device, volume-GUID, drive-relative, alternate-stream, and non-NTFS/ReFS targets. It does not reinterpret an unsupported spelling as a broader path.

Handle ownership

Open returns an Object that exclusively owns its no-follow Windows handle. The handle pins the opened identity while callers compare the canonical DOS path, volume serial, 128-bit file ID, type, reparse tag, and link count. Copying an Object does not duplicate the kernel handle. The owner must call Close exactly once and must keep the object alive for the entire authorization or ACL mutation. Callers that need independent lifetimes must open independent objects.

Path strings never substitute for the retained handle. Revalidation fails when the final name, stable ID, type, or any ancestor/reparse transition changes. Unsupported namespace syntax is rejected before it can be normalized into a different authority class.

Live verification status

Cross-builds do not execute Windows syscalls. The required live gate remains pending on a supported Windows worker:

go test -race -count=1 ./internal/winpath ./pkg/profile ./internal/policy

Until that command passes on NTFS and ReFS fixtures, the implementation has compile/test-shape evidence only for Windows-specific behavior.

Documentation

Rendered for windows/amd64

Overview

Package winpath provides fail-closed, handle-derived Windows path identity.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnsupportedPath = errors.New("sandbox: unsupported Windows path")
	// ErrReparsePoint identifies the unsupported-path subset caused by a
	// reparse-point component. Callers that expose policy vocabulary can map
	// this filesystem-mechanism error without parsing an error string.
	ErrReparsePoint = errors.New("sandbox: Windows reparse-point path")
)

Functions

func Compare

func Compare(left, right string) int

Compare orders path keys with CompareStringOrdinal's case-insensitive UTF-16 semantics. It returns -1, 0, or 1.

func EqualPath

func EqualPath(left, right string) bool

EqualPath reports ordinal case-insensitive equality.

func HasPrefix

func HasPrefix(value, prefix string) bool

HasPrefix reports whether value begins with prefix under ordinal case-insensitive UTF-16 comparison.

func Normalize

func Normalize(path string) (string, error)

Normalize validates a path spelling without widening it and returns an absolute DOS-drive spelling suitable for CreateFileW.

func VolumeRoots

func VolumeRoots() ([]string, error)

VolumeRoots enumerates every supported fixed local NTFS/ReFS volume. A volume with no drive letter is represented by its ordinal-lowest DOS mount path; volume GUID paths never escape this package.

Types

type Kind

type Kind uint8
const (
	KindUnknown Kind = iota
	KindFile
	KindDirectory
	KindReparsePoint
)

type Object

type Object struct {
	Handle       windows.Handle
	DOSPath      string
	PathKey      string
	VolumeSerial uint64
	FileID       [16]byte
	Kind         Kind
	ReparseTag   uint32
	LinkCount    uint32
	// contains filtered or unexported fields
}

Object owns a no-follow Windows handle and the identity obtained from it.

func Open

func Open(path string) (*Object, error)

Open validates path, rejects reparse-point ancestors, and captures complete stable identity from an owned no-follow handle.

func OpenForACL

func OpenForACL(path string, directory, freezeWrites bool) (*Object, error)

OpenForACL performs the same no-follow component walk as Open, but opens the final object with the authority needed to inspect and replace its DACL. The returned handle never grants delete sharing. freezeWrites additionally denies data-write sharing while a tree is enumerated and projected.

This operation exists here, rather than being assembled by ACL callers, because handles created by NtCreateFile during the component walk cannot be safely assumed to be valid ReOpenFile inputs. The ACL-capable handle is the final result of the identity-preserving walk itself.

func OpenPinned

func OpenPinned(path string) (*Object, error)

OpenPinned is Open with delete-sharing denied. This prevents ordinary Win32 delete opens while the returned object is held, but it is only defense in depth: filesystems that support POSIX-style rename can still move a named object without honoring this sharing exclusion. Callers that rely on a path continuing to name this object must re-open and compare the complete identity before use. The retained handle itself continues to identify the original object even when its name moves.

func (*Object) Close

func (object *Object) Close() error

Close releases the owned handle. It is safe to call repeatedly.

func (*Object) SameIdentity

func (object *Object) SameIdentity(other *Object) bool

SameIdentity compares every security-relevant identity field.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL