Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.3k
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.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:
importsys,ctypes,multiprocessing.util,readlinecollected= []defcollector(event,*_args):collected.append(event)sys.addaudithook(collector)deftest(fn,*args,**kw):collected.clear()fn(*args,**kw)ifcollected:# Just check it's nonemptyprint("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