summaryrefslogtreecommitdiffstats
path: root/libxtables
diff options
context:
space:
mode:
authorAlan Ross <alan@sleuthco.ai>2026-02-12 08:35:21 -0500
committerFlorian Westphal <fw@strlen.de>2026-02-13 12:34:26 +0100
commita2a733e9f0da779bbe009736644f4481e22ca3d1 (patch)
treee7cd02d432c67b4e9ff33b586d54e9c8a84564a0 /libxtables
parentbf77b769b83a68c841dcb4f7cdf3998e2817727f (diff)
libxtables: refuse to run under file capabilities
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>
Diffstat (limited to 'libxtables')
-rw-r--r--libxtables/xtables.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index af56a75f..f872cc69 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -31,6 +31,7 @@
#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>
@@ -331,8 +332,8 @@ void xtables_announce_chain(const char *name)
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");