I had to deal with a very similar situation a few months ago and here’s
a brain dump of what I found out and the solution I went with.
The kernel symbols necessary to perform code signature validation on a
process are not KPI (i.e. private) and attempting to link against them
will lead to kextd (justly) refusing to load the kext. So unless you’re
willing to somehow resolve these private symbols at runtime (don’t do
that!) you’re left with implementing signature validation in user space.
Now, as Stéphane wrote, a good starting point if your user space daemon
is running as root, is to make your control socket `CTL_FLAG_PRIVILEGED`
so that you can already exclude a whole bunch of non-root processes from
connecting to the kext. You will still have to protect your user space
process from code injection. I believe Mach injection (when possible at
all, so against non-SIP processes that is) requires root to obtain the
task from pid so that should be safe. Regarding dyld injection, I think
you’ll want to make sure that your process is restricted (check for
https://opensource.apple.com/source/dyld/dyld-421.1/src/dyld.cpp for
more info) so that dyld doesn’t blindly load dylibs it find in the
`DYLD_INSERT_LIBRARIES` env variable. Note that if your binary is setuid
it should be restricted by default.
If, as in my case, you also need non-root processes to connect to the
kext, you will need a root daemon (as described above) doing code
signature valdiation in user space and connecting to the kext on a
distinct `CTL_FLAG_PRIVILEGED` control socket. Then, whenever a regular
process attempts to connect to the kext on your usual control socket,
you would get its credentials, send them to the root daemon that would
perform signature validation on behalf of the kext and respond with a
yes/no answer. You can then decide whether to allow or deny the original
connection in your kext.
Finally you also need to make sure that you can correctly resolve the
process creds/pid at control socket connection time. I’ve found that the
`ctl_connect` handler is invoked in the connecting process context so
calling `prod_self` and then `proc_ucred` and `proc_pid` should be safe
but worth keeping in mind that it might not always be the case?
Thanks,
Damien
On Wed, Jan 4, 2017, at 03:44 AM, Stéphane Sudre wrote:
>
> On 4 janv. 2017, at 07:10, Josh Hight wrote:
>
> > I have an application with two components, a Kernel Extension and a User-Mode daemon. I need to communicate information from the Kernel Extension to the User-Mode daemon. Since this is a security application and the information being communicated is sensitive
I would quite like to verify that the information is communicated only with my User-Mode daemon. Is there any way to accomplish this?
>
> If the communication between your daemon and the Kernel Extension is
> performed via a control socket, the first step would be to set the
> CTL_FLAG_PRIVILEGED flag when you register your control socket (in the
> kext) so that only a root user-land process can communicate with your
> kext.
>
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Darwin-kernel mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden