windows: support nil security descriptor on GetNamedSecurityInfo

GetNamedSecurityInfoW may return a nil security descriptor when the
object exists but has no security descriptor. This change allows
GetNamedSecurityInfo to return a nil *SECURITY_DESCRIPTOR in that case,
instead of crashing when trying to copy the nil security descriptor.

Fixes golang/go#78396

Change-Id: I2f8d26a431e0a5c3de535cf8983db1465acc24fe
Reviewed-on: https://go-review.googlesource.com/c/sys/+/760160
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/windows/security_windows.go b/windows/security_windows.go
index a8b0364..6c955ce 100644
--- a/windows/security_windows.go
+++ b/windows/security_windows.go
@@ -1438,13 +1438,17 @@
 }
 
 // GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security
-// descriptor result on the Go heap.
+// descriptor result on the Go heap. The security descriptor might be nil, even when err is nil, if the object exists
+// but has no security descriptor.
 func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
 	var winHeapSD *SECURITY_DESCRIPTOR
 	err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
 	if err != nil {
 		return
 	}
+	if winHeapSD == nil {
+		return nil, nil
+	}
 	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
 	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
 }