-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8290005: com/sun/jndi/ldap/LdapCBPropertiesTest.java failling with NullPointerException #13742
Conversation
…llPointerException
👋 Welcome back mpdonova! A progress list of the required criteria for merging this PR into |
Webrevs
|
!conContext.handshakeContext.taskDelegated && | ||
!conContext.handshakeContext.delegatedActions.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't you replace conContext.handshakeContext
with context
in those two lines as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I definitely should have done that. Thanks.
handshakeCtxLock.lock(); | ||
handshakeContext = null; | ||
handshakeCtxLock.unlock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The usual pattern is to use try { } finally { } with locks (even though in this particular case I don't see how the assignment would throw) - but if more things need to be done in the future here then at least the try { } finally { } will be in place.
handshakeCtxLock.lock(); | |
handshakeContext = null; | |
handshakeCtxLock.unlock(); | |
handshakeCtxLock.lock(); | |
try { | |
handshakeContext = null; | |
} finally { | |
handshakeCtxLock.unlock(); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the try/finally.
…t variable in all places it should be
@@ -89,6 +88,7 @@ final class TransportContext implements ConnectionContext { | |||
|
|||
// handshake context | |||
HandshakeContext handshakeContext = null; | |||
Lock handshakeCtxLock = new ReentrantLock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handshakeCtxLock
should be declared final.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. You will need approval from a security-dev Reviewer before pushing though.
In particular I am not sure about the implication of removing the lock around SSLEngineIml::getHandshakeSession()
and SSLSocketImpl::getHandshakeApplicationProtocols()
Can a security-dev Reviewer take a look at this? Thanks! |
Hi, I'm still looking for a Reviewer for this PR. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me.
@mpdonova This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 3 new commits pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the ➡️ To integrate this PR with the above commit message to the |
@@ -911,13 +912,7 @@ public SSLSession getSession() { | |||
|
|||
@Override | |||
public SSLSession getHandshakeSession() { | |||
engineLock.lock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not very sure of this update. By removing the enginLock on socket/engine level here, is it possible there are two threads that one read the handshake session and another on write?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
engineLock
was used to here to make sure that conContext.handshakeContext
is not null before accessing it. The problem is that the handshakeContext
is modified (set to null) by the TransportContext
class. So using a lock in SSLEngineImpl or SSLSocketImpl doesn't protect handshakeContext
from becoming null between the check and use.
The actual SSLSession object was never protected from concurrent modification (unless it has its own lock.)
When reviewing the code to answer this, I noticed that I needed to update SSLEngineImpl.getHandshakeApplicationProtocol()
so there is a new commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a search of the value assignment of handshakeSession. Here is one example of the calling stack:
SSLEngineImpl.DelegatedTask.run()->TransportContext.dispatch()->SSLHandshake().consume()->HandshakeConsumer.consume()->SSLExtensions.product()->ServerHello.produce()->shc.handshakeSession = session
The engineLock was placed on SSLEngineImpl.DelegatedTask.run() and released after complete the job, which means the value assignment of handshakeSession is synchronized.
The locks in SSLEngineImpl and SSLSocketImpl are used for operations synchronization so that other classes may not need additional locks in most cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you're saying with respect to SSLEngineImpl. It looks like all of the public methods are synchronized with engineLock
so I shouldn't have made any changes there. I will revert them.
Are you ok with the changes in SSLSocketImpl?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may update both SSLSocketImpl and SSLEngineImpl, as SSLSocketImpl uses the locks similar to SSLEngineImpl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay on any updates here.
I updated this branch and verified the tests still pass. I ran jdk_security3 tests from test/jdk/TEST.groups. Is there anything else I should do to test this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SSLSocketImpl uses the locks similar to SSLEngineImpl. It may get it complicated and hard to maintain if using different locks in SSLSocketImpl and SSLEngineImpl. You may be able to find similar locking scenarios in SSLSocket implementation like: SSLEngineImpl.DelegatedTask.run()->TransportContext.dispatch()->SSLHandshake().consume()->HandshakeConsumer.consume()->SSLExtensions.product()->ServerHello.produce()->shc.handshakeSession = session.
I understand where you came from for the NullPointerException in the bug. But it is hardly the direction to change the overall locking scenarios. Maybe, the close() function implementation could be focused on instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only lock I added was in TransportContext
to synchronize access to the handshakeContext
field, but I understand your reluctance to make any changes with locks. The problem is that SSLSocketImpl tries to access conContext.handshakeContext.negotiatedProtocol
after TransportContext has set handshakeContext to null.
TransportContext also has a protocolVersion
field. Is it possible to just use that instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TransportContext also has a
protocolVersion
field. Is it possible to just use that instead?
Did you mean a change in duplexCloseOutput() like the following?
- // The protocol version may have been negotiated.
- ProtocolVersion pv = conContext.handshakeContext.negotiatedProtocol;
+ // The protocol version may have been negotiated. The
+ // conContext.handshakeContext.negotiatedProtocol is not used as there
+ // may be a race to set it to null.
+ ProtocolVersion pv = conContext.protocolVersion;
if (pv == null || (!pv.useTLS13PlusSpec())) {
hasCloseReceipt = true;
}
I like the idea as it looks like a safe update in the current implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is what I was thinking.I will make the change and test it out. Thanks.
…Context.protocolVersion during close operation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Thank you!
/integrate |
Going to push as commit afcf8e4.
Your commit was automatically rebased without conflicts. |
In this PR, I added methods to the TransportContext class to synchronize access to the handshakeContext field. I also updated locations in the code that rely on the handshakeContext field to not be null to use the synchronized methods.
Thanks
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/13742/head:pull/13742
$ git checkout pull/13742
Update a local copy of the PR:
$ git checkout pull/13742
$ git pull https://git.openjdk.org/jdk.git pull/13742/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 13742
View PR using the GUI difftool:
$ git pr show -t 13742
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/13742.diff
Webrev
Link to Webrev Comment