Skip to content

Commit

Permalink
pkcs11mod: Work around certutil hang bug
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyRand committed Mar 17, 2022
1 parent 1ea559c commit 945cc67
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pkcs11mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ func Go_Initialize() C.CK_RV {
//export Go_Finalize
func Go_Finalize() C.CK_RV {
err := backend.Finalize()

exitSoon()

return fromError(err)
}

Expand Down
3 changes: 3 additions & 0 deletions prevent_unload_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ package pkcs11mod

func preventUnload() {
}

func exitSoon() {
}
39 changes: 39 additions & 0 deletions prevent_unload_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ package pkcs11mod

import (
"log"
"os"
"path/filepath"
"time"

"golang.org/x/sys/windows"
)
Expand Down Expand Up @@ -37,3 +40,39 @@ func preventUnload() {
log.Println("pkcs11mod: Pinned module")
}
}

// This hack prevents a hang if the application tries to wait for all
// background threads to finish before exiting the process. Affected
// applications include Unity and NSS certutil.
// See the following references:
// https://github.com/golang/go/issues/11100#issuecomment-389539527
// https://github.com/golang/go/issues/11100#issuecomment-487840893
func exitSoon() {
exePath, err := os.Executable()
if err != nil {
log.Printf("pkcs11mod: Error detecting executable name: %s", err)
return
}

exe := filepath.Base(exePath)

shouldForceExitSoon := false

switch exe {
case "certutil.exe":
shouldForceExitSoon = true
default:
log.Println("pkcs11mod: Unknown exe name '%s'. This is probably fine, but if you see this application hang on exit immediately after this message was logged, consider reporting a bug to pkcs11mod; provide the exe name from this log message.", exe)
}

if shouldForceExitSoon {
if trace {
log.Println("pkcs11mod: Exiting process soon")
}

go func() {
time.Sleep(5 * time.Second)
os.Exit(0)
}()
}
}

0 comments on commit 945cc67

Please sign in to comment.