summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2021-03-10 08:50:16 (GMT)
committerGitHub <noreply@github.com>2021-03-10 08:50:16 (GMT)
commita6d0182879d0bf275c4feb38b57f73236ab9c06c (patch)
tree96ea6d412c90761f0c526e4c8e230ea3926baaf2
parente89380765df8f0f02c90ad417e164d1597bd0b05 (diff)
downloadcpython-a6d0182879d0bf275c4feb38b57f73236ab9c06c.zip
cpython-a6d0182879d0bf275c4feb38b57f73236ab9c06c.tar.gz
cpython-a6d0182879d0bf275c4feb38b57f73236ab9c06c.tar.bz2
[3.8] bpo-43439: Add audit hooks for gc functions (GH-24794). (GH-24810)
(cherry picked from commit b4f9089d4aa787c5b74134c98e5f0f11d9e63095) Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
-rw-r--r--Doc/library/gc.rst5
-rw-r--r--Lib/test/audit-tests.py18
-rw-r--r--Lib/test/test_audit.py13
-rw-r--r--Misc/NEWS.d/next/Security/2021-03-08-23-06-07.bpo-43439.5U3lXm.rst2
-rw-r--r--Modules/gcmodule.c11
5 files changed, 49 insertions, 0 deletions
diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst
index 073391d..dcbfe7f 100644
--- a/Doc/library/gc.rst
+++ b/Doc/library/gc.rst
@@ -72,6 +72,8 @@ The :mod:`gc` module provides the following functions:
.. versionchanged:: 3.8
New *generation* parameter.
+ .. audit-event:: gc.get_objects generation gc.get_objects
+
.. function:: get_stats()
Return a list of three per-generation dictionaries containing collection
@@ -141,6 +143,8 @@ The :mod:`gc` module provides the following functions:
invalid state. Avoid using :func:`get_referrers` for any purpose other than
debugging.
+ .. audit-event:: gc.get_referrers objs gc.get_referrers
+
.. function:: get_referents(*objs)
@@ -152,6 +156,7 @@ The :mod:`gc` module provides the following functions:
be involved in a cycle. So, for example, if an integer is directly reachable
from an argument, that integer object may or may not appear in the result list.
+ .. audit-event:: gc.get_referents objs gc.get_referents
.. function:: is_tracked(obj)
diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py
index ee6fc93..8e66594 100644
--- a/Lib/test/audit-tests.py
+++ b/Lib/test/audit-tests.py
@@ -323,6 +323,24 @@ def test_socket():
sock.close()
+def test_gc():
+ import gc
+
+ def hook(event, args):
+ if event.startswith("gc."):
+ print(event, *args)
+
+ sys.addaudithook(hook)
+
+ gc.get_objects(generation=1)
+
+ x = object()
+ y = [x]
+
+ gc.get_referrers(x)
+ gc.get_referents(y)
+
+
if __name__ == "__main__":
from test.support import suppress_msvcrt_asserts
diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py
index f79edbc..a9ac6fe 100644
--- a/Lib/test/test_audit.py
+++ b/Lib/test/test_audit.py
@@ -115,5 +115,18 @@ class AuditTest(unittest.TestCase):
self.assertEqual(events[2][0], "socket.bind")
self.assertTrue(events[2][2].endswith("('127.0.0.1', 8080)"))
+ def test_gc(self):
+ returncode, events, stderr = self.run_python("test_gc")
+ if returncode:
+ self.fail(stderr)
+
+ if support.verbose:
+ print(*events, sep='\n')
+ self.assertEqual(
+ [event[0] for event in events],
+ ["gc.get_objects", "gc.get_referrers", "gc.get_referents"]
+ )
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/NEWS.d/next/Security/2021-03-08-23-06-07.bpo-43439.5U3lXm.rst b/Misc/NEWS.d/next/Security/2021-03-08-23-06-07.bpo-43439.5U3lXm.rst
new file mode 100644
index 0000000..5186503
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2021-03-08-23-06-07.bpo-43439.5U3lXm.rst
@@ -0,0 +1,2 @@
+Add audit hooks for :func:`gc.get_objects`, :func:`gc.get_referrers` and
+:func:`gc.get_referents`. Patch by Pablo Galindo.
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 5a6a81d..7a37a16 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1480,6 +1480,10 @@ static PyObject *
gc_get_referrers(PyObject *self, PyObject *args)
{
int i;
+ if (PySys_Audit("gc.get_referrers", "O", args) < 0) {
+ return NULL;
+ }
+
PyObject *result = PyList_New(0);
if (!result) return NULL;
@@ -1508,6 +1512,9 @@ static PyObject *
gc_get_referents(PyObject *self, PyObject *args)
{
Py_ssize_t i;
+ if (PySys_Audit("gc.get_referents", "O", args) < 0) {
+ return NULL;
+ }
PyObject *result = PyList_New(0);
if (result == NULL)
@@ -1549,6 +1556,10 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation)
PyObject* result;
struct _gc_runtime_state *state = &_PyRuntime.gc;
+ if (PySys_Audit("gc.get_objects", "n", generation) < 0) {
+ return NULL;
+ }
+
result = PyList_New(0);
if (result == NULL) {
return NULL;