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-43406: Fix possible race condition where PyErr_CheckSignals tries to execute a non-Python signal handler #24756

Merged
merged 3 commits into from Mar 5, 2021

Conversation

pitrou
Copy link
Member

@pitrou pitrou commented Mar 4, 2021

…ries to execute a non-Python signal handler.
* raising cryptic exceptions asynchronously
* such as "TypeError: 'int' object is not callable".
*/
continue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably require some consensus, but I would personally raise, as the situation is tricky enough that I think it should not pass silently.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vstinner What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One problem is that re-raising will break the assumption that _thread.interrupt_main only simulates SIGINT.

Copy link
Member

@pablogsal pablogsal Mar 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One problem is that re-raising will break the assumption that _thread.interrupt_main only simulates SIGINT.

That's an excellent point actually. Maybe we should set an unraisable exception (PyErr_WriteUnraisable)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would not be much better than the asynchronous TypeError, would it?

Copy link
Member

@pablogsal pablogsal Mar 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not set the error indicator IIRC and can be handled separately if needed by a hook. By default is like printing to stderr. The advantage would be that keeps the assumption that _thread.interrupt_main only simulates SIGINT but doesn't pass silently.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sounds good then!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to take a look at the updated patch @pablogsal .

Copy link
Member

@pablogsal pablogsal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo a couple of comments

pitrou and others added 2 commits March 4, 2021 23:07
Copy link
Member

@pablogsal pablogsal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

This is great work. Thanks a lot for working on this!

I think we can refine the error message (so we don't say "race condition" as users won't be able to act on that) but I propose to merge this as is and I will propose another PR with an improvement in the error message.

@pitrou pitrou merged commit 68245b7 into python:master Mar 5, 2021
@miss-islington
Copy link
Contributor

Thanks @pitrou for the PR 🌮🎉.. I'm working now to backport this PR to: 3.8, 3.9.
🐍🍒⛏🤖

@pitrou
Copy link
Member Author

pitrou commented Mar 5, 2021

Thanks for the quick review @pablogsal !

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Mar 5, 2021
…ries to execute a non-Python signal handler (pythonGH-24756)

We can receive signals (at the C level, in `trip_signal()` in signalmodule.c) while `signal.signal` is being called to modify the corresponding handler.  Later when `PyErr_CheckSignals()` is called to handle the given signal, the handler may be a non-callable object and would raise a cryptic asynchronous exception.
(cherry picked from commit 68245b7)

Co-authored-by: Antoine Pitrou <antoine@python.org>
@bedevere-bot
Copy link

GH-24761 is a backport of this pull request to the 3.9 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.9 only security fixes label Mar 5, 2021
@miss-islington
Copy link
Contributor

Sorry, @pitrou, I could not cleanly backport this to 3.8 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 68245b7a1030287294c65c298975ab9026543fd2 3.8

pitrou added a commit to pitrou/cpython that referenced this pull request Mar 5, 2021
…ls`` tries to execute a non-Python signal handler (pythonGH-24756)

We can receive signals (at the C level, in `trip_signal()` in signalmodule.c) while `signal.signal` is being called to modify the corresponding handler.  Later when `PyErr_CheckSignals()` is called to handle the given signal, the handler may be a non-callable object and would raise a cryptic asynchronous exception..
(cherry picked from commit 68245b7)

Co-authored-by: Antoine Pitrou <antoine@python.org>
@bedevere-bot
Copy link

GH-24762 is a backport of this pull request to the 3.8 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.8 only security fixes label Mar 5, 2021
@pitrou pitrou deleted the bpo-43406-signal-race-condition branch March 5, 2021 09:45
miss-islington added a commit that referenced this pull request Mar 6, 2021
…ls`` tries to execute a non-Python signal handler (GH-24756) (GH-24761)

We can receive signals (at the C level, in `trip_signal()` in signalmodule.c) while `signal.signal` is being called to modify the corresponding handler.  Later when `PyErr_CheckSignals()` is called to handle the given signal, the handler may be a non-callable object and would raise a cryptic asynchronous exception.
(cherry picked from commit 68245b7)


Co-authored-by: Antoine Pitrou <antoine@python.org>
miss-islington pushed a commit that referenced this pull request Mar 6, 2021
…ls`` tries to execute a non-Python signal handler (GH-24756) (GH-24762)

We can receive signals (at the C level, in `trip_signal()` in signalmodule.c) while `signal.signal` is being called to modify the corresponding handler.  Later when `PyErr_CheckSignals()` is called to handle the given signal, the handler may be a non-callable object and would raise a cryptic asynchronous exception..
(cherry picked from commit 68245b7)

Co-authored-by: Antoine Pitrou <antoine@python.org>
kreathon pushed a commit to kreathon/cpython that referenced this pull request May 2, 2021
…ries to execute a non-Python signal handler (pythonGH-24756)

We can receive signals (at the C level, in `trip_signal()` in signalmodule.c) while `signal.signal` is being called to modify the corresponding handler.  Later when `PyErr_CheckSignals()` is called to handle the given signal, the handler may be a non-callable object and would raise a cryptic asynchronous exception.
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.

None yet

6 participants