mirror of https://github.com/python/cpython
bpo-42800: add audit hooks 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 Add an AUDIT_READ attribute flag aliased to READ_RESTRICTED. Update obsolete flag documentation.
This commit is contained in:
parent
088a15c49d
commit
9a2c2a9ec3
|
@ -287,18 +287,23 @@ combined using bitwise-OR.
|
|||
+===========================+==============================================+
|
||||
| :const:`READONLY` | Never writable. |
|
||||
+---------------------------+----------------------------------------------+
|
||||
| :const:`READ_RESTRICTED` | Not readable in restricted mode. |
|
||||
+---------------------------+----------------------------------------------+
|
||||
| :const:`WRITE_RESTRICTED` | Not writable in restricted mode. |
|
||||
+---------------------------+----------------------------------------------+
|
||||
| :const:`RESTRICTED` | Not readable or writable in restricted mode. |
|
||||
| :const:`AUDIT_READ` | Emit an ``object.__getattr__`` |
|
||||
| | :ref:`audit events <audit-events>` before |
|
||||
| | reading. |
|
||||
+---------------------------+----------------------------------------------+
|
||||
|
||||
.. versionchanged:: 3.10
|
||||
:const:`RESTRICTED`, :const:`READ_RESTRICTED` and :const:`WRITE_RESTRICTED`
|
||||
are deprecated. However, :const:`READ_RESTRICTED` is an alias for
|
||||
:const:`AUDIT_READ`, so fields that specify either :const:`RESTRICTED` or
|
||||
:const:`READ_RESTRICTED` will also raise an audit event.
|
||||
|
||||
.. index::
|
||||
single: READONLY
|
||||
single: READ_RESTRICTED
|
||||
single: WRITE_RESTRICTED
|
||||
single: RESTRICTED
|
||||
single: AUDIT_READ
|
||||
|
||||
An interesting advantage of using the :c:member:`~PyTypeObject.tp_members` table to build
|
||||
descriptors that are used at runtime is that any attribute defined this way can
|
||||
|
|
|
@ -7,7 +7,7 @@ Audit events table
|
|||
|
||||
This table contains all events raised by :func:`sys.audit` or
|
||||
: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
|
||||
information on handling these events.
|
||||
|
|
|
@ -5195,6 +5195,9 @@ environment. Code objects are returned by the built-in :func:`compile` function
|
|||
and can be extracted from function objects through their :attr:`__code__`
|
||||
attribute. See also the :mod:`code` module.
|
||||
|
||||
Accessing ``__code__`` raises an :ref:`auditing event <auditing>`
|
||||
``object.__getattr__`` with arguments ``obj`` and ``"__code__"``.
|
||||
|
||||
.. index::
|
||||
builtin: exec
|
||||
builtin: eval
|
||||
|
|
|
@ -1005,6 +1005,9 @@ Internal types
|
|||
:attr:`f_lasti` gives the precise instruction (this is an index into the
|
||||
bytecode string of the code object).
|
||||
|
||||
Accessing ``f_code`` raises an :ref:`auditing event <auditing>`
|
||||
``object.__getattr__`` with arguments ``obj`` and ``"f_code"``.
|
||||
|
||||
.. index::
|
||||
single: f_trace (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
|
||||
finally clause.
|
||||
|
||||
Accessing ``tb_frame`` raises an :ref:`auditing event <auditing>`
|
||||
``object.__getattr__`` with arguments ``obj`` and ``"tb_frame"``.
|
||||
|
||||
.. index::
|
||||
single: tb_next (traceback attribute)
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ typedef struct PyMemberDef {
|
|||
#define PY_WRITE_RESTRICTED 4
|
||||
#define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED)
|
||||
|
||||
#define AUDIT_READ READ_RESTRICTED
|
||||
|
||||
/* Current API, use this */
|
||||
PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, struct PyMemberDef *);
|
||||
|
|
|
@ -723,6 +723,7 @@ Kevan Heydon
|
|||
Wouter van Heyst
|
||||
Kelsey Hightower
|
||||
Jason Hildebrand
|
||||
Ryan Hileman
|
||||
Aaron Hill
|
||||
Joel Hillacre
|
||||
Richie Hindle
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Audit hooks are now fired for frame.f_code, traceback.tb_frame, and generator code/frame attribute access.
|
|
@ -164,7 +164,7 @@ member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
|
|||
if (descr_check((PyDescrObject *)descr, obj, &res))
|
||||
return res;
|
||||
|
||||
if (descr->d_member->flags & READ_RESTRICTED) {
|
||||
if (descr->d_member->flags & AUDIT_READ) {
|
||||
if (PySys_Audit("object.__getattr__", "Os",
|
||||
obj ? obj : Py_None, descr->d_member->name) < 0) {
|
||||
return NULL;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
static PyMemberDef frame_memberlist[] = {
|
||||
{"f_back", T_OBJECT, OFF(f_back), READONLY},
|
||||
{"f_code", T_OBJECT, OFF(f_code), READONLY},
|
||||
{"f_code", T_OBJECT, OFF(f_code), READONLY|AUDIT_READ},
|
||||
{"f_builtins", T_OBJECT, OFF(f_builtins), READONLY},
|
||||
{"f_globals", T_OBJECT, OFF(f_globals), READONLY},
|
||||
{"f_trace_lines", T_BOOL, OFF(f_trace_lines), 0},
|
||||
|
|
|
@ -741,8 +741,8 @@ static PyGetSetDef gen_getsetlist[] = {
|
|||
};
|
||||
|
||||
static PyMemberDef gen_memberlist[] = {
|
||||
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
|
||||
{"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
|
||||
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY|AUDIT_READ},
|
||||
{"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY|AUDIT_READ},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
@ -978,8 +978,8 @@ static PyGetSetDef coro_getsetlist[] = {
|
|||
};
|
||||
|
||||
static PyMemberDef coro_memberlist[] = {
|
||||
{"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY},
|
||||
{"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY},
|
||||
{"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY|AUDIT_READ},
|
||||
{"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY|AUDIT_READ},
|
||||
{"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin), READONLY},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
@ -1360,10 +1360,10 @@ static PyGetSetDef async_gen_getsetlist[] = {
|
|||
};
|
||||
|
||||
static PyMemberDef async_gen_memberlist[] = {
|
||||
{"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame), READONLY},
|
||||
{"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame), READONLY|AUDIT_READ},
|
||||
{"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async),
|
||||
READONLY},
|
||||
{"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY},
|
||||
{"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY|AUDIT_READ},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ static PyMethodDef tb_methods[] = {
|
|||
};
|
||||
|
||||
static PyMemberDef tb_memberlist[] = {
|
||||
{"tb_frame", T_OBJECT, OFF(tb_frame), READONLY},
|
||||
{"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|AUDIT_READ},
|
||||
{"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
|
||||
{"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
|
||||
{NULL} /* Sentinel */
|
||||
|
|
Loading…
Reference in New Issue