@@ -18,16 +18,17 @@ import (
1818 "golang.org/x/sys/unix"
1919)
2020
21- func rerankerProcessExecutableIdentity (pid int ) (uint64 , uint64 , error ) {
22- type uniqueIdentifierInfo struct {
23- UUID [16 ]byte
24- UniqueID uint64
25- ParentUniqueID uint64
26- IDVersion int32
27- Reserved2 uint32
28- Reserved3 uint64
29- Reserved4 uint64
30- }
21+ type uniqueIdentifierInfo struct {
22+ UUID [16 ]byte
23+ UniqueID uint64
24+ ParentUniqueID uint64
25+ IDVersion int32
26+ Reserved2 uint32
27+ Reserved3 uint64
28+ Reserved4 uint64
29+ }
30+
31+ func darwinProcessIdentity (pid int ) (uniqueIdentifierInfo , error ) {
3132 var identity uniqueIdentifierInfo
3233 const (
3334 procInfoCallPIDInfo = 0x2
@@ -44,10 +45,18 @@ func rerankerProcessExecutableIdentity(pid int) (uint64, uint64, error) {
4445 unsafe .Sizeof (identity ),
4546 )
4647 if errno != 0 {
47- return 0 , 0 , errno
48+ return identity , errno
4849 }
4950 if result != unsafe .Sizeof (identity ) {
50- return 0 , 0 , fmt .Errorf ("unexpected Darwin executable identity size %d" , result )
51+ return identity , fmt .Errorf ("unexpected Darwin executable identity size %d" , result )
52+ }
53+ return identity , nil
54+ }
55+
56+ func rerankerProcessExecutableIdentity (pid int ) (uint64 , uint64 , error ) {
57+ identity , err := darwinProcessIdentity (pid )
58+ if err != nil {
59+ return 0 , 0 , err
5160 }
5261 first := binary .LittleEndian .Uint64 (identity .UUID [:8 ])
5362 second := binary .LittleEndian .Uint64 (identity .UUID [8 :])
@@ -177,10 +186,20 @@ type rerankerProcessHandle struct {
177186
178187func openRerankerProcessHandle (pid int , started string , identity * os.File ) (* rerankerProcessHandle , error ) {
179188 token , err := peerAuditToken (identity )
180- if err != nil {
189+ if errors .Is (err , unix .ENOTCONN ) {
190+ // The executed program may close inherited descriptors before we
191+ // observe its image. Darwin's proc_find_audit_token (used by signal)
192+ // checks only PID and pidversion; obtain both from kernel process
193+ // information rather than falling back to a racy kill(pid).
194+ info , infoErr := darwinProcessIdentity (pid )
195+ if infoErr != nil {
196+ return nil , infoErr
197+ }
198+ token = [8 ]uint32 {5 : uint32 (pid ), 7 : uint32 (info .IDVersion )}
199+ } else if err != nil {
181200 return nil , err
182201 }
183- if int (token [5 ]) != pid || rerankerProcessStartIdentity (pid ) != started {
202+ if int (token [5 ]) != pid || started == "" || rerankerProcessStartIdentity (pid ) != started {
184203 return nil , fmt .Errorf ("reranker process generation changed while acquiring audit token" )
185204 }
186205 return & rerankerProcessHandle {token : token }, nil
0 commit comments