MIME-Version: 1.0 X-Authentication-Warning: mx.elandsys.com: logan set sender to logan@elandsys.com using -f In-Reply-To: X-Spam-Status: No, score=-1.0 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,RP_MATCHES_RCVD,URIBL_BLACK autolearn=no version=3.3.1 Content-Disposition: inline References: <20140111071407.GA5742@mx.elandsys.com> Message-ID: <20140214041111.GA4946@mx.elandsys.com> Content-Type: text/plain; charset="utf-8" X-RT-Original-Encoding: utf-8 Authentication-Results: mx.pao1.isc.org; dkim=pass reason="1024-bit key; insecure key" header.d=opendkim.org header.i=@opendkim.org header.b=bsmQcODC; dkim-adsp=pass Received: from mx.pao1.isc.org (mx.pao1.isc.org [149.20.64.53]) by bugs.isc.org (Postfix) with ESMTP id 909C82D20051 for ; Fri, 14 Feb 2014 04:11:34 +0000 (UTC) Received: from mx.pao1.isc.org (localhost [127.0.0.1]) by mx.pao1.isc.org (Postfix) with ESMTP id 7C632C948E for ; Fri, 14 Feb 2014 04:11:20 +0000 (UTC) (envelope-from logan@elandsys.com) Received: from mx.ipv6.elandsys.com (mx.ipv6.elandsys.com [IPv6:2001:470:f329:1::1]) by mx.pao1.isc.org (Postfix) with ESMTP for ; Fri, 14 Feb 2014 04:11:20 +0000 (UTC) (envelope-from logan@elandsys.com) Received: from mx.elandsys.com (IDENT:logan@localhost [127.0.0.1]) by mx.elandsys.com (8.14.5/8.14.5) with ESMTP id s1E4BB6U014193 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 13 Feb 2014 20:11:19 -0800 (PST) Received: (from logan@localhost) by mx.elandsys.com (8.14.5/8.14.5/Submit) id s1E4BBZ4025206 for dhcp-bugs@isc.org; Thu, 13 Feb 2014 20:11:11 -0800 (PST) X-DCC-X.dcc-Servers-Metrics: post.isc.org 104; Body=1 Fuz1=1 Fuz2=1 Delivered-To: dhcp-bugs@bugs.isc.org Subject: Re: [ISC-Bugs #35184] isc-dhcpd sandboxing patch User-Agent: Mutt/1.5.21 (2010-09-15) Return-Path: Dkim-Signature: v=1; a=rsa-sha256; c=simple/simple; d=opendkim.org; s=mail2010; t=1392351079; bh=lDrXmtxvZVEfvzPMiVzcnagMo9Q9CZyZV0IbULYsBOU=; h=Date:From:To:Subject:References:In-Reply-To; b=bsmQcODCs8InLzv0/S6qXZH2nYlpdFXCyPCGzca5ofe913XeorCjpZyxM8+z+YLHq GB4+i/+UAzcz8jVwW5AWW7W1fbC5i3+Zgl4i3+AuKP9E1wy8rc2CLClZRJ18gLzD3q +EgKzCcWlo6I9+esOB9KMYR0mG0uIrwakZ7VGH2s= Dkim-Signature: v=1; a=rsa-sha256; c=simple/simple; d=elandsys.com; s=mail; t=1392351079; i=@elandsys.com; bh=lDrXmtxvZVEfvzPMiVzcnagMo9Q9CZyZV0IbULYsBOU=; h=Date:From:To:Subject:References:In-Reply-To; b=g4EqMiHVTJcXhbUVxiY02P/HQ9PUCkwOUWDKcN2DjZDB4NfrBW2kNYWNZ2dqiXb2F 5x47bhfcWotIUkjDcG+bd/iqM7OSjOnydqCjiS+aOgna8ctfVEi8O+q/P+noe5H8mU J8i0bjeOYquj1qor/8M/MmlktojamNuLscbz/Ztc= X-Original-To: dhcp-bugs@bugs.isc.org Date: Thu, 13 Feb 2014 20:11:11 -0800 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mx.pao1.isc.org To: Michael McNally via RT From: Loganaden Velvindron RT-Message-ID: Content-Length: 7534 On Thu, Jan 23, 2014 at 06:07:14PM +0000, Michael McNally via RT wrote: > On Sat Jan 11 07:14:25 2014, logan@elandsys.com wrote: > > Dear Jeremy and ISC team, > > > > I'm currently running with isc-dhcpd sandboxed on Production Ubuntu > > servers. > > > > The patch restricts dhcpd to a small number of whitelisted C functions > > using > > seccomp. OpenSSH and systemd ship with a similar sandbox on Linux. > > > > This prevents exploits that use execve() and such. > > > > If there is interest in such a patch, I'm willing to improve it futher > > based on the feedback I get from ISC. > > Hello. > > Thank you for your patch, and apologies for the slow response -- > our DHCP team has been very busy putting the finishing touches > on DHCP 4.3.0 and new maintenance versions of 4.2.x and 4.1-ESV. > > Your patch looks interesting and will be forwarded to the development > team for assessment, but probably will not receive scrutiny until after > the release schedules currently in process are completed. Thank you very much ! > > Thank you, though, for your submission and for your efforts to help > us improve ISC DHCP. You're most welcomed. > > Michael McNally > ISC Support > We've improved the diff further by testing it on 64-bit ubuntu servers running in production. Diff below: diff --git a/configure.ac b/configure.ac index a14366d..40a0cf0 100644 --- a/configure.ac +++ b/configure.ac @@ -145,6 +145,17 @@ if test "$enable_early_chroot" = "yes" ; then [Define to any value to chroot() prior to loading config.]) fi +# LIBSECCOMP is off by default -- needs testing with all the features +AC_ARG_ENABLE(libseccomp, + AS_HELP_STRING([--enable-libseccomp],[enable support for libseccomp sandboxing (default is no)])) +if test "$enable_libseccomp" = "yes" ; then + AC_SEARCH_LIBS(seccomp_init, [seccomp]) + if test "$ac_cv_search_seccomp_init" = "-lseccomp" ; then + AC_DEFINE([LIBSECCOMP], [1], + [Define to any value to include libseccomp sandboxing.]) + fi +fi + AC_ARG_ENABLE(ipv4_pktinfo, AS_HELP_STRING([--enable-ipv4-pktinfo],[enable use of pktinfo on IPv4 sockets (default is no)])) diff --git a/server/dhcpd.c b/server/dhcpd.c index a06913e..db00003 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -52,6 +52,12 @@ static const char url [] = # undef group #endif /* PARANOIA */ +#if defined (LIBSECCOMP) +#include +#include +#include +#endif /* LIBSECCOMP */ + #ifndef UNIT_TEST static void usage(void); #endif @@ -740,6 +746,93 @@ main(int argc, char **argv) { } } +#if defined (LIBSECCOMP) + scmp_filter_ctx ctx; + if ((ctx = seccomp_init(SCMP_ACT_KILL)) < 0) + log_fatal("%s:libseccomp activation failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpid), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(gettimeofday), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(clock_gettime), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#ifdef __NR_time /* not defined on EABI ARM */ + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#endif + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(poll), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#ifdef __NR__newselect + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(_newselect), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#else + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(select), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#endif + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(madvise), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#ifdef __NR_mmap2 /* EABI ARM only has mmap2() */ + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#endif +#ifdef __NR_mmap + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#endif + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#ifdef __NR_rt_sigprocmask + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#else + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sigprocmask), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#endif + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fsync), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#ifdef __NR_sigreturn + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sigreturn), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#else + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#endif + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsid), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chdir), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#ifdef __NR_socketcall + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall), 0) < 0) + log_fatal("%s:libseccomp rule failed", __func__); +#endif +#ifdef __NR_sendto /* x86_64 */ + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sendto), 0) <0) + log_fatal("%s:libseccomp rule failed", __func__); +#endif +#ifdef __NR_recvfrom /* x86_64 */ + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(recvfrom), 0) <0) + log_fatal("%s:libseccomp rule failed", __func__); +#endif + + if (seccomp_load(ctx) < 0) + log_fatal("%s:libseccomp unable to load filter", __func__); +#endif /* LIBSECCOMP */ + /* If we were requested to log to stdout on the command line, keep doing so; otherwise, stop. */ if (log_perror == -1) @@ -783,6 +876,7 @@ main(int argc, char **argv) { /* Log that we are about to start working */ log_info("Server starting service."); + /* * Receive packets and dispatch them... * dispatch() will never return.