bpo-39184: Add audit events to command execution functions in os and pty modules (GH-17824)
This commit is contained in:
parent
40e547dfbb
commit
95f6001021
|
@ -3314,6 +3314,8 @@ to be ignored.
|
||||||
you can check whether or not it is available using :data:`os.supports_fd`.
|
you can check whether or not it is available using :data:`os.supports_fd`.
|
||||||
If it is unavailable, using it will raise a :exc:`NotImplementedError`.
|
If it is unavailable, using it will raise a :exc:`NotImplementedError`.
|
||||||
|
|
||||||
|
.. audit-event:: os.exec path,args,env os.execl
|
||||||
|
|
||||||
.. availability:: Unix, Windows.
|
.. availability:: Unix, Windows.
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
@ -3670,6 +3672,8 @@ written in Python, such as a mail server's external command delivery program.
|
||||||
:c:data:`POSIX_SPAWN_SETSCHEDPARAM` and :c:data:`POSIX_SPAWN_SETSCHEDULER`
|
:c:data:`POSIX_SPAWN_SETSCHEDPARAM` and :c:data:`POSIX_SPAWN_SETSCHEDULER`
|
||||||
flags.
|
flags.
|
||||||
|
|
||||||
|
.. audit-event:: os.posix_spawn path,argv,env os.posix_spawn
|
||||||
|
|
||||||
.. versionadded:: 3.8
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
.. availability:: Unix.
|
.. availability:: Unix.
|
||||||
|
@ -3684,6 +3688,8 @@ written in Python, such as a mail server's external command delivery program.
|
||||||
for the *executable* file in the list of directories specified by the
|
for the *executable* file in the list of directories specified by the
|
||||||
:envvar:`PATH` environment variable (in the same way as for ``execvp(3)``).
|
:envvar:`PATH` environment variable (in the same way as for ``execvp(3)``).
|
||||||
|
|
||||||
|
.. audit-event:: os.posix_spawn path,argv,env os.posix_spawnp
|
||||||
|
|
||||||
.. versionadded:: 3.8
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
.. availability:: See :func:`posix_spawn` documentation.
|
.. availability:: See :func:`posix_spawn` documentation.
|
||||||
|
@ -3784,6 +3790,8 @@ written in Python, such as a mail server's external command delivery program.
|
||||||
L = ['cp', 'index.html', '/dev/null']
|
L = ['cp', 'index.html', '/dev/null']
|
||||||
os.spawnvpe(os.P_WAIT, 'cp', L, os.environ)
|
os.spawnvpe(os.P_WAIT, 'cp', L, os.environ)
|
||||||
|
|
||||||
|
.. audit-event:: os.spawn mode,path,args,env os.spawnl
|
||||||
|
|
||||||
.. availability:: Unix, Windows. :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp`
|
.. availability:: Unix, Windows. :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp`
|
||||||
and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and
|
and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and
|
||||||
:func:`spawnve` are not thread-safe on Windows; we advise you to use the
|
:func:`spawnve` are not thread-safe on Windows; we advise you to use the
|
||||||
|
@ -3853,6 +3861,8 @@ written in Python, such as a mail server's external command delivery program.
|
||||||
function is not resolved until this function is first called. If the function
|
function is not resolved until this function is first called. If the function
|
||||||
cannot be resolved, :exc:`NotImplementedError` will be raised.
|
cannot be resolved, :exc:`NotImplementedError` will be raised.
|
||||||
|
|
||||||
|
.. audit-event:: os.startfile path,operation os.startfile
|
||||||
|
|
||||||
.. availability:: Windows.
|
.. availability:: Windows.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ The :mod:`pty` module defines the following functions:
|
||||||
*select* throws an error on your platform when passed three empty lists. This
|
*select* throws an error on your platform when passed three empty lists. This
|
||||||
is a bug, documented in `issue 26228 <https://bugs.python.org/issue26228>`_.
|
is a bug, documented in `issue 26228 <https://bugs.python.org/issue26228>`_.
|
||||||
|
|
||||||
|
.. audit-event:: pty.spawn argv pty.spawn
|
||||||
|
|
||||||
.. versionchanged:: 3.4
|
.. versionchanged:: 3.4
|
||||||
:func:`spawn` now returns the status value from :func:`os.waitpid`
|
:func:`spawn` now returns the status value from :func:`os.waitpid`
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
from select import select
|
from select import select
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import tty
|
import tty
|
||||||
|
|
||||||
__all__ = ["openpty","fork","spawn"]
|
__all__ = ["openpty","fork","spawn"]
|
||||||
|
@ -151,6 +152,7 @@ def spawn(argv, master_read=_read, stdin_read=_read):
|
||||||
"""Create a spawned process."""
|
"""Create a spawned process."""
|
||||||
if type(argv) == type(''):
|
if type(argv) == type(''):
|
||||||
argv = (argv,)
|
argv = (argv,)
|
||||||
|
sys.audit('pty.spawn', argv)
|
||||||
pid, master_fd = fork()
|
pid, master_fd = fork()
|
||||||
if pid == CHILD:
|
if pid == CHILD:
|
||||||
os.execlp(argv[0], *argv)
|
os.execlp(argv[0], *argv)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Add audit events to command execution functions in os and pty modules.
|
|
@ -5234,6 +5234,12 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None,
|
||||||
|
argv, Py_None) < 0) {
|
||||||
|
free_string_array(argvlist, argc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
_Py_BEGIN_SUPPRESS_IPH
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
#ifdef HAVE_WEXECV
|
#ifdef HAVE_WEXECV
|
||||||
_wexecv(path->wide, argvlist);
|
_wexecv(path->wide, argvlist);
|
||||||
|
@ -5277,7 +5283,7 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
|
||||||
if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
|
if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"execve: argv must be a tuple or list");
|
"execve: argv must be a tuple or list");
|
||||||
goto fail;
|
goto fail_0;
|
||||||
}
|
}
|
||||||
argc = PySequence_Size(argv);
|
argc = PySequence_Size(argv);
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
|
@ -5288,22 +5294,27 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
|
||||||
if (!PyMapping_Check(env)) {
|
if (!PyMapping_Check(env)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"execve: environment must be a mapping object");
|
"execve: environment must be a mapping object");
|
||||||
goto fail;
|
goto fail_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
argvlist = parse_arglist(argv, &argc);
|
argvlist = parse_arglist(argv, &argc);
|
||||||
if (argvlist == NULL) {
|
if (argvlist == NULL) {
|
||||||
goto fail;
|
goto fail_0;
|
||||||
}
|
}
|
||||||
if (!argvlist[0][0]) {
|
if (!argvlist[0][0]) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"execve: argv first element cannot be empty");
|
"execve: argv first element cannot be empty");
|
||||||
goto fail;
|
goto fail_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
envlist = parse_envlist(env, &envc);
|
envlist = parse_envlist(env, &envc);
|
||||||
if (envlist == NULL)
|
if (envlist == NULL)
|
||||||
goto fail;
|
goto fail_0;
|
||||||
|
|
||||||
|
if (PySys_Audit("os.exec", "OOO", path->object ? path->object : Py_None,
|
||||||
|
argv, env) < 0) {
|
||||||
|
goto fail_1;
|
||||||
|
}
|
||||||
|
|
||||||
_Py_BEGIN_SUPPRESS_IPH
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
#ifdef HAVE_FEXECVE
|
#ifdef HAVE_FEXECVE
|
||||||
|
@ -5321,9 +5332,9 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
|
||||||
/* If we get here it's definitely an error */
|
/* If we get here it's definitely an error */
|
||||||
|
|
||||||
posix_path_error(path);
|
posix_path_error(path);
|
||||||
|
fail_1:
|
||||||
free_string_array(envlist, envc);
|
free_string_array(envlist, envc);
|
||||||
fail:
|
fail_0:
|
||||||
if (argvlist)
|
if (argvlist)
|
||||||
free_string_array(argvlist, argc);
|
free_string_array(argvlist, argc);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5654,6 +5665,11 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
|
||||||
}
|
}
|
||||||
attrp = &attr;
|
attrp = &attr;
|
||||||
|
|
||||||
|
if (PySys_Audit("os.posix_spawn", "OOO",
|
||||||
|
path->object ? path->object : Py_None, argv, env) < 0) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
_Py_BEGIN_SUPPRESS_IPH
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
#ifdef HAVE_POSIX_SPAWNP
|
#ifdef HAVE_POSIX_SPAWNP
|
||||||
if (use_posix_spawnp) {
|
if (use_posix_spawnp) {
|
||||||
|
@ -5894,6 +5910,13 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
|
||||||
mode = _P_OVERLAY;
|
mode = _P_OVERLAY;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (PySys_Audit("os.spawn", "iOOO", mode,
|
||||||
|
path->object ? path->object : Py_None, argv,
|
||||||
|
Py_None) < 0) {
|
||||||
|
free_string_array(argvlist, argc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
_Py_BEGIN_SUPPRESS_IPH
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
#ifdef HAVE_WSPAWNV
|
#ifdef HAVE_WSPAWNV
|
||||||
|
@ -6003,6 +6026,11 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
|
||||||
mode = _P_OVERLAY;
|
mode = _P_OVERLAY;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (PySys_Audit("os.spawn", "iOOO", mode,
|
||||||
|
path->object ? path->object : Py_None, argv, env) < 0) {
|
||||||
|
goto fail_2;
|
||||||
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
_Py_BEGIN_SUPPRESS_IPH
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
#ifdef HAVE_WSPAWNV
|
#ifdef HAVE_WSPAWNV
|
||||||
|
@ -6021,6 +6049,7 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
|
||||||
else
|
else
|
||||||
res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
|
res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
|
||||||
|
|
||||||
|
fail_2:
|
||||||
while (--envc >= 0)
|
while (--envc >= 0)
|
||||||
PyMem_DEL(envlist[envc]);
|
PyMem_DEL(envlist[envc]);
|
||||||
PyMem_DEL(envlist);
|
PyMem_DEL(envlist);
|
||||||
|
@ -11701,6 +11730,12 @@ os_startfile_impl(PyObject *module, path_t *filepath,
|
||||||
"startfile not available on this platform");
|
"startfile not available on this platform");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PySys_Audit("os.startfile", "Ou",
|
||||||
|
filepath->object ? filepath->object : Py_None,
|
||||||
|
operation) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
|
rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
|
||||||
NULL, NULL, SW_SHOWNORMAL);
|
NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
|
Loading…
Reference in New Issue