Because of the PublicKeyECDSA (pub) finalizer, any time pub.key is passed to cgo, that call must be followed by a call to runtime.KeepAlive, to make sure pub is not collected (and finalized) before the call returns.
VerifyECDSA does call runtime.KeepAlive, but that call will be deleted if the compiler can prove that h is always 0, leaving _goboringcrypto_internal_ECDSA_verify call vulnerable at garbage collector mercy.
The fix is easy, just add a runtime.KeepAlice call to the h == crypto.Hash(0) branch.
PD. We (Go team at Microsoft) found this bug when porting the OpenSSL bindings in here to our own repo, located at https://github.com/microsoft/go-crypto-openssl. To be specific, the test that caught the use-after-free error was TestECDSASignAndVerify, in case you want to port it to your test-suite.
Because of the PublicKeyECDSA (pub) finalizer, any time pub.key is passed to cgo, that call must be followed by a call to runtime.KeepAlive, to make sure pub is not collected (and finalized) before the call returns.
VerifyECDSA does call runtime.KeepAlive, but that call will be deleted if the compiler can prove that h is always 0, leaving _goboringcrypto_internal_ECDSA_verify call vulnerable at garbage collector mercy.
The fix is easy, just add a runtime.KeepAlice call to the h == crypto.Hash(0) branch.
PD. We (Go team at Microsoft) found this bug when porting the OpenSSL bindings in here to our own repo, located at https://github.com/microsoft/go-crypto-openssl. To be specific, the test that caught the use-after-free error was TestECDSASignAndVerify, in case you want to port it to your test-suite.