Open
Description
Bug report
Bug description:
Several extension modules don't fully emit the relevant audit events, leading to file read or process spawning without any traceability.
In particular:
- Calling a
_ctypes.CFuncPtr
does not emitctypes.call_function
. When combined with some known addresses, this can result in arbitrary functions in libc or python getting called. Such addresses could come fromid
,ctypes.pythonapi._handle
, passing abyref
pointer toctypes.cast
, or probably still several other methods. Coincidentally, thectypes.cast
method would by audited by the samectypes.call_function
once it is present. The downside is that it may also result in multiple audit hooks for functions likectypes.string_at
that have their own specialized audit hook event too. - Related, and maybe debatable, but constructing a
_ctypes.CFuncPtr
might fall under the audit eventctypes.cdata
, as it is in spirit (though not in implementation) similar to calling a.from_address
. An option might be to introducectypes.cdata/function
similar toctypes.cdata/buffer
for this. - The
readline
module can open and read a file throughreadline.read_history_file
without having anopen
audit hook. Together withreadline.get_history_item
, this can lead to unaudited file reads. A similar situation exists for some other functions in this library. - The
_posixsubprocess.fork_exec
function, and its only user in the standard library,multiprocessing.util.spawnv_passfds
perform a fork + exec without any audit hooks. One would expect eitheros.fork
andos.exec
or the functionally similaros.posix_spawn
here.
I'm happy to make a quick PR for these and adjust any specific event types to be more consistent or more uniquely identifiable.
Quick example in code:
import sys, ctypes, multiprocessing.util, readline
collected = []
def collector(event, *_args):
collected.append(event)
sys.addaudithook(collector)
def test(fn, *args, **kw):
collected.clear()
fn(*args, **kw)
if collected: # Just check it's nonempty
print("Success")
else:
print("Fail")
test(ctypes.memmove, 0, 0, 0)
test(ctypes.CFUNCTYPE(ctypes.py_object), ctypes._memmove_addr)
test(readline.read_history_file, __file__)
test(multiprocessing.util.spawnv_passfds, b"/bin/id", [], [])
CPython versions tested on:
3.11, 3.12, 3.13, CPython main branch
Operating systems tested on:
Linux