Communication between kernel and userspace via local socket

Maxim Ignatenko gelraen.ua at gmail.com
Tue Nov 15 20:18:51 UTC 2011


frHi,

I'm currently inventing the wheel^W^W^Wwriting a firewall from scratch and 
looking for most convenient way to establish communication between userspace 
processes and kernel part. Communication pattern best fits to listening 
PF_LOCAL socket opened from kernel and userspace processes connecting to it. 
Clients should be able to send requests and receive responses from kernel (to 
retrieve list of loaded modules, active ruleset, add or remove rules, ...) and 
vice versa: kernel should be able to send request to userspace process and 
receive response (I'm planning to add interactive features like in most 
firewalls for windows(r)).

First part can be implemented via ioctl, but it should be called not only by 
processes with euid == 0, so supplied pointer to receive buffer cannot be 
trusted (is there any mechanism to check memory allocation?) and any 
unprivileged user can instruct kernel to write some trash at arbitrary address 
(for example, VM just rebooted ungracefully when I supplied (void*)123 as 
pointer to destination buffer).

So, requirements is:
1) message exchange can initiated from userspace and from kernel
2) safe to communicate with unprivileged processes (not like in above case 
with ioctl)
3) kernel part should be able to determine process uid
4) messages size can be large (from 1KB to 10KB and more)

Now I'm thinking about few variants:
1) emulation of local socket via character device. This way requires to 
manually handle per-process IO buffers, which almost certainly will have many 
bugs
2) opening local socket from kernel. This, as I think, require to spawn new 
process in kernel (but I don't know how to do this) to listen for incoming 
connections and messages
3) userspace mux/demux daemon (like devd): one and only one process opens 
character device and uses local socket to communicate with other processes. 
This requires to design 2 ABIs - kernel<->daemon and daemon<->client.

2nd variant looks most appropriate but know I don't know how to implement it. 
Can anyone point me to some documentation about spawning processes in kernel 
an working with sockets from kernelspace, or suggest better way of 
communication between processes and kernel?


More information about the freebsd-hackers mailing list