-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
Open
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
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.CFuncPtrdoes 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 abyrefpointer toctypes.cast, or probably still several other methods. Coincidentally, thectypes.castmethod would by audited by the samectypes.call_functiononce it is present. The downside is that it may also result in multiple audit hooks for functions likectypes.string_atthat have their own specialized audit hook event too. - Related, and maybe debatable, but constructing a
_ctypes.CFuncPtrmight 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/functionsimilar toctypes.cdata/bufferfor this. - The
readlinemodule can open and read a file throughreadline.read_history_filewithout having anopenaudit 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_execfunction, and its only user in the standard library,multiprocessing.util.spawnv_passfdsperform a fork + exec without any audit hooks. One would expect eitheros.forkandos.execor the functionally similaros.posix_spawnhere.
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
Linked PRs
hyunsikjeong, RealHurrison and gpshead
Metadata
Metadata
Assignees
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error