From af60ab229954519b8295bb3ef453231f4d3b9087 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 11 Oct 2021 13:08:50 -0600 Subject: global: use unsafe.Slice instead of unsafeSlice Signed-off-by: Jason A. Donenfeld --- conf/dpapi/dpapi_windows.go | 22 ++++------------------ conf/dpapi/dpapi_windows_test.go | 6 +----- driver/configuration_windows.go | 27 +++------------------------ driver/memmod/memmod_windows.go | 40 +++++++--------------------------------- manager/service.go | 7 +------ tunnel/winipcfg/types.go | 33 +++++---------------------------- 6 files changed, 21 insertions(+), 114 deletions(-) diff --git a/conf/dpapi/dpapi_windows.go b/conf/dpapi/dpapi_windows.go index b3f28a93..b8e6af4b 100644 --- a/conf/dpapi/dpapi_windows.go +++ b/conf/dpapi/dpapi_windows.go @@ -28,16 +28,9 @@ func Encrypt(data []byte, name string) ([]byte, error) { if err != nil { return nil, fmt.Errorf("unable to encrypt DPAPI protected data: %w", err) } - - outSlice := *(*[]byte)(unsafe.Pointer(&(struct { - addr *byte - len int - cap int - }{out.Data, int(out.Size), int(out.Size)}))) - ret := make([]byte, len(outSlice)) - copy(ret, outSlice) + ret := make([]byte, out.Size) + copy(ret, unsafe.Slice(out.Data, out.Size)) windows.LocalFree(windows.Handle(unsafe.Pointer(out.Data))) - return ret, nil } @@ -48,19 +41,12 @@ func Decrypt(data []byte, name string) ([]byte, error) { if err != nil { return nil, err } - err = windows.CryptUnprotectData(bytesToBlob(data), &outName, nil, 0, nil, windows.CRYPTPROTECT_UI_FORBIDDEN, &out) if err != nil { return nil, fmt.Errorf("unable to decrypt DPAPI protected data: %w", err) } - - outSlice := *(*[]byte)(unsafe.Pointer(&(struct { - addr *byte - len int - cap int - }{out.Data, int(out.Size), int(out.Size)}))) - ret := make([]byte, len(outSlice)) - copy(ret, outSlice) + ret := make([]byte, out.Size) + copy(ret, unsafe.Slice(out.Data, out.Size)) windows.LocalFree(windows.Handle(unsafe.Pointer(out.Data))) // Note: this ridiculous open-coded strcmp is not constant time. diff --git a/conf/dpapi/dpapi_windows_test.go b/conf/dpapi/dpapi_windows_test.go index 2e12e273..351b4d8f 100644 --- a/conf/dpapi/dpapi_windows_test.go +++ b/conf/dpapi/dpapi_windows_test.go @@ -53,11 +53,7 @@ func TestRoundTrip(t *testing.T) { if err != nil { t.Errorf("Unable to get utf16 chars for name: %s", err) } - nameUtf16Bytes := *(*[]byte)(unsafe.Pointer(&struct { - addr *byte - len int - cap int - }{(*byte)(unsafe.Pointer(&nameUtf16[0])), len(nameUtf16) * 2, cap(nameUtf16) * 2})) + nameUtf16Bytes := unsafe.Slice((*byte)(unsafe.Pointer(&nameUtf16[0])), len(nameUtf16) * 2) i := bytes.Index(eCorrupt, nameUtf16Bytes) if i == -1 { t.Error("Unable to find ad in blob") diff --git a/driver/configuration_windows.go b/driver/configuration_windows.go index a9f08a91..2029c75a 100644 --- a/driver/configuration_windows.go +++ b/driver/configuration_windows.go @@ -158,22 +158,19 @@ func (builder *ConfigBuilder) Preallocate(size uint32) { // AppendInterface appends an interface to the building configuration. This should be called first. func (builder *ConfigBuilder) AppendInterface(interfaze *Interface) { - var newBytes []byte - unsafeSlice(unsafe.Pointer(&newBytes), unsafe.Pointer(interfaze), int(unsafe.Sizeof(*interfaze))) + newBytes := unsafe.Slice((*byte)(unsafe.Pointer(interfaze)), unsafe.Sizeof(*interfaze)) builder.buffer = append(builder.buffer, newBytes...) } // AppendPeer appends a peer to the building configuration. This should be called after an interface has been added. func (builder *ConfigBuilder) AppendPeer(peer *Peer) { - var newBytes []byte - unsafeSlice(unsafe.Pointer(&newBytes), unsafe.Pointer(peer), int(unsafe.Sizeof(*peer))) + newBytes := unsafe.Slice((*byte)(unsafe.Pointer(peer)), unsafe.Sizeof(*peer)) builder.buffer = append(builder.buffer, newBytes...) } // AppendAllowedIP appends an allowed IP to the building configuration. This should be called after a peer has been added. func (builder *ConfigBuilder) AppendAllowedIP(allowedIP *AllowedIP) { - var newBytes []byte - unsafeSlice(unsafe.Pointer(&newBytes), unsafe.Pointer(allowedIP), int(unsafe.Sizeof(*allowedIP))) + newBytes := unsafe.Slice((*byte)(unsafe.Pointer(allowedIP)), unsafe.Sizeof(*allowedIP)) builder.buffer = append(builder.buffer, newBytes...) } @@ -184,21 +181,3 @@ func (builder *ConfigBuilder) Interface() (*Interface, uint32) { } return (*Interface)(unsafe.Pointer(&builder.buffer[0])), uint32(len(builder.buffer)) } - -// unsafeSlice updates the slice slicePtr to be a slice -// referencing the provided data with its length & capacity set to -// lenCap. -// -// TODO: when Go 1.16 or Go 1.17 is the minimum supported version, -// update callers to use unsafe.Slice instead of this. -func unsafeSlice(slicePtr, data unsafe.Pointer, lenCap int) { - type sliceHeader struct { - Data unsafe.Pointer - Len int - Cap int - } - h := (*sliceHeader)(slicePtr) - h.Data = data - h.Len = lenCap - h.Cap = lenCap -} diff --git a/driver/memmod/memmod_windows.go b/driver/memmod/memmod_windows.go index 6ced43fe..da6ff9af 100644 --- a/driver/memmod/memmod_windows.go +++ b/driver/memmod/memmod_windows.go @@ -64,8 +64,7 @@ func (module *Module) copySections(address uintptr, size uintptr, oldHeaders *IM dest = module.codeBase + uintptr(sections[i].VirtualAddress) // NOTE: On 64bit systems we truncate to 32bit here but expand again later when "PhysicalAddress" is used. sections[i].SetPhysicalAddress((uint32)(dest & 0xffffffff)) - var dst []byte - unsafeSlice(unsafe.Pointer(&dst), a2p(dest), int(sectionSize)) + dst := unsafe.Slice((*byte)(a2p(dest)), sectionSize) for j := range dst { dst[j] = 0 } @@ -247,11 +246,9 @@ func (module *Module) performBaseRelocation(delta uintptr) (relocated bool, err for relocationHdr.VirtualAddress > 0 { dest := module.codeBase + uintptr(relocationHdr.VirtualAddress) - var relInfos []uint16 - unsafeSlice( - unsafe.Pointer(&relInfos), - a2p(uintptr(unsafe.Pointer(relocationHdr))+unsafe.Sizeof(*relocationHdr)), - int((uintptr(relocationHdr.SizeOfBlock)-unsafe.Sizeof(*relocationHdr))/unsafe.Sizeof(relInfos[0]))) + relInfos := unsafe.Slice( + (*uint16)(a2p(uintptr(unsafe.Pointer(relocationHdr))+unsafe.Sizeof(*relocationHdr))), + (uintptr(relocationHdr.SizeOfBlock)-unsafe.Sizeof(*relocationHdr))/unsafe.Sizeof(uint16(0))) for _, relInfo := range relInfos { // The upper 4 bits define the type of relocation. relType := relInfo >> 12 @@ -372,10 +369,8 @@ func (module *Module) buildNameExports() error { if exports.NumberOfNames == 0 { return errors.New("No functions exported by name") } - var nameRefs []uint32 - unsafeSlice(unsafe.Pointer(&nameRefs), a2p(module.codeBase+uintptr(exports.AddressOfNames)), int(exports.NumberOfNames)) - var ordinals []uint16 - unsafeSlice(unsafe.Pointer(&ordinals), a2p(module.codeBase+uintptr(exports.AddressOfNameOrdinals)), int(exports.NumberOfNames)) + nameRefs := unsafe.Slice((*uint32)(a2p(module.codeBase+uintptr(exports.AddressOfNames))), exports.NumberOfNames) + ordinals := unsafe.Slice((*uint16)(a2p(module.codeBase+uintptr(exports.AddressOfNameOrdinals))), exports.NumberOfNames) module.nameExports = make(map[string]uint16) for i := range nameRefs { nameArray := windows.BytePtrToString((*byte)(a2p(module.codeBase + uintptr(nameRefs[i])))) @@ -694,26 +689,5 @@ func a2p(addr uintptr) unsafe.Pointer { } func memcpy(dst, src, size uintptr) { - var d, s []byte - unsafeSlice(unsafe.Pointer(&d), a2p(dst), int(size)) - unsafeSlice(unsafe.Pointer(&s), a2p(src), int(size)) - copy(d, s) -} - -// unsafeSlice updates the slice slicePtr to be a slice -// referencing the provided data with its length & capacity set to -// lenCap. -// -// TODO: when Go 1.16 or Go 1.17 is the minimum supported version, -// update callers to use unsafe.Slice instead of this. -func unsafeSlice(slicePtr, data unsafe.Pointer, lenCap int) { - type sliceHeader struct { - Data unsafe.Pointer - Len int - Cap int - } - h := (*sliceHeader)(slicePtr) - h.Data = data - h.Len = lenCap - h.Cap = lenCap + copy(unsafe.Slice((*byte)(a2p(dst)), size), unsafe.Slice((*byte)(a2p(src)), size)) } diff --git a/manager/service.go b/manager/service.go index 2b553793..71be634d 100644 --- a/manager/service.go +++ b/manager/service.go @@ -278,12 +278,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest serviceError = services.ErrorEnumerateSessions return } - sessions := *(*[]windows.WTS_SESSION_INFO)(unsafe.Pointer(&struct { - addr *windows.WTS_SESSION_INFO - len int - cap int - }{sessionsPointer, int(count), int(count)})) - for _, session := range sessions { + for _, session := range unsafe.Slice(sessionsPointer, count) { if session.State != windows.WTSActive && session.State != windows.WTSDisconnected { continue } diff --git a/tunnel/winipcfg/types.go b/tunnel/winipcfg/types.go index d82d1a6f..789ee501 100644 --- a/tunnel/winipcfg/types.go +++ b/tunnel/winipcfg/types.go @@ -685,8 +685,7 @@ func (row *MibIPInterfaceRow) Set() error { // get method returns all table rows as a Go slice. func (tab *mibIPInterfaceTable) get() (s []MibIPInterfaceRow) { - unsafeSlice(unsafe.Pointer(&s), unsafe.Pointer(&tab.table[0]), int(tab.numEntries)) - return + return unsafe.Slice(&tab.table[0], tab.numEntries) } // free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes. @@ -723,8 +722,7 @@ func (row *MibIfRow2) get() (ret error) { // get method returns all table rows as a Go slice. func (tab *mibIfTable2) get() (s []MibIfRow2) { - unsafeSlice(unsafe.Pointer(&s), unsafe.Pointer(&tab.table[0]), int(tab.numEntries)) - return + return unsafe.Slice(&tab.table[0], tab.numEntries) } // free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes. @@ -835,8 +833,7 @@ func (row *MibUnicastIPAddressRow) Delete() error { // get method returns all table rows as a Go slice. func (tab *mibUnicastIPAddressTable) get() (s []MibUnicastIPAddressRow) { - unsafeSlice(unsafe.Pointer(&s), unsafe.Pointer(&tab.table[0]), int(tab.numEntries)) - return + return unsafe.Slice(&tab.table[0], tab.numEntries) } // free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes. @@ -865,8 +862,7 @@ func (row *MibAnycastIPAddressRow) Delete() error { // get method returns all table rows as a Go slice. func (tab *mibAnycastIPAddressTable) get() (s []MibAnycastIPAddressRow) { - unsafeSlice(unsafe.Pointer(&s), unsafe.Pointer(&tab.table[0]), int(tab.numEntries)) - return + return unsafe.Slice(&tab.table[0], tab.numEntries) } // free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes. @@ -958,8 +954,7 @@ func (row *MibIPforwardRow2) Delete() error { // get method returns all table rows as a Go slice. func (tab *mibIPforwardTable2) get() (s []MibIPforwardRow2) { - unsafeSlice(unsafe.Pointer(&s), unsafe.Pointer(&tab.table[0]), int(tab.numEntries)) - return + return unsafe.Slice(&tab.table[0], tab.numEntries) } // free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes. @@ -1007,21 +1002,3 @@ const ( DnsInterfaceSettingsFlagDOH = 0x1000 // v3 only DnsInterfaceSettingsFlagDOHProfile = 0x2000 // v3 only ) - -// unsafeSlice updates the slice slicePtr to be a slice -// referencing the provided data with its length & capacity set to -// lenCap. -// -// TODO: when Go 1.16 or Go 1.17 is the minimum supported version, -// update callers to use unsafe.Slice instead of this. -func unsafeSlice(slicePtr, data unsafe.Pointer, lenCap int) { - type sliceHeader struct { - Data unsafe.Pointer - Len int - Cap int - } - h := (*sliceHeader)(slicePtr) - h.Data = data - h.Len = lenCap - h.Cap = lenCap -} -- cgit v1.2.3-59-g8ed1b