]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-43439: Add audit hooks for gc functions (GH-24794)
authorPablo Galindo <Pablogsal@gmail.com>
Wed, 10 Mar 2021 00:53:57 +0000 (00:53 +0000)
committerGitHub <noreply@github.com>
Wed, 10 Mar 2021 00:53:57 +0000 (00:53 +0000)
Doc/library/gc.rst
Doc/whatsnew/3.10.rst
Lib/test/audit-tests.py
Lib/test/test_audit.py
Misc/NEWS.d/next/Security/2021-03-08-23-06-07.bpo-43439.5U3lXm.rst [new file with mode: 0644]
Modules/gcmodule.c

index a3d201d5055c8ecda55c5a4c4bcb5c74b6b6b689..69a1a8313b7593104986cac131d9c189b1415cc2 100644 (file)
@@ -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)
 
index db71f061f14df4585def3bb35876641c8069fcaf..814594a0525958f21c89c6feb369fca738ac02a9 100644 (file)
@@ -673,9 +673,16 @@ When a module does not define ``__loader__``, fall back to ``__spec__.loader``.
 
 encodings
 ---------
+
 :func:`encodings.normalize_encoding` now ignores non-ASCII characters.
 (Contributed by Hai Shi in :issue:`39337`.)
 
+gc
+--
+
+Added audit hooks for :func:`gc.get_objects`, :func:`gc.get_referrers` and
+:func:`gc.get_referents`. (Contributed by Pablo Galindo in :issue:`43439`.)
+
 glob
 ----
 
index ee6fc93351b753392e317e30cd8c1d85085648fc..8e66594e52429b623eb8f070f861e0b2bb5e816f 100644 (file)
@@ -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
 
index 4f8d06a3ebcbeeb15b146f7556920afad0b33e28..58180e147a49a3799593f694a86a1dbfbb7d386c 100644 (file)
@@ -118,5 +118,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 (file)
index 0000000..5186503
--- /dev/null
@@ -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.
index 21f6bd1a9b6d0e16e4929665f236e455bfc72530..225da2b20959250cbc064b1e83566d35763bfd2a 100644 (file)
@@ -1690,6 +1690,10 @@ Return the list of objects that directly refer to any of objs.");
 static PyObject *
 gc_get_referrers(PyObject *self, PyObject *args)
 {
+    if (PySys_Audit("gc.get_referrers", "O", args) < 0) {
+        return NULL;
+    }
+
     PyObject *result = PyList_New(0);
     if (!result) {
         return NULL;
@@ -1720,6 +1724,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)
@@ -1762,6 +1769,10 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation)
     PyObject* result;
     GCState *gcstate = &tstate->interp->gc;
 
+    if (PySys_Audit("gc.get_objects", "n", generation) < 0) {
+        return NULL;
+    }
+
     result = PyList_New(0);
     if (result == NULL) {
         return NULL;