]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[release-branch.go1.21] internal/syscall/windows: fix the signature of SetFileInforma...
authorBryan C. Mills <bcmills@google.com>
Tue, 12 Dec 2023 21:26:45 +0000 (16:26 -0500)
committerCarlos Amedee <carlos@golang.org>
Wed, 28 Feb 2024 19:46:24 +0000 (19:46 +0000)
Also fix its call site in internal/poll to pass the length of the
actual buffer instead of an unrelated variable, and update the
definition of FILE_BASIC_INFO to match the documented field types
and add padding that is empirically needed on the 386 architecture.

Passing a pointer to a Go-allocated buffer as type uintptr violates
the unsafe.Pointer conversion rules, which allow such a conversion
only in the call expression itself for a call to syscall.Syscall or
equivalent. That can allow the buffer to be corrupted arbitrarily if
the Go runtime happens to garbage-collect it while the call to
SetFileInformationByHandle is in progress.

The Microsoft documentation for SetFileInformationByHandle specifies
its third argument type as LPVOID, which corresponds to Go's
unsafe.Pointer, not uintptr.

Fixes #65882.
Updates #58933.

Change-Id: If577b57adea9922f5fcca55e46030c703d8f035c
Cq-Include-Trybots: luci.golang.try:go1.21-windows-amd64-longtest
Reviewed-on: https://go-review.googlesource.com/c/go/+/549256
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
(cherry picked from commit a7097243e462802f3055da9f843013e450a75092)
Reviewed-on: https://go-review.googlesource.com/c/go/+/566155
Reviewed-by: Bryan Mills <bcmills@google.com>
src/internal/poll/fd_windows.go
src/internal/syscall/windows/syscall_windows.go
src/internal/syscall/windows/zsyscall_windows.go

index 9df39edced5bba986e7e478f1b9b9734116a8cba..2095a6aa292700db883e7d973e76b9b330baf28d 100644 (file)
@@ -1037,8 +1037,7 @@ func (fd *FD) Fchmod(mode uint32) error {
 
        var du windows.FILE_BASIC_INFO
        du.FileAttributes = attrs
-       l := uint32(unsafe.Sizeof(d))
-       return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, uintptr(unsafe.Pointer(&du)), l)
+       return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, unsafe.Pointer(&du), uint32(unsafe.Sizeof(du)))
 }
 
 // Fchdir wraps syscall.Fchdir.
index e9390b07cd40a1c3a8957783c9d34b93a0a7bd33..ab2f9a1ad2c957ec8e66db5148fa172237c83995 100644 (file)
@@ -129,11 +129,22 @@ type SecurityAttributes struct {
 }
 
 type FILE_BASIC_INFO struct {
-       CreationTime   syscall.Filetime
-       LastAccessTime syscall.Filetime
-       LastWriteTime  syscall.Filetime
-       ChangedTime    syscall.Filetime
+       CreationTime   int64
+       LastAccessTime int64
+       LastWriteTime  int64
+       ChangedTime    int64
        FileAttributes uint32
+
+       // Pad out to 8-byte alignment.
+       //
+       // Without this padding, TestChmod fails due to an argument validation error
+       // in SetFileInformationByHandle on windows/386.
+       //
+       // https://learn.microsoft.com/en-us/cpp/build/reference/zp-struct-member-alignment?view=msvc-170
+       // says that “The C/C++ headers in the Windows SDK assume the platform's
+       // default alignment is used.” What we see here is padding rather than
+       // alignment, but maybe it is related.
+       _ uint32
 }
 
 const (
@@ -150,7 +161,7 @@ const (
 //sys  GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
 //sys  MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
 //sys  GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
-//sys  SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle
+//sys  SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf unsafe.Pointer, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle
 //sys  VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQuery
 //sys  GetTempPath2(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPath2W
 
index 26ec290e026c1a010b55acad874715782cf44c11..6be7aa470b656cc7a2135079c3b1ffee196fcca5 100644 (file)
@@ -295,7 +295,7 @@ func RtlVirtualUnwind(handlerType uint32, baseAddress uintptr, pc uintptr, entry
        return
 }
 
-func SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) {
+func SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf unsafe.Pointer, bufsize uint32) (err error) {
        r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(handle), uintptr(fileInformationClass), uintptr(buf), uintptr(bufsize), 0, 0)
        if r1 == 0 {
                err = errnoErr(e1)