From: Remi Gacogne Date: Fri, 2 Nov 2018 13:01:15 +0000 (+0100) Subject: dnsdist: Drop remaining capabilities after startup X-Git-Tag: rec-4.2.0-alpha1~58^2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fdc3ea42e4d860c7e3f33f63b425ed8bc99d047e;p=pdns dnsdist: Drop remaining capabilities after startup --- diff --git a/m4/pdns_with_libcap.m4 b/m4/pdns_with_libcap.m4 new file mode 100644 index 000000000..0dba5da27 --- /dev/null +++ b/m4/pdns_with_libcap.m4 @@ -0,0 +1,25 @@ +AC_DEFUN([PDNS_WITH_LIBCAP], [ + AC_MSG_CHECKING([whether we will be linking in libcap]) + HAVE_LIBCAPS=0 + AC_ARG_WITH([libcap], + AS_HELP_STRING([--with-libcap],[use libcap @<:@default=auto@:>@]), + [with_libcap=$withval], + [with_libcap=auto], + ) + AC_MSG_RESULT([$with_libcap]) + + AS_IF([test "x$with_libcap" != "xno"], [ + AS_IF([test "x$with_libcap" = "xyes" -o "x$with_libcap" = "xauto"], [ + PKG_CHECK_MODULES([LIBCAP], [libcap] , [ + [HAVE_LIBCAP=1] + AC_DEFINE([HAVE_LIBCAP], [1], [Define to 1 if you have libcap]) + ], [ : ]) + ]) + ]) + AM_CONDITIONAL([HAVE_LIBCAP], [test "x$LIBCAP_LIBS" != "x"]) + AS_IF([test "x$with_libcap" = "xyes"], [ + AS_IF([test x"$LIBCAP_LIBS" = "x"], [ + AC_MSG_ERROR([libcap requested but libraries were not found]) + ]) + ]) +]) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 915d90484..7ada5929e 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -2701,6 +2701,18 @@ try dropGroupPrivs(newgid); dropUserPrivs(newuid); + try { + /* we might still have capabilities remaining, + for example if we have been started as root + without --uid or --gid (please don't do that) + or as an unprivileged user with ambient + capabilities like CAP_NET_BIND_SERVICE. + */ + dropCapabilities(); + } + catch(const std::exception& e) { + warnlog("%s", e.what()); + } /* this need to be done _after_ dropping privileges */ g_delay = new DelayPipe(); diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 92c8632ce..50354ece1 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -1,4 +1,4 @@ -AM_CPPFLAGS += $(SYSTEMD_CFLAGS) $(LUA_CFLAGS) $(LIBEDIT_CFLAGS) $(LIBSODIUM_CFLAGS) $(FSTRM_CFLAGS) $(YAHTTP_CFLAGS) $(SANITIZER_FLAGS) $(NET_SNMP_CFLAGS) -DSYSCONFDIR=\"${sysconfdir}\" +AM_CPPFLAGS += $(SYSTEMD_CFLAGS) $(LUA_CFLAGS) $(LIBEDIT_CFLAGS) $(LIBSODIUM_CFLAGS) $(FSTRM_CFLAGS) $(YAHTTP_CFLAGS) $(SANITIZER_FLAGS) $(NET_SNMP_CFLAGS) $(LIBCAP_CFLAGS) -DSYSCONFDIR=\"${sysconfdir}\" ACLOCAL_AMFLAGS = -I m4 @@ -162,7 +162,8 @@ dnsdist_LDADD = \ $(FSTRM_LIBS) \ $(SANITIZER_FLAGS) \ $(SYSTEMD_LIBS) \ - $(NET_SNMP_LIBS) + $(NET_SNMP_LIBS) \ + $(LIBCAP_LIBS) if HAVE_RE2 dnsdist_LDADD += $(RE2_LIBS) @@ -266,7 +267,8 @@ testrunner_LDADD = \ $(LIBSODIUM_LIBS) \ $(FSTRM_LIBS) \ $(RT_LIBS) \ - $(SANITIZER_FLAGS) + $(SANITIZER_FLAGS) \ + $(LIBCAP_LIBS) MANPAGES=dnsdist.1 diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index a1b41989c..6ee328f24 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -40,6 +40,7 @@ PDNS_WITH_RE2 DNSDIST_ENABLE_DNSCRYPT PDNS_WITH_EBPF PDNS_WITH_NET_SNMP +PDNS_WITH_LIBCAP AX_AVAILABLE_SYSTEMD AM_CONDITIONAL([HAVE_SYSTEMD], [ test x"$systemd" = "xy" ]) diff --git a/pdns/dnsdistdist/m4/pdns_with_libcap.m4 b/pdns/dnsdistdist/m4/pdns_with_libcap.m4 new file mode 120000 index 000000000..bf9aef73a --- /dev/null +++ b/pdns/dnsdistdist/m4/pdns_with_libcap.m4 @@ -0,0 +1 @@ +../../../m4/pdns_with_libcap.m4 \ No newline at end of file diff --git a/pdns/misc.cc b/pdns/misc.cc index 196a4bcf4..cd8842ed5 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -65,6 +65,10 @@ # include #endif +#ifdef HAVE_LIBCAP +#include +#endif + bool g_singleThreaded; size_t writen2(int fd, const void *buf, size_t count) @@ -1449,3 +1453,20 @@ std::vector getResolvers(const std::string& resolvConfPath) return results; } + +void dropCapabilities() +{ +#ifdef HAVE_LIBCAP + cap_t caps = cap_get_proc(); + if (caps != nullptr) { + cap_clear(caps); + + if (cap_set_proc(caps) != 0) { + cap_free(caps); + throw std::runtime_error("Unable to drop capabilities: " + std::string(strerror(errno))); + } + + cap_free(caps); + } +#endif /* HAVE_LIBCAP */ +} diff --git a/pdns/misc.hh b/pdns/misc.hh index fcf3c6a51..d4420dfa8 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -593,6 +593,7 @@ double DiffTime(const struct timespec& first, const struct timespec& second); double DiffTime(const struct timeval& first, const struct timeval& second); uid_t strToUID(const string &str); gid_t strToGID(const string &str); +void dropCapabilities(); unsigned int pdns_stou(const std::string& str, size_t * idx = 0, int base = 10);