fix(safeio): normalize NT relative access masks
This commit is contained in:
@@ -178,6 +178,7 @@ func openWindowsRelativeObjectWithShareMode(
|
|||||||
if parent == 0 || !validPrivateLeafName(name) {
|
if parent == 0 || !validPrivateLeafName(name) {
|
||||||
return 0, ErrUnsafeFile
|
return 0, ErrUnsafeFile
|
||||||
}
|
}
|
||||||
|
access = normalizeWindowsNTDesiredAccess(access)
|
||||||
objectName, err := windows.NewNTUnicodeString(name)
|
objectName, err := windows.NewNTUnicodeString(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, ErrUnsafeFile
|
return 0, ErrUnsafeFile
|
||||||
@@ -203,10 +204,8 @@ func openWindowsRelativeObjectWithShareMode(
|
|||||||
attributes,
|
attributes,
|
||||||
&status,
|
&status,
|
||||||
&allocationSize,
|
&allocationSize,
|
||||||
// NtCreateFile expects zero here for the retained open/create contract. The
|
// NtCreateFile supplies the normal attribute default when this is zero; no
|
||||||
// Win32 FILE_ATTRIBUTE_NORMAL flag is not a valid NT FileAttributes value
|
// explicit creation attribute is needed for these retained open/create calls.
|
||||||
// for this RootDirectory-relative call and produces STATUS_INVALID_PARAMETER
|
|
||||||
// on the Windows runner.
|
|
||||||
0,
|
0,
|
||||||
shareMode,
|
shareMode,
|
||||||
disposition,
|
disposition,
|
||||||
@@ -222,6 +221,24 @@ func openWindowsRelativeObjectWithShareMode(
|
|||||||
return handle, nil
|
return handle, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func normalizeWindowsNTDesiredAccess(access uint32) uint32 {
|
||||||
|
if access&uint32(windows.GENERIC_ALL) != 0 {
|
||||||
|
const fileSpecificAll = uint32(0x1ff)
|
||||||
|
access = access&^uint32(windows.GENERIC_ALL) |
|
||||||
|
uint32(windows.STANDARD_RIGHTS_REQUIRED|windows.SYNCHRONIZE) | fileSpecificAll
|
||||||
|
}
|
||||||
|
if access&uint32(windows.GENERIC_READ) != 0 {
|
||||||
|
access = access&^uint32(windows.GENERIC_READ) | uint32(windows.FILE_GENERIC_READ)
|
||||||
|
}
|
||||||
|
if access&uint32(windows.GENERIC_WRITE) != 0 {
|
||||||
|
access = access&^uint32(windows.GENERIC_WRITE) | uint32(windows.FILE_GENERIC_WRITE)
|
||||||
|
}
|
||||||
|
if access&uint32(windows.GENERIC_EXECUTE) != 0 {
|
||||||
|
access = access&^uint32(windows.GENERIC_EXECUTE) | uint32(windows.FILE_GENERIC_EXECUTE)
|
||||||
|
}
|
||||||
|
return access
|
||||||
|
}
|
||||||
|
|
||||||
func privateWindowsDirectoryInfo(handle windows.Handle) (windows.ByHandleFileInformation, error) {
|
func privateWindowsDirectoryInfo(handle windows.Handle) (windows.ByHandleFileInformation, error) {
|
||||||
var info windows.ByHandleFileInformation
|
var info windows.ByHandleFileInformation
|
||||||
if handle == 0 || windows.GetFileInformationByHandle(handle, &info) != nil ||
|
if handle == 0 || windows.GetFileInformationByHandle(handle, &info) != nil ||
|
||||||
|
|||||||
@@ -70,6 +70,16 @@ func TestOwnerOnlyDACLAcceptsWindowsFullControlMask(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWindowsNTDesiredAccessMapsGenericBits(t *testing.T) {
|
||||||
|
if got, want := normalizeWindowsNTDesiredAccess(windows.GENERIC_READ), uint32(windows.FILE_GENERIC_READ); got != want {
|
||||||
|
t.Fatalf("normalized generic read access = %#x, want %#x", got, want)
|
||||||
|
}
|
||||||
|
want := uint32(windows.FILE_GENERIC_READ | windows.WRITE_DAC | windows.WRITE_OWNER)
|
||||||
|
if got := normalizeWindowsNTDesiredAccess(windows.GENERIC_READ | windows.WRITE_DAC | windows.WRITE_OWNER); got != want {
|
||||||
|
t.Fatalf("normalized protected read access = %#x, want %#x", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestOwnerOnlyDACLNativeShape(t *testing.T) {
|
func TestOwnerOnlyDACLNativeShape(t *testing.T) {
|
||||||
directory := filepath.Join(t.TempDir(), "auth")
|
directory := filepath.Join(t.TempDir(), "auth")
|
||||||
if err := os.Mkdir(directory, 0o700); err != nil {
|
if err := os.Mkdir(directory, 0o700); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user