From 2a61ed51634785bc1bbbdbee035986ec3e45904b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 18 Jul 2024 13:06:29 +0200 Subject: [PATCH 1/5] gh-121957: Emit `cpython.run_stdin` audit event for `python -i` with PyREPL Relatedly, emit the `cpython.run_startup` event from the Python version of `PYTHONSTARTUP` handling. --- Lib/_pyrepl/main.py | 2 ++ Modules/main.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/_pyrepl/main.py b/Lib/_pyrepl/main.py index 8d6e07d36b52ca..a6f824dcc4ad14 100644 --- a/Lib/_pyrepl/main.py +++ b/Lib/_pyrepl/main.py @@ -39,6 +39,8 @@ def interactive_console(mainmodule=None, quiet=False, pythonstartup=False): # sys._baserepl() above does this internally, we do it here startup_path = os.getenv("PYTHONSTARTUP") if pythonstartup and startup_path: + sys.audit("cpython.run_startup", startup_path) + import tokenize with tokenize.open(startup_path) as f: startup_code = compile(f.read(), startup_path, "exec") diff --git a/Modules/main.c b/Modules/main.c index 3c202c85c76dcc..ad2fb784d030df 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -264,12 +264,17 @@ static int pymain_start_pyrepl_no_main(void) { int res = 0; + PyObject *pyrepl = NULL; PyObject *console = NULL; PyObject *empty_tuple = NULL; PyObject *kwargs = NULL; PyObject *console_result = NULL; - PyObject *pyrepl = PyImport_ImportModule("_pyrepl.main"); + if (PySys_Audit("cpython.run_stdin", NULL) < 0) { + res = pymain_exit_err_print(); + goto done; + } + pyrepl = PyImport_ImportModule("_pyrepl.main"); if (pyrepl == NULL) { fprintf(stderr, "Could not import _pyrepl.main\n"); res = pymain_exit_err_print(); From 8e0cf2cd7286a723b76b3e7eeb1b93cbb5d34a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 18 Jul 2024 13:17:51 +0200 Subject: [PATCH 2/5] Add Blurb --- .../Security/2024-07-18-13-17-47.gh-issue-121957.QemKLU.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Security/2024-07-18-13-17-47.gh-issue-121957.QemKLU.rst diff --git a/Misc/NEWS.d/next/Security/2024-07-18-13-17-47.gh-issue-121957.QemKLU.rst b/Misc/NEWS.d/next/Security/2024-07-18-13-17-47.gh-issue-121957.QemKLU.rst new file mode 100644 index 00000000000000..49ccc5e14633cd --- /dev/null +++ b/Misc/NEWS.d/next/Security/2024-07-18-13-17-47.gh-issue-121957.QemKLU.rst @@ -0,0 +1,3 @@ +Fixed missing audit events around interactive use of Python, now also +properly firing for ``python -i``, as well as for ``python -m asyncio``. The +events in question are ``cpython.run_stdin`` and ``cpython.run_startup``. From 7c5a8975dc51b45adf2ba893d64801eb9afd860b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 18 Jul 2024 13:38:00 +0200 Subject: [PATCH 3/5] Also emit events in `-m asyncio` --- Lib/asyncio/__main__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/asyncio/__main__.py b/Lib/asyncio/__main__.py index 8b5a4b8f282a92..111b7d92367210 100644 --- a/Lib/asyncio/__main__.py +++ b/Lib/asyncio/__main__.py @@ -91,6 +91,8 @@ def run(self): console.write(banner) if startup_path := os.getenv("PYTHONSTARTUP"): + sys.audit("cpython.run_startup", startup_path) + import tokenize with tokenize.open(startup_path) as f: startup_code = compile(f.read(), startup_path, "exec") @@ -127,6 +129,8 @@ def run(self): if __name__ == '__main__': + sys.audit("cpython.run_stdin") + if os.getenv('PYTHON_BASIC_REPL'): CAN_USE_PYREPL = False else: @@ -155,6 +159,7 @@ def run(self): interactive_hook = getattr(sys, "__interactivehook__", None) if interactive_hook is not None: + sys.audit("cpython.run_interactivehook", interactive_hook) interactive_hook() if interactive_hook is site.register_readline: From cf65323c04c6f60b1775391b8cc3877e8bb7dfdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 18 Jul 2024 13:38:18 +0200 Subject: [PATCH 4/5] Emit `cpython.run_stdin` in `python -i` even if PyREPL is not used --- Modules/main.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Modules/main.c b/Modules/main.c index ad2fb784d030df..15ea49a1bad19e 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -264,17 +264,12 @@ static int pymain_start_pyrepl_no_main(void) { int res = 0; - PyObject *pyrepl = NULL; PyObject *console = NULL; PyObject *empty_tuple = NULL; PyObject *kwargs = NULL; PyObject *console_result = NULL; - if (PySys_Audit("cpython.run_stdin", NULL) < 0) { - res = pymain_exit_err_print(); - goto done; - } - pyrepl = PyImport_ImportModule("_pyrepl.main"); + PyObject *pyrepl = PyImport_ImportModule("_pyrepl.main"); if (pyrepl == NULL) { fprintf(stderr, "Could not import _pyrepl.main\n"); res = pymain_exit_err_print(); @@ -599,6 +594,10 @@ pymain_repl(PyConfig *config, int *exitcode) return; } + if (PySys_Audit("cpython.run_stdin", NULL) < 0) { + return; + } + if (!isatty(fileno(stdin)) || _Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) { PyCompilerFlags cf = _PyCompilerFlags_INIT; From 461e9b4a4a8fbf4800c18f0e684bba9775f72b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 18 Jul 2024 14:43:02 +0200 Subject: [PATCH 5/5] Document newly emitted events --- Doc/library/asyncio.rst | 15 +++++++++++++-- Doc/using/cmdline.rst | 9 +++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 184f981c1021aa..5f83b3a2658da4 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -56,9 +56,13 @@ Additionally, there are **low-level** APIs for * :ref:`bridge ` callback-based libraries and code with async/await syntax. +.. include:: ../includes/wasm-notavail.rst + .. _asyncio-cli: -You can experiment with an ``asyncio`` concurrent context in the REPL: +.. rubric:: asyncio REPL + +You can experiment with an ``asyncio`` concurrent context in the :term:`REPL`: .. code-block:: pycon @@ -70,7 +74,14 @@ You can experiment with an ``asyncio`` concurrent context in the REPL: >>> await asyncio.sleep(10, result='hello') 'hello' -.. include:: ../includes/wasm-notavail.rst +.. audit-event:: cpython.run_stdin "" "" + +.. versionchanged:: 3.12.5 (also 3.11.10, 3.10.15, 3.9.20, and 3.8.20) + Emits audit events. + +.. versionchanged:: 3.13 + Uses PyREPL if possible, in which case :envvar:`PYTHONSTARTUP` is + also executed. Emits audit events. .. We use the "rubric" directive here to avoid creating the "Reference" subsection in the TOC. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index a575760c963327..c175c4f8b5b1eb 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -793,6 +793,15 @@ conflict. This variable can also be modified by Python code using :data:`os.environ` to force inspect mode on program termination. + .. audit-event:: cpython.run_stdin "" "" + + .. versionchanged:: 3.12.5 (also 3.11.10, 3.10.15, 3.9.20, and 3.8.20) + Emits audit events. + + .. versionchanged:: 3.13 + Uses PyREPL if possible, in which case :envvar:`PYTHONSTARTUP` is + also executed. Emits audit events. + .. envvar:: PYTHONUNBUFFERED