Extend the existing setuid guard in xtables_init() to also detect
file capabilities via getauxval(AT_SECURE).
Some container runtimes and minimal distributions grant cap_net_admin
via file capabilities (setcap cap_net_admin+ep /usr/sbin/iptables)
rather than running through sudo. In that configuration the kernel
sets AT_SECURE and the dynamic linker strips LD_PRELOAD, but
getuid() == geteuid() so the existing setuid check passes.
Attacker-controlled env vars (XTABLES_LIBDIR, IPTABLES_LIB_DIR,
IP6TABLES_LIB_DIR) still reach dlopen(), allowing arbitrary code
execution as the capability-elevated user.
getauxval(AT_SECURE) is nonzero whenever the kernel has set AT_SECURE
in the auxiliary vector -- this covers both classic setuid/setgid and
file capabilities. Exit with status 111, matching the existing
setuid behavior.
Signed-off-by: Alan Ross <alan@sleuthco.ai>
Signed-off-by: Florian Westphal <fw@strlen.de>
#include <netinet/ether.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/auxv.h>
#include <sys/statfs.h>
#include <sys/types.h>
#include <sys/utsname.h>
void xtables_init(void)
{
- /* xtables cannot be used with setuid in a safe way. */
- if (getuid() != geteuid())
+ /* xtables cannot be used with setuid/setcap in a safe way. */
+ if (getuid() != geteuid() || getauxval(AT_SECURE))
_exit(111);
xtables_libdir = getenv("XTABLES_LIBDIR");