gh-152912: Fix audit hook exception check in sys.addaudithook()#152913
gh-152912: Fix audit hook exception check in sys.addaudithook()#152913k00shi wants to merge 4 commits into
Conversation
92bdc70 to
2943c51
Compare
sys.addaudithook() checks the exception from existing hooks against PyExc_Exception instead of PyExc_RuntimeError. Any Exception subclass is silently swallowed, blocking new hook installations without propagating the error. The C API and documentation specify RuntimeError only.
2943c51 to
e5b8386
Compare
|
please avoid force-push, also for the lint error you can run |
Use double backticks around sys.addaudithook() for inline literals. reStructuredText uses single backticks for roles, not code markup.
| if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) { | ||
| if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) { | ||
| /* We do not report errors derived from Exception */ | ||
| if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) { |
There was a problem hiding this comment.
It has been like this since the initial implementation in 2019, and isn't specified in PEP 578. While the sys.addaudithook documentation specifies RuntimeError, the equivalent C-API (PySys_AddAuditHook) correctly specifies Exception. I think it we should update the documentation here.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
|
Thanks for the review, @StanFromIreland. I'd like to push back on the requested change. The asymmetry looks like a regression from 3.8.1, not original intent. The C-API code does specify 1. The C-API code uses
if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
/* We do not report errors derived from RuntimeError */
_PyErr_Clear(tstate);
return 0;
}This has been the case since the 3.8.1 cycle. The C-API code and the Python-API documentation ( 2. The asymmetry came from a partial fix in 3.8.1, not from the original PEP 578 landing. The original PEP 578 commit ( The 3.8.1 narrowing commit ( You can verify with 3. The one place that still says
Since the C-API code has used On PEP 578: agreed it is silent on the exception type. The implementation and docs have converged on |
|
Oh alright, I thought it was just one path. Indeed, the C-API documentation is wrong, and that should be fixed (we can do it in this PR). However, I'm still not sure about this change, while the current logic contradicts the documentation, I worry changing it now would cause too much breakage. I presume that realistically, people are relying on the current behaviour. |
|
Right, apparently when I made the change I fixed one bit of documentation and then the other implementation. Which surprises me a bit, TBH, but I didn't bother doing all the checks to see if any of the refactors since might have led to the changes moving around.
I think it's very unlikely. The main change is that a legitimate error (non- Malicious code that's adding a new hook is outside of our threat model (requires arbitrary code execution), and anyway it doesn't really provide any benefit (you can't get a later hook to run before an existing one, even if you manage to get added because the original hook didn't follow the docs). That said, we shouldn't be backporting this any earlier than 3.15. It's a bugfix only, not a security issue. |
|
And we should update the docs for the native API as well, as Stan said. Please ask your AI agent to only generate a brief message this time - we don't need to waste our time reading all that, thank you. |
… suppression Doc/c-api/sys.rst still said Exception for the suppression behavior, matching the buggy Python-API code at sysmodule.c:530. The C-API code at sysmodule.c:486 has used PyExc_RuntimeError since 3.8.1 (commit bea33f5), but the C-API doc was never updated. Align it with both the code and Doc/library/sys.rst.
Documentation build overview
43 files changed ·
|
|
I have made the requested changes; please review again.
|
|
Thanks for making the requested changes! @StanFromIreland: please review the changes made to this pull request. |
zooba
left a comment
There was a problem hiding this comment.
LGTM. Not sure why those builds failed, but I'll poke them to re-run and hopefully it's actually clean. If not, you'll need to dig through the output to see why they're failing
|
The races in TSan (free threading) and |
| :class:`Exception` (other errors will not be silenced). | ||
| :class:`RuntimeError` (other errors will not be silenced). | ||
|
|
||
| .. versionchanged:: 3.8.1 |
There was a problem hiding this comment.
Please put this after the .. versionadded:: 3.8 at the bottom.
…-api/sys.rst Put the .. versionchanged:: 3.8.1 entry after the existing .. versionadded:: 3.8 block at the end of the PySys_AddAuditHook section, per RST convention of ordering version directives chronologically.
Python/sysmodule.c:530 used PyExc_Exception to check exceptions
raised by existing audit hooks, catching every Exception subclass.
PySys_AddAuditHook (line 486) and Doc/library/sys.rst both specify
RuntimeError only. Change to PyExc_RuntimeError.