[Snort-devel] [RFC][DAQ] nfq: add support for unprivileged operation

Michael Altizer xiche at ...1778...
Tue Aug 3 14:16:33 EDT 2010

On 08/03/2010 12:11 PM, Florian Westphal wrote:
> Disclaimer:
> This patch should not be applied.
> It seems better to me to follow Will Metcalfs libcap-ng pointer
> than to use the "old" libcap (which is what this patch uses).
> Also, newer kernels (and libcap-ng) would allow use of
> uid 0 without the ability to regain a full privilege set
> via execve().
> Anyway, maybe it is of some help.
> Note that without the setuid() threads spawned before retain
> their capability set, so its not easy to do without it.
> =============================
> its possible to use nfqueue with a non-zero user id as long as
> the calling thread has CAP_NET_ADMIN privileges.
> Add "--daq-var uid=<id>" to have the nfq backend switch uid while
> keep CAP_NET_ADMIN privileges.
> Its currently not possible to have snort do the setuid, as we need
> to follow this sequence:
> 1. prctl(PR_SET_KEEPCAPS, 1)
> 2. setuid()
> 3. set capabilities to CAP_NET_ADMIN (discarding all others)
> 1 has to be called before snort will call setuid/setgid, this can be
> done e.g. in the daq init hook.
> However, snort may invoke pthread_create (depends on configuration)
> before it calls into the daq module again (DAQ_Start), so we have something like
> this:
> 1. prctl (daq init)
> 2. setuid (snort)
> 3. pthread_create (snort -- e.g. for the reload thread)
> 4. set capabilities to CAP_NET_ADMIN (discarding all others)
> as capabilites are per-thread attributes, all spawned threads
> still run with the full privilege set.
> This would have to be solved either by creating other DAQ hooks
> (e.g. DAQ_pre_setuid/DAQ_post_setuid) or by guaranteeing that threads
> are only created after e.g. DAQ_start.
<snip patch>

(I know that you said this was not to be applied, but I'm replying based 
on your code since I'm not familiar with libpcap-ng.)

I think we would probably be better off making this a little more 
generic from the DAQ module perspective and having the application using 
LibDAQ handle it appropriately.  So, for example, use either a DAQ_CAPA 
or DAQ_TYPE flag on the NFQ DAQ module to indicate that it can be run 
unprivileged as long as the capabilities are set correctly and let Snort 
handle doing so in its own setuid/gid routine.

Right now, the NFQ DAQ has the DAQ_TYPE_NO_UNPRIV flag to handle this 
situation.  It could instead have something like 
DAQ_TYPE_REQUIRES_NET_ADMIN.  If Snort is compiled with libcap support, 
it would then try to do the capabilities stuff accordingly in 
SetUidGid(), otherwise it would treat it as it does now (refuse to drop 
privs at all).  This also makes it easier for Snort to do the right 
thing in your second multithreaded case.


More information about the Snort-devel mailing list