Skip to content
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

bpo-30594: Fix spurious DECREF in newPySSLSocket #1992

Merged
merged 1 commit into from
Jun 8, 2017

Conversation

njsmith
Copy link
Contributor

@njsmith njsmith commented Jun 8, 2017

In newPySSLSocket, it sets up the new 'self' object, which among other
things owns a reference to the parent SSLContext in 'self->ctx'.

It then tries to idna-decode the given server_hostname, and if this
fails it does Py_DECREF(self) and returns.

The Py_DECREF(self) causes the PySSLSocket destructor to run, which
calls Py_DECREF(self->ctx), which releases the reference to the parent
SSLContext object.

However... as currently written, we don't actually take the
reference to the parent SSLContext until after the idna-decoding
step. I.e., this does a Py_DECREF on an object that was never
Py_INCREFed. Eventually we get a segfault.

In newPySSLSocket, it sets up the new 'self' object, which among other
things owns a reference to the parent SSLContext in 'self->ctx'.

It then tries to idna-decode the given server_hostname, and if this
fails it does Py_DECREF(self) and returns.

The Py_DECREF(self) causes the PySSLSocket destructor to run, which
calls Py_DECREF(self->ctx), which releases the reference to the parent
SSLContext object.

However... as currently written, we don't actually *take* the
reference to the parent SSLContext until *after* the idna-decoding
step. I.e., this does a Py_DECREF on an object that was never
Py_INCREFed. Eventually we get a segfault.
@mention-bot
Copy link

@njsmith, thanks for your PR! By analyzing the history of the files in this pull request, we identified @vadmium, @tiran and @serhiy-storchaka to be potential reviewers.

@njsmith njsmith changed the title Fix spurious DECREF in newPySSLSocket bpo-30594: Fix spurious DECREF in newPySSLSocket Jun 8, 2017
@njsmith
Copy link
Contributor Author

njsmith commented Jun 8, 2017

Of course, the real solution would be to not attempt to IDNA-decode the passed in name, why are we even doing this, everything inside this module should be using A-labels. But that's another story...

@serhiy-storchaka serhiy-storchaka added needs backport to 2.7 type-bug An unexpected behavior, bug, or error labels Jun 8, 2017
@serhiy-storchaka serhiy-storchaka merged commit 65ece7c into python:master Jun 8, 2017
@vstinner
Copy link
Member

vstinner commented Jun 8, 2017

Would it be possible to write an unit test?

@njsmith njsmith deleted the ref-sink-in-newPySSLSocket branch June 8, 2017 08:38
@njsmith
Copy link
Contributor Author

njsmith commented Jun 8, 2017

@Haypo: The truth is I couldn't figure out where to put such a test (there are currently literally zero tests for anything related to IDN and ssl), and wasn't sure what the preferred style was for refcount issues like this anyway. (Call it 100 times and then move on, and if the tests segfault then that's a failure?)

@njsmith
Copy link
Contributor Author

njsmith commented Jun 8, 2017

Sorry, hit post too soon and lost my last sentence :-). What I meant to say is, if you can tell me the answer to those I can write a test :-)

njsmith added a commit to njsmith/cpython that referenced this pull request Jun 8, 2017
If pass a server_hostname= that fails IDNA decoding to SSLContext.wrap_socket or SSLContext.wrap_bio, then the SSLContext object had a spurious Py_DECREF called on it, eventually leading to segfaults.
(cherry picked from commit 65ece7c)
njsmith added a commit to njsmith/cpython that referenced this pull request Jun 8, 2017
If pass a server_hostname= that fails IDNA decoding to SSLContext.wrap_socket or SSLContext.wrap_bio, then the SSLContext object had a spurious Py_DECREF called on it, eventually leading to segfaults.
(cherry picked from commit 65ece7c)
@serhiy-storchaka
Copy link
Member

This is trivial fix, and it is very unlikely the bug will be reintroduced. I think a test and a Misc/NEWS entry are not required for this issue.

@vstinner
Copy link
Member

vstinner commented Jun 8, 2017

@njsmith: Try to write an unit test in test_ssl on SSLContext with an invalid IDNA.

@serhiy-storchaka: I agree that the unit test is not required, but it would be nice to test the error path as well ;-)

serhiy-storchaka pushed a commit that referenced this pull request Jun 8, 2017
If pass a server_hostname= that fails IDNA decoding to SSLContext.wrap_socket or SSLContext.wrap_bio, then the SSLContext object had a spurious Py_DECREF called on it, eventually leading to segfaults.
(cherry picked from commit 65ece7c)
serhiy-storchaka pushed a commit that referenced this pull request Jun 8, 2017
If pass a server_hostname= that fails IDNA decoding to SSLContext.wrap_socket or SSLContext.wrap_bio, then the SSLContext object had a spurious Py_DECREF called on it, eventually leading to segfaults.
(cherry picked from commit 65ece7c)
njsmith added a commit to njsmith/cpython that referenced this pull request Jun 9, 2017
vstinner pushed a commit that referenced this pull request Jun 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants