On 16Apr2019 0532, Christian Heimes wrote:
Sorry, I forgot to reply.
Do you think it would make sense to split the PEP into two PEPs? The auditing hook and import opener hook are related, but distinct improvements. The auditing part looks solid and ready now. The import opener may need some more refinement. I would also like to get feedback from some Linux Kernel security engineers first.
That will make three PEPs...
The only question for the security engineers is "how much context do you need from the calling process", as that's the only thing that will affect the API. It doesn't have to have any implementation right now.
And so far, all the context that's been proposed is "may be executed", which is already implied in the open_code() call. I haven't heard any more requests than "give us the filename and let us return the open (and exclusive) handle/descriptor", so this feels like YAGNI.
On 01/04/2019 18.31, Steve Dower wrote:
In each case there should be associated audit events for tracking the intent (and interrupting at that point if it doesn't like the intended action), but for the simple case of "let me open this specific file" it doesn't really add much. And it almost certainly shouldn't impact decision making.
There is no need to trust the intent flag that much. I would like to have a way to further narrow down the scope for an open call. This would allow the caller to tell the hook "I want to open something that should be a shared library suitable for ctypes". It would allow tighter control.
But those don't go through open(), they'll go through dlopen(), right? It's already a totally different code path from "open and read arbitrary bytes".
Audit events are useful and powerful. But I don't want to put too much burden on the auditing framwork. I prefer to have checks that prevent operations rather than allow operations and audit them.
Right, and this is the default position for security defenders (to try and block things) ;) Auditing has been found to be a working balance
- Context is an optional Python object from the caller's context. For
the import system, it could be the loader instance.
I think the audit event covers this, unless you have some way of using this context in mind that I can't think of?
To be honest I don't have a good use case yet. I just like the idea to have a way to pass some custom thing into an API and now who called an API. You seem to like it, too. Your hook has a void *userData, but it's not passed into the Python function. :)
int PyImport_SetOpenForImportHook(hook_func handler, void *userData)
There is no Python function for the (now named) open_code hook. It can only be set as a C function by an embedder, and that's when the userData is provided. Nothing to do with each individual call - just one value per CPython runtime. (Similarly with the audit hook, but for the Python hooks you can pass a closure or a method - in C you need a separate pointer for this.)