bpo-42800: Add audit events for f_code and tb_frame (GH-24182)

Accessing the following attributes will now fire PEP 578 style audit hooks as (object.__getattr__, obj, name):
* PyTracebackObject: tb_frame
* PyFrameObject: f_code
* PyGenObject: gi_code, gi_frame
* PyCoroObject: cr_code, cr_frame
* PyAsyncGenObject: ag_code, ag_frame
This commit is contained in:
Steve Dower 2021-05-03 14:06:36 +01:00 committed by GitHub
parent 1536342c44
commit bb2f3ff7a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 22 additions and 9 deletions

View file

@ -7,7 +7,7 @@ Audit events table
This table contains all events raised by :func:`sys.audit` or This table contains all events raised by :func:`sys.audit` or
:c:func:`PySys_Audit` calls throughout the CPython runtime and the :c:func:`PySys_Audit` calls throughout the CPython runtime and the
standard library. These calls were added in 3.8.0 or later. standard library. These calls were added in 3.8.0 or later (see :pep:`578`).
See :func:`sys.addaudithook` and :c:func:`PySys_AddAuditHook` for See :func:`sys.addaudithook` and :c:func:`PySys_AddAuditHook` for
information on handling these events. information on handling these events.

View file

@ -5044,6 +5044,9 @@ environment. Code objects are returned by the built-in :func:`compile` function
and can be extracted from function objects through their :attr:`__code__` and can be extracted from function objects through their :attr:`__code__`
attribute. See also the :mod:`code` module. attribute. See also the :mod:`code` module.
Accessing ``__code__`` raises an :ref:`auditing event <auditing>`
``object.__getattr__`` with arguments ``obj`` and ``"__code__"``.
.. index:: .. index::
builtin: exec builtin: exec
builtin: eval builtin: eval

View file

@ -1005,6 +1005,9 @@ Internal types
:attr:`f_lasti` gives the precise instruction (this is an index into the :attr:`f_lasti` gives the precise instruction (this is an index into the
bytecode string of the code object). bytecode string of the code object).
Accessing ``f_code`` raises an :ref:`auditing event <auditing>`
``object.__getattr__`` with arguments ``obj`` and ``"f_code"``.
.. index:: .. index::
single: f_trace (frame attribute) single: f_trace (frame attribute)
single: f_trace_lines (frame attribute) single: f_trace_lines (frame attribute)
@ -1089,6 +1092,9 @@ Internal types
:keyword:`try` statement with no matching except clause or with a :keyword:`try` statement with no matching except clause or with a
finally clause. finally clause.
Accessing ``tb_frame`` raises an :ref:`auditing event <auditing>`
``object.__getattr__`` with arguments ``obj`` and ``"tb_frame"``.
.. index:: .. index::
single: tb_next (traceback attribute) single: tb_next (traceback attribute)

View file

@ -716,6 +716,7 @@ Kevan Heydon
Wouter van Heyst Wouter van Heyst
Kelsey Hightower Kelsey Hightower
Jason Hildebrand Jason Hildebrand
Ryan Hileman
Aaron Hill Aaron Hill
Joel Hillacre Joel Hillacre
Richie Hindle Richie Hindle

View file

@ -0,0 +1 @@
Audit hooks are now fired for frame.f_code, traceback.tb_frame, and generator code/frame attribute access.

View file

@ -13,7 +13,7 @@
static PyMemberDef frame_memberlist[] = { static PyMemberDef frame_memberlist[] = {
{"f_back", T_OBJECT, OFF(f_back), READONLY}, {"f_back", T_OBJECT, OFF(f_back), READONLY},
{"f_code", T_OBJECT, OFF(f_code), READONLY}, {"f_code", T_OBJECT, OFF(f_code), READONLY|READ_RESTRICTED},
{"f_builtins", T_OBJECT, OFF(f_builtins), READONLY}, {"f_builtins", T_OBJECT, OFF(f_builtins), READONLY},
{"f_globals", T_OBJECT, OFF(f_globals), READONLY}, {"f_globals", T_OBJECT, OFF(f_globals), READONLY},
{"f_lasti", T_INT, OFF(f_lasti), READONLY}, {"f_lasti", T_INT, OFF(f_lasti), READONLY},

View file

@ -711,9 +711,9 @@ static PyGetSetDef gen_getsetlist[] = {
}; };
static PyMemberDef gen_memberlist[] = { static PyMemberDef gen_memberlist[] = {
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY}, {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY|READ_RESTRICTED},
{"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY}, {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY},
{"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY}, {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY|READ_RESTRICTED},
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };
@ -931,9 +931,9 @@ static PyGetSetDef coro_getsetlist[] = {
}; };
static PyMemberDef coro_memberlist[] = { static PyMemberDef coro_memberlist[] = {
{"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY}, {"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY|READ_RESTRICTED},
{"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY}, {"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY},
{"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY}, {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY|READ_RESTRICTED},
{"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin), READONLY}, {"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin), READONLY},
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };
@ -1328,10 +1328,12 @@ static PyGetSetDef async_gen_getsetlist[] = {
}; };
static PyMemberDef async_gen_memberlist[] = { static PyMemberDef async_gen_memberlist[] = {
{"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame), READONLY}, {"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame),
READONLY|READ_RESTRICTED},
{"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async), {"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async),
READONLY}, READONLY},
{"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY}, {"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code),
READONLY|READ_RESTRICTED},
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };

View file

@ -147,7 +147,7 @@ static PyMethodDef tb_methods[] = {
}; };
static PyMemberDef tb_memberlist[] = { static PyMemberDef tb_memberlist[] = {
{"tb_frame", T_OBJECT, OFF(tb_frame), READONLY}, {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|READ_RESTRICTED},
{"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, {"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
{"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, {"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
{NULL} /* Sentinel */ {NULL} /* Sentinel */