Skip to content

Commit 6a85559

Browse files
thepuddsgopherbot
authored andcommitted
windows: fix dangling pointers in (*SECURITY_DESCRIPTOR).ToAbsolute
Prior to this CL, a byte slice was allocated via make to use as the absoluteSD argument passed to the Windows API MakeAbsoluteSD. MakeAbsoluteSD then sets pointers outside the view of the GC, including pointers within absoluteSD that point to other chunks of memory we pass into MakeAbsoluteSD. CL 653856 recently allowed more make results to be stack allocated, which worsened the problems here and made it easier for those pointers in absoluteSD to become dangling pointers, though the core problems here existed before. This CL instead allocates absoluteSD as a proper SECURITY_DESCRIPTOR struct so that the GC can be aware of its pointers. We also verify the pointers are as we expect, and then set them explicitly in view of the GC. Updates golang/go#73199 Change-Id: Id8038d38a887bb8ff3ffc6eae603589b97e92cdc Reviewed-on: https://go-review.googlesource.com/c/sys/+/663355 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Auto-Submit: Dmitri Shuralyov <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 01aaa83 commit 6a85559

File tree

1 file changed

+44
-5
lines changed

1 file changed

+44
-5
lines changed

windows/security_windows.go

+44-5
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,10 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE
13031303
return nil, err
13041304
}
13051305
if absoluteSDSize > 0 {
1306-
absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0]))
1306+
absoluteSD = new(SECURITY_DESCRIPTOR)
1307+
if unsafe.Sizeof(*absoluteSD) < uintptr(absoluteSDSize) {
1308+
panic("sizeof(SECURITY_DESCRIPTOR) too small")
1309+
}
13071310
}
13081311
var (
13091312
dacl *ACL
@@ -1312,19 +1315,55 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE
13121315
group *SID
13131316
)
13141317
if daclSize > 0 {
1315-
dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0]))
1318+
dacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, daclSize))))
13161319
}
13171320
if saclSize > 0 {
1318-
sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0]))
1321+
sacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, saclSize))))
13191322
}
13201323
if ownerSize > 0 {
1321-
owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0]))
1324+
owner = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, ownerSize))))
13221325
}
13231326
if groupSize > 0 {
1324-
group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0]))
1327+
group = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, groupSize))))
13251328
}
1329+
// We call into Windows via makeAbsoluteSD, which sets up
1330+
// pointers within absoluteSD that point to other chunks of memory
1331+
// we pass into makeAbsoluteSD, and that happens outside the view of the GC.
1332+
// We therefore take some care here to then verify the pointers are as we expect
1333+
// and set them explicitly in view of the GC. See https://go.dev/issue/73199.
1334+
// TODO: consider weak pointers once Go 1.24 is appropriate. See suggestion in https://go.dev/cl/663575.
13261335
err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
13271336
dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
1337+
if err != nil {
1338+
// Don't return absoluteSD, which might be partially initialized.
1339+
return nil, err
1340+
}
1341+
// Before using any fields, verify absoluteSD is in the format we expect according to Windows.
1342+
// See https://learn.microsoft.com/en-us/windows/win32/secauthz/absolute-and-self-relative-security-descriptors
1343+
absControl, _, err := absoluteSD.Control()
1344+
if err != nil {
1345+
panic("absoluteSD: " + err.Error())
1346+
}
1347+
if absControl&SE_SELF_RELATIVE != 0 {
1348+
panic("absoluteSD not in absolute format")
1349+
}
1350+
if absoluteSD.dacl != dacl {
1351+
panic("dacl pointer mismatch")
1352+
}
1353+
if absoluteSD.sacl != sacl {
1354+
panic("sacl pointer mismatch")
1355+
}
1356+
if absoluteSD.owner != owner {
1357+
panic("owner pointer mismatch")
1358+
}
1359+
if absoluteSD.group != group {
1360+
panic("group pointer mismatch")
1361+
}
1362+
absoluteSD.dacl = dacl
1363+
absoluteSD.sacl = sacl
1364+
absoluteSD.owner = owner
1365+
absoluteSD.group = group
1366+
13281367
return
13291368
}
13301369

0 commit comments

Comments
 (0)