CC: bind9-bugs@isc.org MIME-Version: 1.0 X-Spam-Status: No, score=-3.3 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD autolearn=ham autolearn_force=no version=3.4.0 In-Reply-To: <53F36A3B.1000109@redhat.com> X-Mailer: Zimbra 8.0.6_GA_5922 (ZimbraWebClient - GC36 (Linux)/8.0.6_GA_5922) References: <53F36A3B.1000109@redhat.com> Content-Type: text/plain; charset=utf-8 Message-ID: <1692671561.23269505.1408495501961.JavaMail.zimbra@redhat.com> Received: from mx.pao1.isc.org (mx.pao1.isc.org [149.20.64.53]) by bugs.isc.org (Postfix) with ESMTP id 97FDC2D20571 for ; Wed, 20 Aug 2014 00:45:05 +0000 (UTC) Received: from mx6-phx2.redhat.com (mx6-phx2.redhat.com [209.132.183.39]) by mx.pao1.isc.org (Postfix) with ESMTP id 4CA00349308 for ; Wed, 20 Aug 2014 00:45:03 +0000 (UTC) Received: from zmail23.collab.prod.int.phx2.redhat.com (zmail23.collab.prod.int.phx2.redhat.com [10.5.83.28]) by mx6-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s7K0j2iS027294; Tue, 19 Aug 2014 20:45:02 -0400 Delivered-To: bind9-bugs@bugs.isc.org Subject: Re: BIND 9.10.1 beta with seccomp functionality Return-Path: Thread-Index: 5FEQleH348lo6uvfEQzoC5CLq016gA== X-Original-To: bind9-bugs@bugs.isc.org Date: Tue, 19 Aug 2014 20:45:01 -0400 (EDT) Thread-Topic: BIND 9.10.1 beta with seccomp functionality X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mx.pao1.isc.org X-Originating-Ip: [10.5.82.7] To: secure-development@redhat.com Content-Transfer-Encoding: 7bit From: Andrew Griffiths X-RT-Original-Encoding: utf-8 Content-Length: 4240 Hello, bind Thought I'd take a look at how they implement this: for (i = 0 ; i < sizeof(scmp_syscalls)/sizeof(*(scmp_syscalls)); i++) { ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, scmp_syscalls[i], 0); So, it just whitelists the system calls allowed, and doesn't restrict arguments. Taking a look at the system calls allowed, there appears to be plenty of avenues for kernel exploits, such as x32 recvmsg(), futex() addr == addr2, and so on. While probably out of scope, it's something to think about when designing and/or retrofitting new security mechanisms onto existing codebases, and determining what your aims are. SCMP_SYS(open), SCMP_SYS(read), SCMP_SYS(write), SCMP_SYS(close), would allow for arbitrary file creation dependent upon permissions, since open() arguments are not restricted, or information disclosure in case of suitably readable files. (of course, chances are you're using chroot() which reduces the impact of this if you have seccomp enabled :-)) SCMP_SYS(socket), SCMP_SYS(sendto), The address family there could be restricted further to prevent arbitrary !ip modules being loaded, and possibly being used for mischievousness (such as NETLINK). #ifndef ISC_PLATFORM_USETHREADS is outright scary in bin/named/include/named/seccomp.h From looking at bin/named/main.c, we see that: setup() calls create_managers(), which in turns calls isc_taskmgr_create(), which in turn creates threads. At the end of setup(), it calls setup_seccomp(). setup_seccomp() is only called from main.c. Why's this a problem, you may be wondering? Threads share memory - if you have arbitrary code execution in a seccomp thread, it's trivial to break out by modifying a non-seccomp thread's execution by changing the return address or modifying the GOT, etc. Additionally, creating threads before changing user ids is problematic, depending on the operating systems and C libraries used. It might be worthwhile testing !linux and seeing what privilege levels the threads are running as if the operating system has per-thread credentials[0]. This will be a privilege escalation vulnerability in certain combinations. (bind9 under linux will reduce capabilities + setuid before creating threads, so it won't be affected, unless their is threads created before setup() is called). tl;dr: - seccomp implementation doesn't look like it applies to all threads. it general, it must, otherwise there is no point in using seccomp[1] - applying seccomp rules to all running threads may be possible via https://lkml.org/lkml/2014/7/10/538 .. but I would strongly recommend that all privilege dropping / process restriction is performed before creating threads, as it's the only portable to way to ensure that there aren't threads running with higher privileges, or running unrestricted. Perhaps having some test cases that inspect a system running bind to verify all suitable bind processes and threads are running as suitably reduced privilege levels / restrictions would prevent future recurrence of bugs like these. [0] https://bugs.launchpad.net/qemu/+bug/807893 (seems I looked it up at some stage, and FreeBSD and MacOSX does per-thread credentials). Various Linux distributions are vuln due to not using glibc. http://forums.grsecurity.net/viewtopic.php?f=7&t=2939 mentions grsecurity's approach to dealing with it (which incidentally mentions me as well..) [1] chrome uses a "trusted" thread to do system calls that require memory reads / validation. probably better performance than IPC overhead to a more privileged process, at a somewhat increased risk. Thanks, Andrew Griffiths ----- Original Message ----- > From: "Tomas Hozza" > To: tech-list@redhat.com, secure-development@redhat.com > Sent: Wednesday, August 20, 2014 1:16:11 AM > Subject: BIND 9.10.1 beta with seccomp functionality > > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Hello. > > ISC is working on new BIND 9.10 release which includes the seccomp > functionality which improves the security. It can be turned on by > configuring BIND before build with "--enable-seccomp". >