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-25750: fix refcounts in type_getattro() #6118

Merged
merged 1 commit into from Sep 7, 2018

Conversation

Projects
None yet
6 participants
@jdemeyer
Contributor

jdemeyer commented Mar 14, 2018

When calling tp_descr_get(attr, obj, type), make sure that we own a reference to attr. In the existing code, we only have a borrowed reference.

This bug goes back to at least Python 2.7, so ideally it should be backported to all previous versions.

https://bugs.python.org/issue25750

Downstream: https://trac.sagemath.org/ticket/19633

@the-knights-who-say-ni

This comment has been minimized.

Show comment
Hide comment
@the-knights-who-say-ni

the-knights-who-say-ni Mar 14, 2018

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA).

Unfortunately we couldn't find an account corresponding to your GitHub username on bugs.python.org (b.p.o) to verify you have signed the CLA (this might be simply due to a missing "GitHub Name" entry in your b.p.o account settings). This is necessary for legal reasons before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

Thanks again to your contribution and we look forward to looking at it!

the-knights-who-say-ni commented Mar 14, 2018

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA).

Unfortunately we couldn't find an account corresponding to your GitHub username on bugs.python.org (b.p.o) to verify you have signed the CLA (this might be simply due to a missing "GitHub Name" entry in your b.p.o account settings). This is necessary for legal reasons before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

Thanks again to your contribution and we look forward to looking at it!

@berkerpeksag

In https://bugs.python.org/issue25750#msg255566 you said:

My patch does fix the crash in Lib/test/crashers/borrowed_ref_2.py on Python 2.7.10.

Is it possible to convert https://github.com/python/cpython/blob/2.7/Lib/test/crashers/borrowed_ref_2.py to a simple test case?

Thanks!

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Mar 24, 2018

Contributor

Is it possible to convert https://github.com/python/cpython/blob/2.7/Lib/test/crashers/borrowed_ref_2.py to a simple test case?

I can try, but I never managed to get the vanilla Python testsuite to pass on my system, so it's hard to test it myself.

Contributor

jdemeyer commented Mar 24, 2018

Is it possible to convert https://github.com/python/cpython/blob/2.7/Lib/test/crashers/borrowed_ref_2.py to a simple test case?

I can try, but I never managed to get the vanilla Python testsuite to pass on my system, so it's hard to test it myself.

@berkerpeksag

This comment has been minimized.

Show comment
Hide comment
@berkerpeksag

berkerpeksag Mar 24, 2018

Member

We can use Travis to test it :)

By the way, the test suite should pass on most systems. I suggest reporting test failures on your system on bugs.p.o.

Member

berkerpeksag commented Mar 24, 2018

We can use Travis to test it :)

By the way, the test suite should pass on most systems. I suggest reporting test failures on your system on bugs.p.o.

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Apr 2, 2018

Contributor

Is it possible to convert https://github.com/python/cpython/blob/2.7/Lib/test/crashers/borrowed_ref_2.py to a simple test case?

That example seems to crash only on Python 2, not Python 3. In fact, I do not know how to reproduce the crash on Python 3.

Contributor

jdemeyer commented Apr 2, 2018

Is it possible to convert https://github.com/python/cpython/blob/2.7/Lib/test/crashers/borrowed_ref_2.py to a simple test case?

That example seems to crash only on Python 2, not Python 3. In fact, I do not know how to reproduce the crash on Python 3.

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Apr 20, 2018

Contributor

I added a testcase. This was a lot harder to reproduce on Python 3.8 than Python 2.7, probably due to the changes regarding calling functions.

Contributor

jdemeyer commented Apr 20, 2018

I added a testcase. This was a lot harder to reproduce on Python 3.8 than Python 2.7, probably due to the changes regarding calling functions.

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Apr 20, 2018

Contributor

So, in some sense, the backport to Python 2.7 is more important than the fix to Python 3.8. The underlying issue is the same, it's just harder to accidentally hit it because of unrelated changes.

Contributor

jdemeyer commented Apr 20, 2018

So, in some sense, the backport to Python 2.7 is more important than the fix to Python 3.8. The underlying issue is the same, it's just harder to accidentally hit it because of unrelated changes.

@timokau timokau referenced this pull request Apr 26, 2018

Closed

python-2.7.14: Fix #27177 and #25750 #39555

0 of 8 tasks complete
@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Jul 5, 2018

Contributor

@berkerpeksag Can you please finish the review of this PR?

Contributor

jdemeyer commented Jul 5, 2018

@berkerpeksag Can you please finish the review of this PR?

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Jul 5, 2018

Contributor

If you insist, here is a pure Python 3 reproducer:

import pickle

class Descr:
    __get__ = pickle.dump
    __set__ = None

class M(type):
    def __int__(self):
        self.write = None
        return 0

class X(type, metaclass=M):
    write = Descr()

class Y(metaclass=X):
    pass

Y.write

However, this code is so artificial that it would be really strange to add it to the testsuite. I think that the current C code does a much better job of showing the error.

Contributor

jdemeyer commented Jul 5, 2018

If you insist, here is a pure Python 3 reproducer:

import pickle

class Descr:
    __get__ = pickle.dump
    __set__ = None

class M(type):
    def __int__(self):
        self.write = None
        return 0

class X(type, metaclass=M):
    write = Descr()

class Y(metaclass=X):
    pass

Y.write

However, this code is so artificial that it would be really strange to add it to the testsuite. I think that the current C code does a much better job of showing the error.

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Jul 5, 2018

Contributor

I made the requested changes on the branch.

Contributor

jdemeyer commented Jul 5, 2018

I made the requested changes on the branch.

@waynr waynr referenced this pull request Jul 6, 2018

Closed

Vendor python type_getattro patch. #43112

1 of 9 tasks complete
@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Jul 29, 2018

Contributor

if it's not possible to crash the interpreter in a pure Python 3 code, I wonder whether we should only fix this in Python 2.7.

First of all, it is possible to crash the interpreter using pickle.dump as I demonstrated above.

Second, CPython is more than just the Python interpreter: even if a bug is only relevant for the Python/C API, it's still a bug that should be fixed.

So we can get this merged finally? It's an obvious bug fix, and I see nothing controversial about it.

Contributor

jdemeyer commented Jul 29, 2018

if it's not possible to crash the interpreter in a pure Python 3 code, I wonder whether we should only fix this in Python 2.7.

First of all, it is possible to crash the interpreter using pickle.dump as I demonstrated above.

Second, CPython is more than just the Python interpreter: even if a bug is only relevant for the Python/C API, it's still a bug that should be fixed.

So we can get this merged finally? It's an obvious bug fix, and I see nothing controversial about it.

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Sep 4, 2018

Contributor

@vstinner You obviously care about abusing borrowed references...

Contributor

jdemeyer commented Sep 4, 2018

@vstinner You obviously care about abusing borrowed references...

@vstinner

The typeobject.c fix LGTM, but I'm not sure about the test. The test seems quite complicated and not reliable :-( Do we really have to add an unit test for that?

@serhiy-storchaka: Would you be ok to omit the test on such fix?

I dislike having a test doing "cls.descr = None" and "Create this large list to corrupt some unused memory". IMHO the test is too close to the exact C implementation.

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Sep 5, 2018

Contributor

I added a testcase by request of @berkerpeksag

Contributor

jdemeyer commented Sep 5, 2018

I added a testcase by request of @berkerpeksag

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Sep 5, 2018

Contributor

I dislike having a test doing "cls.descr = None"

Why? That is exactly the main point of the test (unless you prefer del cls.descr?). Only the "Create this large list to corrupt some unused memory" part is hackish indeed.

Contributor

jdemeyer commented Sep 5, 2018

I dislike having a test doing "cls.descr = None"

Why? That is exactly the main point of the test (unless you prefer del cls.descr?). Only the "Create this large list to corrupt some unused memory" part is hackish indeed.

@vstinner

This comment has been minimized.

Show comment
Hide comment
@vstinner

vstinner Sep 5, 2018

Member

I dislike having a test doing "cls.descr = None"

Why? That is exactly the main point of the test (unless you prefer del cls.descr?).

If it becomes part of the test suite, it means that we have to support this weird use case. I'm not sure that it should be part of the "language specification".

Member

vstinner commented Sep 5, 2018

I dislike having a test doing "cls.descr = None"

Why? That is exactly the main point of the test (unless you prefer del cls.descr?).

If it becomes part of the test suite, it means that we have to support this weird use case. I'm not sure that it should be part of the "language specification".

@berkerpeksag

This comment has been minimized.

Show comment
Hide comment
@berkerpeksag

berkerpeksag Sep 5, 2018

Member

The whole point of this issue and PR is that someone is already depending on this behavior. We already have tests for more rare cases (e.g. https://bugs.python.org/issue31781) than this one.

We could wrap the test with the @cpython_only decorator if you think that the test is too close to the implementation.

Member

berkerpeksag commented Sep 5, 2018

The whole point of this issue and PR is that someone is already depending on this behavior. We already have tests for more rare cases (e.g. https://bugs.python.org/issue31781) than this one.

We could wrap the test with the @cpython_only decorator if you think that the test is too close to the implementation.

@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Sep 6, 2018

Contributor

I'm not sure that it should be part of the "language specification".

So you think that doing cls.descr = None is not part of the language specification? I would guess that adding/changing attributes of classes like that is a reasonable standard feature.

Contributor

jdemeyer commented Sep 6, 2018

I'm not sure that it should be part of the "language specification".

So you think that doing cls.descr = None is not part of the language specification? I would guess that adding/changing attributes of classes like that is a reasonable standard feature.

@vstinner

This comment has been minimized.

Show comment
Hide comment
@vstinner

vstinner Sep 6, 2018

Member

I have no strong opinion on this change. I let someone else take a decision.

Member

vstinner commented Sep 6, 2018

I have no strong opinion on this change. I let someone else take a decision.

bpo-25750: fix refcounts in type_getattro()
When calling tp_descr_get(self, obj, type),
make sure that we own a reference to "self"
@jdemeyer

This comment has been minimized.

Show comment
Hide comment
@jdemeyer

jdemeyer Sep 6, 2018

Contributor

Since the testcase is apparently controversial, I decided to separate it as a new pull request: #9084

I really hope that this issue can now finally be fixed.

Contributor

jdemeyer commented Sep 6, 2018

Since the testcase is apparently controversial, I decided to separate it as a new pull request: #9084

I really hope that this issue can now finally be fixed.

@vstinner vstinner merged commit 8f73548 into python:master Sep 7, 2018

9 checks passed

Linux-PR #Linux-PR_20180906.31 succeeded
Details
Linux-PR-Coverage #Linux-PR-Coverage_20180906.31 succeeded
Details
Windows-PR #Windows-PR_20180906.31 succeeded
Details
bedevere/issue-number Issue number 25750 found
Details
bedevere/news News entry found in Misc/NEWS.d
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
docs #docs_20180906.31 succeeded
Details
macOS-PR #macOS-PR_20180906.31 succeeded
Details
@miss-islington

This comment has been minimized.

Show comment
Hide comment
@miss-islington

miss-islington Sep 7, 2018

Thanks @jdemeyer for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6, 3.7.
🐍🍒🤖

miss-islington commented Sep 7, 2018

Thanks @jdemeyer for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6, 3.7.
🐍🍒🤖

miss-islington added a commit to miss-islington/cpython that referenced this pull request Sep 7, 2018

bpo-25750: fix refcounts in type_getattro() (GH-6118)
When calling tp_descr_get(self, obj, type), make sure that
we own a strong reference to "self".
(cherry picked from commit 8f73548)

Co-authored-by: jdemeyer <jdemeyer@cage.ugent.be>
@bedevere-bot

This comment has been minimized.

Show comment
Hide comment
@bedevere-bot

bedevere-bot Sep 7, 2018

GH-9087 is a backport of this pull request to the 3.7 branch.

bedevere-bot commented Sep 7, 2018

GH-9087 is a backport of this pull request to the 3.7 branch.

@bedevere-bot

This comment has been minimized.

Show comment
Hide comment
@bedevere-bot

bedevere-bot Sep 7, 2018

GH-9088 is a backport of this pull request to the 3.6 branch.

bedevere-bot commented Sep 7, 2018

GH-9088 is a backport of this pull request to the 3.6 branch.

miss-islington added a commit to miss-islington/cpython that referenced this pull request Sep 7, 2018

bpo-25750: fix refcounts in type_getattro() (GH-6118)
When calling tp_descr_get(self, obj, type), make sure that
we own a strong reference to "self".
(cherry picked from commit 8f73548)

Co-authored-by: jdemeyer <jdemeyer@cage.ugent.be>
@bedevere-bot

This comment has been minimized.

Show comment
Hide comment
@bedevere-bot

bedevere-bot Sep 7, 2018

GH-9089 is a backport of this pull request to the 2.7 branch.

bedevere-bot commented Sep 7, 2018

GH-9089 is a backport of this pull request to the 2.7 branch.

miss-islington added a commit to miss-islington/cpython that referenced this pull request Sep 7, 2018

bpo-25750: fix refcounts in type_getattro() (GH-6118)
When calling tp_descr_get(self, obj, type), make sure that
we own a strong reference to "self".
(cherry picked from commit 8f73548)

Co-authored-by: jdemeyer <jdemeyer@cage.ugent.be>
@vstinner

This comment has been minimized.

Show comment
Hide comment
@vstinner

vstinner Sep 7, 2018

Member

Since the testcase is apparently controversial, I decided to separate it as a new pull request: #9084

I'm sorry for being picky :-(

I really hope that this issue can now finally be fixed.

Sure, I just merged it. miss-inlington bot created the 3 backports and I already approved them, they will be merged once the CI tests pass.

Member

vstinner commented Sep 7, 2018

Since the testcase is apparently controversial, I decided to separate it as a new pull request: #9084

I'm sorry for being picky :-(

I really hope that this issue can now finally be fixed.

Sure, I just merged it. miss-inlington bot created the 3 backports and I already approved them, they will be merged once the CI tests pass.

miss-islington added a commit that referenced this pull request Sep 7, 2018

bpo-25750: fix refcounts in type_getattro() (GH-6118)
When calling tp_descr_get(self, obj, type), make sure that
we own a strong reference to "self".
(cherry picked from commit 8f73548)

Co-authored-by: jdemeyer <jdemeyer@cage.ugent.be>

vstinner added a commit to vstinner/cpython that referenced this pull request Sep 7, 2018

bpo-25750: fix refcounts in type_getattro() (GH-6118)
When calling tp_descr_get(self, obj, type), make sure that
we own a strong reference to "self".

(cherry picked from commit 8f73548)

vstinner added a commit that referenced this pull request Sep 7, 2018

bpo-25750: fix refcounts in type_getattro() (GH-6118) (GH-9088)
When calling tp_descr_get(self, obj, type), make sure that
we own a strong reference to "self".
(cherry picked from commit 8f73548)

Co-authored-by: jdemeyer <jdemeyer@cage.ugent.be>

vstinner added a commit that referenced this pull request Sep 7, 2018

bpo-25750: fix refcounts in type_getattro() (GH-6118) (GH-9091)
When calling tp_descr_get(self, obj, type), make sure that
we own a strong reference to "self".

(cherry picked from commit 8f73548)

lisroach pushed a commit to lisroach/cpython that referenced this pull request Sep 12, 2018

bpo-25750: fix refcounts in type_getattro() (GH-6118)
When calling tp_descr_get(self, obj, type), make sure that
we own a strong reference to "self".

dacut added a commit to dacut/cpython that referenced this pull request Sep 16, 2018

bpo-25750: fix refcounts in type_getattro() (GH-6118)
When calling tp_descr_get(self, obj, type), make sure that
we own a strong reference to "self".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment