3853. [cleanup] Refactor dns_rdataslab_fromrdataset to separate out
the handling of a rdataset with no records. [RT #35968]
+3851. [func] Allow libseccomp based system-call filtering
+ on Linux; use "configure --enable-seccomp" to
+ turn it on. Thanks to Loganaden Velvindron for
+ the contribution. [RT #35347]
+
3850. [bug] Disabling forwarding could trigger a REQUIRE assertion.
[RT #35979]
--- /dev/null
+/*
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef NAMED_SECCOMP_H
+#define NAMED_SECCOMP_H 1
+
+/*! \file */
+
+#ifdef HAVE_LIBSECCOMP
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <seccomp.h>
+#include <isc/platform.h>
+
+/*%
+ * For each architecture, the scmp_syscalls and
+ * scmp_syscall_names arrays MUST be kept in sync.
+ */
+#ifdef __x86_64__
+int scmp_syscalls[] = {
+ SCMP_SYS(access),
+ SCMP_SYS(open),
+ SCMP_SYS(clock_gettime),
+ SCMP_SYS(time),
+ SCMP_SYS(read),
+ SCMP_SYS(write),
+ SCMP_SYS(close),
+ SCMP_SYS(brk),
+ SCMP_SYS(poll),
+ SCMP_SYS(select),
+ SCMP_SYS(madvise),
+ SCMP_SYS(mmap),
+ SCMP_SYS(munmap),
+ SCMP_SYS(exit_group),
+ SCMP_SYS(rt_sigprocmask),
+ SCMP_SYS(rt_sigaction),
+ SCMP_SYS(fsync),
+ SCMP_SYS(rt_sigreturn),
+ SCMP_SYS(setsid),
+ SCMP_SYS(chdir),
+ SCMP_SYS(futex),
+ SCMP_SYS(stat),
+ SCMP_SYS(rt_sigsuspend),
+ SCMP_SYS(fstat),
+ SCMP_SYS(epoll_ctl),
+ SCMP_SYS(gettimeofday),
+ SCMP_SYS(unlink),
+ SCMP_SYS(socket),
+ SCMP_SYS(sendto),
+#ifndef ISC_PLATFORM_USETHREADS
+ SCMP_SYS(bind),
+ SCMP_SYS(accept),
+ SCMP_SYS(connect),
+ SCMP_SYS(listen),
+ SCMP_SYS(fcntl),
+ SCMP_SYS(sendmsg),
+ SCMP_SYS(recvmsg),
+ SCMP_SYS(uname),
+ SCMP_SYS(setrlimit),
+ SCMP_SYS(getrlimit),
+ SCMP_SYS(setsockopt),
+ SCMP_SYS(getsockopt),
+ SCMP_SYS(getsockname),
+ SCMP_SYS(lstat),
+ SCMP_SYS(lseek),
+ SCMP_SYS(getgid),
+ SCMP_SYS(getegid),
+ SCMP_SYS(getuid),
+ SCMP_SYS(geteuid),
+ SCMP_SYS(setresgid),
+ SCMP_SYS(setresuid),
+ SCMP_SYS(setgid),
+ SCMP_SYS(setuid),
+ SCMP_SYS(prctl),
+ SCMP_SYS(epoll_wait),
+ SCMP_SYS(openat),
+ SCMP_SYS(getdents),
+ SCMP_SYS(rename),
+ SCMP_SYS(utimes),
+ SCMP_SYS(dup),
+#endif
+};
+const char *scmp_syscall_names[] = {
+ "access",
+ "open",
+ "clock_gettime",
+ "time",
+ "read",
+ "write",
+ "close",
+ "brk",
+ "poll",
+ "select",
+ "madvise",
+ "mmap",
+ "munmap",
+ "exit_group",
+ "rt_sigprocmask",
+ "rt_sigaction",
+ "fsync",
+ "rt_sigreturn",
+ "setsid",
+ "chdir",
+ "futex",
+ "stat",
+ "rt_sigsuspend",
+ "fstat",
+ "epoll_ctl",
+ "gettimeofday",
+ "unlink",
+ "socket",
+ "sendto",
+#ifndef ISC_PLATFORM_USETHREADS
+ "bind",
+ "accept",
+ "connect",
+ "listen",
+ "fcntl",
+ "sendmsg",
+ "recvmsg",
+ "uname",
+ "setrlimit",
+ "getrlimit",
+ "setsockopt",
+ "getsockopt",
+ "getsockname",
+ "lstat",
+ "lseek",
+ "getgid",
+ "getegid",
+ "getuid",
+ "geteuid",
+ "setresgid",
+ "setresuid",
+ "setgid",
+ "setuid",
+ "prctl",
+ "epoll_wait",
+ "openat",
+ "getdents",
+ "rename",
+ "utimes",
+ "dup",
+#endif
+};
+#endif /* __x86_64__ */
+#ifdef __i386__
+int scmp_syscalls[] = {
+ SCMP_SYS(access),
+ SCMP_SYS(open),
+ SCMP_SYS(clock_gettime),
+ SCMP_SYS(time),
+ SCMP_SYS(read),
+ SCMP_SYS(write),
+ SCMP_SYS(close),
+ SCMP_SYS(brk),
+ SCMP_SYS(poll),
+ SCMP_SYS(_newselect),
+ SCMP_SYS(select),
+ SCMP_SYS(madvise),
+ SCMP_SYS(mmap2),
+ SCMP_SYS(mmap),
+ SCMP_SYS(munmap),
+ SCMP_SYS(exit_group),
+ SCMP_SYS(rt_sigprocmask),
+ SCMP_SYS(sigprocmask),
+ SCMP_SYS(rt_sigaction),
+ SCMP_SYS(socketcall),
+ SCMP_SYS(fsync),
+ SCMP_SYS(sigreturn),
+ SCMP_SYS(setsid),
+ SCMP_SYS(chdir),
+ SCMP_SYS(futex),
+ SCMP_SYS(stat64),
+ SCMP_SYS(rt_sigsuspend),
+ SCMP_SYS(fstat64),
+ SCMP_SYS(epoll_ctl),
+ SCMP_SYS(gettimeofday),
+ SCMP_SYS(unlink),
+#ifndef ISC_PLATFORM_USETHREADS
+ SCMP_SYS(fcntl64),
+#endif
+};
+const char *scmp_syscall_names[] = {
+ "access",
+ "open",
+ "clock_gettime",
+ "time",
+ "read",
+ "write",
+ "close",
+ "brk",
+ "poll",
+ "_newselect",
+ "select",
+ "madvise",
+ "mmap2",
+ "mmap",
+ "munmap",
+ "exit_group",
+ "rt_sigprocmask",
+ "sigprocmask",
+ "rt_sigaction",
+ "socketcall",
+ "fsync",
+ "sigreturn",
+ "setsid",
+ "chdir",
+ "futex",
+ "stat64",
+ "rt_sigsuspend",
+ "fstat64",
+ "epoll_ctl",
+ "gettimeofday",
+ "unlink",
+#ifndef ISC_PLATFORM_USETHREADS
+ "fcntl64",
+#endif
+};
+#endif /* __i386__ */
+#endif /* HAVE_LIBSECCOMP */
+
+#endif /* NAMED_SECCOMP_H */
#include <named/server.h>
#include <named/lwresd.h>
#include <named/main.h>
+#include <named/seccomp.h>
#ifdef HAVE_LIBSCF
#include <named/ns_smf_globals.h>
#endif
}
}
+#ifdef HAVE_LIBSECCOMP
+static void
+setup_seccomp() {
+ scmp_filter_ctx ctx;
+ unsigned int i;
+ int ret;
+
+ /* Make sure the lists are in sync */
+ INSIST((sizeof(scmp_syscalls) / sizeof(int)) ==
+ (sizeof(scmp_syscall_names) / sizeof(const char *)));
+
+ ctx = seccomp_init(SCMP_ACT_KILL);
+ if (ctx == NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN, ISC_LOG_WARNING,
+ "libseccomp activation failed");
+ return;
+ }
+
+ for (i = 0 ; i < sizeof(scmp_syscalls)/sizeof(*(scmp_syscalls)); i++) {
+ ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW,
+ scmp_syscalls[i], 0);
+ if (ret < 0)
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN, ISC_LOG_WARNING,
+ "libseccomp rule failed: %s",
+ scmp_syscall_names[i]);
+
+ else
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(9),
+ "added libseccomp rule: %s",
+ scmp_syscall_names[i]);
+ }
+
+ ret = seccomp_load(ctx);
+ if (ret < 0) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN, ISC_LOG_WARNING,
+ "libseccomp unable to load filter");
+ } else {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN, ISC_LOG_NOTICE,
+ "libseccomp sandboxing active");
+ }
+
+ /*
+ * Release filter in ctx. Filters already loaded are not
+ * affected.
+ */
+ seccomp_release(ctx);
+}
+#endif /* HAVE_LIBSECCOMP */
+
static void
setup(void) {
isc_result_t result;
#endif
ns_server_create(ns_g_mctx, &ns_g_server);
+
+#ifdef HAVE_LIBSECCOMP
+ setup_seccomp();
+#endif /* HAVE_LIBSECCOMP */
}
static void
/* Define to 1 if you have the `scf' library (-lscf). */
#undef HAVE_LIBSCF
+/* Define to use libseccomp system call filtering. */
+#undef HAVE_LIBSECCOMP
+
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
enable_libtool_lock
enable_libbind
enable_developer
+enable_seccomp
with_python
enable_kqueue
enable_epoll
--disable-libtool-lock avoid locking (might break parallel builds)
--enable-libbind deprecated
--enable-developer enable developer build settings
+ --enable-seccomp enable support for libseccomp sysstem call filtering
+ [default=no]
--enable-kqueue use BSD kqueue when available [default=yes]
--enable-epoll use Linux epoll when available [default=auto]
--enable-devpoll use /dev/poll when available [default=yes]
test "${enable_sit+set}" = set || enable_sit=yes
;;
esac
+
+#libseccomp sandboxing
+# Check whether --enable-seccomp was given.
+if test "${enable_seccomp+set}" = set; then :
+ enableval=$enable_seccomp;
+fi
+
+case "$enable_seccomp" in
+ yes)
+ case $host_os in
+ linux*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: seccomp is not supported on non-linux platforms; disabling it" >&5
+$as_echo "$as_me: WARNING: seccomp is not supported on non-linux platforms; disabling it" >&2;}
+ enable_seccomp=no
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing seccomp_init" >&5
+$as_echo_n "checking for library containing seccomp_init... " >&6; }
+if ${ac_cv_search_seccomp_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char seccomp_init ();
+int
+main ()
+{
+return seccomp_init ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' seccomp; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_seccomp_init=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_seccomp_init+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_seccomp_init+:} false; then :
+
+else
+ ac_cv_search_seccomp_init=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_seccomp_init" >&5
+$as_echo "$ac_cv_search_seccomp_init" >&6; }
+ac_res=$ac_cv_search_seccomp_init
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ if test "$ac_cv_search_seccomp_init" = "-lseccomp" ; then
+ if test "$cross_compiling" = yes; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <sys/prctl.h>
+ #include <linux/seccomp.h>
+
+ int main(void)
+ {
+ int ret;
+
+ ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);
+ if (ret < 0) {
+ switch (errno) {
+ case ENOSYS:
+ return 1;
+ case EINVAL:
+ return 1;
+ default:
+ return 1;
+ }
+ }
+ ret =
+ prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
+ if (ret < 0) {
+ switch (errno) {
+ case EINVAL:
+ return 1;
+ case EFAULT:
+ return 0;
+ default:
+ return 1;
+ }
+ }
+ return 1;
+ }
+
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+$as_echo "#define HAVE_LIBSECCOMP 1" >>confdefs.h
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+ ;;
+ *)
+ ;;
+esac
+
#
# Make very sure that these are the first files processed by
# config.status, since we use the processed output as the input for
echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)"
test "$enable_filter" = "yes" && \
echo " AAAA filtering (--enable-filter-aaaa)"
+test "$enable_seccomp" = yes && \
+ echo " Use libseccomp system call filtering (--enable-seccomp)"
test "$want_backtrace" = "yes" && \
echo " Print backtrace on crash (--enable-backtrace)"
test "$want_symtable" = "minimal" && \
test "X$CRYPTO" = "X" -o "$OPENSSL_ECDSA" = "yes" -o "$PKCS11_ECDSA" = "yes" || \
echo " ECDSA algorithm support (--with-ecdsa)"
+test "$enable_seccomp" = yes || \
+ echo " Use libseccomp system call filtering (--enable-seccomp)"
test "$want_backtrace" = "yes" || \
echo " Print backtrace on crash (--enable-backtrace)"
test "$use_libtool" = "yes" || echo " Use GNU libtool (--with-libtool)"
test "${enable_sit+set}" = set || enable_sit=yes
;;
esac
+
+#libseccomp sandboxing
+AC_ARG_ENABLE(seccomp,
+ AS_HELP_STRING([--enable-seccomp],[enable support for libseccomp sysstem call filtering [default=no]]))
+case "$enable_seccomp" in
+ yes)
+ case $host_os in
+ linux*)
+ ;;
+ *)
+ AC_MSG_WARN([seccomp is not supported on non-linux platforms; disabling it])
+ enable_seccomp=no
+ ;;
+ esac
+ AC_SEARCH_LIBS(seccomp_init, [seccomp])
+ if test "$ac_cv_search_seccomp_init" = "-lseccomp" ; then
+ AC_TRY_RUN([
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <sys/prctl.h>
+ #include <linux/seccomp.h>
+
+ int main(void)
+ {
+ int ret;
+
+ ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);
+ if (ret < 0) {
+ switch (errno) {
+ case ENOSYS:
+ return 1;
+ case EINVAL:
+ return 1;
+ default:
+ return 1;
+ }
+ }
+ ret =
+ prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
+ if (ret < 0) {
+ switch (errno) {
+ case EINVAL:
+ return 1;
+ case EFAULT:
+ return 0;
+ default:
+ return 1;
+ }
+ }
+ return 1;
+ }
+ ]
+ , AC_DEFINE([HAVE_LIBSECCOMP], 1,
+ [Define to use libseccomp system call filtering.])
+ , []
+ )
+ fi
+ ;;
+ *)
+ ;;
+esac
+
#
# Make very sure that these are the first files processed by
# config.status, since we use the processed output as the input for
echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)"
test "$enable_filter" = "yes" && \
echo " AAAA filtering (--enable-filter-aaaa)"
+test "$enable_seccomp" = yes && \
+ echo " Use libseccomp system call filtering (--enable-seccomp)"
test "$want_backtrace" = "yes" && \
echo " Print backtrace on crash (--enable-backtrace)"
test "$want_symtable" = "minimal" && \
test "X$CRYPTO" = "X" -o "$OPENSSL_ECDSA" = "yes" -o "$PKCS11_ECDSA" = "yes" || \
echo " ECDSA algorithm support (--with-ecdsa)"
+test "$enable_seccomp" = yes || \
+ echo " Use libseccomp system call filtering (--enable-seccomp)"
test "$want_backtrace" = "yes" || \
echo " Print backtrace on crash (--enable-backtrace)"
test "$use_libtool" = "yes" || echo " Use GNU libtool (--with-libtool)"