Skip to content

Do not delete the authentication method local reference twice - #1002

Closed
fredericgermain wants to merge 1 commit into
netty:mainfrom
fredericgermain:fix-cert-verify-double-delete-local
Closed

fredericgermain wants to merge 1 commit into
netty:mainfrom
fredericgermain:fix-cert-verify-double-delete-local

Conversation

@fredericgermain

Copy link
Copy Markdown
Contributor

Motivation:

#996 added an early NETTY_JNI_UTIL_DELETE_LOCAL of authMethodString in both cert verify callbacks. The macro does not NULL its argument, and both functions already delete that reference again at their complete: label. A double DeleteLocalRef is fatal under -Xcheck:jni, so every openssl-dynamic job in netty/netty#17356 dies with:

FATAL ERROR in native method: Bad global or local ref passed to JNI
    at io.netty.internal.tcnative.SSL.readFromSSL(Native Method)
    at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.readPlaintextData

Only openssl is affected because SSL_cert_verify has no task path and always reaches both deletes. tcn_SSL_cert_custom_verify has the same defect, but netty defaults useTasks to true so that branch is skipped, which is why the boringssl jobs stay green. It is fixed here too rather than left waiting for someone to set useTasks to false.

Modification:

NULL authMethodString after the early delete in both functions, matching what get_certs and every other delete site in this file already do.

Result:

Fixes netty/netty#17356. Verified on macOS aarch64 against OpenSSL 3.6.3, driving a pair of netty SSLEngines through a handshake under -Xcheck:jni: unpatched the JVM dies on the first handshake, patched 50 handshakes complete over TLSv1.3.

https://claude.ai/code/session_01RVaAsJndUk7hxtG38JTxTc

Motivation:

netty/netty#17356, which only bumps to 2.0.82.Final, dies in every
openssl-dynamic job with

  FATAL ERROR in native method: Bad global or local ref passed to JNI
      at io.netty.internal.tcnative.SSL.readFromSSL(Native Method)
      at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.readPlaintextData

netty#996 added an early NETTY_JNI_UTIL_DELETE_LOCAL of authMethodString right
after the verifier callback returns, but that macro does not NULL its
argument and both cert verify functions already delete the same reference
again at their complete: label. Deleting a local reference twice is fatal
under -Xcheck:jni, which netty's test JVMs run with, and it is undefined
behaviour without it.

Every other delete site in this file already clears the variable after
deleting it, get_certs included. These two were the only ones that did not.

This is only visible on the openssl build because SSL_cert_verify has no
task path: it always reaches both deletes. The BoringSSL and AWS-LC twin,
tcn_SSL_cert_custom_verify, has the same defect but netty defaults
io.netty.handler.ssl.openssl.useTasks to true, so the branch that carries
it is not taken and the boringssl jobs stay green. It is fixed here too
rather than left waiting for someone to set useTasks to false.

Modification:

NULL authMethodString after the early delete in SSL_cert_verify and in
tcn_SSL_cert_custom_verify, so the complete: block skips it.

Result:

Reproduced first on macOS aarch64 against OpenSSL 3.6.3, driving a pair of
netty SSLEngines through a handshake under -Xcheck:jni: unpatched, the JVM
dies on the first handshake with the stack above; patched, 50 handshakes
complete and negotiate TLS_AES_128_GCM_SHA256 over TLSv1.3. Confirmed
separately with a standalone JNI test that a second DeleteLocalRef on the
same reference produces exactly this error on its first occurrence, and
that clearing the variable removes it.
@normanmaurer

Copy link
Copy Markdown
Member

This was already fixed by #1001

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants