From patchwork Fri Dec 30 11:56:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 89333 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp6405705qgi; Fri, 30 Dec 2016 03:56:51 -0800 (PST) X-Received: by 10.84.136.1 with SMTP id 1mr98685262plk.152.1483099011454; Fri, 30 Dec 2016 03:56:51 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 68si56720424pga.8.2016.12.30.03.56.51 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Dec 2016 03:56:51 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-76430-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-76430-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-76430-patch=linaro.org@sourceware.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:to:references:cc:from:message-id:date :mime-version:in-reply-to:content-type; q=dns; s=default; b=vIg7 jktHyoee5U3hEUmtbcOtTTLXRLU2UG62woSH8QhtFfzJJZFn6GOBlAHxFPaUc5wy kNO1v6IYgOTUaYTLi7y6gd5t50HdivE5raVd7LHaM9rk8GKsjV411jj81TvZwqAV 4/NQSM/RPogMBM/GTwR9Uq28mAQfYq/eSLzxskE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:to:references:cc:from:message-id:date :mime-version:in-reply-to:content-type; s=default; bh=aJKFGaGTfd 4Qxmn6t4oM9fNL4V8=; b=f+9tOe8qFRAji4yWGIiHbRYJVZLS56TaThRFAnc0Q9 N4Bk+iUaaOjdiKbEHnv3aNcPv2nyjb6+82frPlDjRwvMNC69UbYv0xAstP77j9Nk LOTnBdVoPWJbx0Haeno1TFHxuMp3GJ2rCiKwmBPQZjw+XDSQjNgdrZNVqfVNqi4A 4= Received: (qmail 94757 invoked by alias); 30 Dec 2016 11:56:40 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 94748 invoked by uid 89); 30 Dec 2016 11:56:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-5.1 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Enter, networking, GID, UID X-HELO: mx1.redhat.com Subject: Re: Testing on hosts with firewalls To: Andreas Schwab References: <20161229180613.GD16617@vapier> <7f8dad7f-ecb3-675a-f45b-16887dbc4f4e@redhat.com> <20161229233516.GF16617@vapier> <87r34psr46.fsf@linux-m68k.org> <882d8a9c-9017-b427-f023-96e3f9053958@redhat.com> <87k2ahsn9u.fsf@linux-m68k.org> Cc: GNU C Library From: Florian Weimer Message-ID: Date: Fri, 30 Dec 2016 12:56:26 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: <87k2ahsn9u.fsf@linux-m68k.org> On 12/30/2016 11:51 AM, Andreas Schwab wrote: > On Dez 30 2016, Florian Weimer wrote: > >> If this is a current upstream kernel with user namespaces enabled, I would >> be worried, though. > > $ zgrep USER_NS /proc/config.gz > CONFIG_USER_NS=y > $ uname -r > 4.9.0-2.g6fbc0c0-default Hmm. It turns out that the UID/GID mapping is not required. Using Mike's ioctls, I could bring up the loopback interface within an unmodified user namespace (created by an unprivileged user). I'm now testing the attached patch. It should use network namespaces even on kernels which lack user namespace support, as long as the tests are run as root. Thanks, Florian support: Helper functions for entering namespaces 2016-12-30 Florian Weimer * support/namespace.h: New file. * support/support_become_root.c: Likewise. * support/support_enter_network_namespace.c: Likewise. * support/tst-support-namespace.c: Likewise. * support/xsocket.c: Likewise. * support/xsocket.h: Likewise. * support/Makefile (libsupport-routines): Add support_become_root, support_enter_network_namespace, xsocket. (tests): Add tst-support-namespace. diff --git a/support/Makefile b/support/Makefile index 1bde8bd..8e3b89d 100644 --- a/support/Makefile +++ b/support/Makefile @@ -30,6 +30,8 @@ libsupport-routines = \ ignore_stderr \ oom_error \ set_fortify_handler \ + support_become_root \ + support_enter_network_namespace \ support_record_failure \ support_test_main \ support_test_verify_impl \ @@ -54,6 +56,7 @@ libsupport-routines = \ xpthread_spin_lock \ xpthread_spin_unlock \ xrealloc \ + xsocket \ xwaitpid \ libsupport-static-only-routines := $(libsupport-routines) @@ -65,6 +68,7 @@ endif tests = \ README-testing \ + tst-support-namespace \ tst-support_record_failure \ tests-special = \ diff --git a/support/namespace.h b/support/namespace.h new file mode 100644 index 0000000..ba0229f --- /dev/null +++ b/support/namespace.h @@ -0,0 +1,48 @@ +/* Entering namespaces for test case isolation. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef SUPPORT_NAMESPACE_H +#define SUPPORT_NAMESPACE_H + +#include +#include + +__BEGIN_DECLS + +/* Attempts to become root (or acquire root-like privileges), possibly + with the help of user namespaces. Return true if (restricted) root + privileges could be attained in some way. Print diagnostics to + standard output. */ +bool support_become_root (void); + +/* Enter a network namespace (and a UTS namespace if possible) and + configure the loopback interface. Return true if a network + namespace could be created. Print diagnostics to standard output. + If a network namespace could be created, but networking in it could + not be configured, terminate the process. It is recommended to + call support_become_root before this function so that the process + has sufficient privileges. */ +bool support_enter_network_namespace (void); + +/* Return true if support_enter_network_namespace managed to enter a + UTS namespace. */ +bool support_in_uts_namespace (void); + +__END_DECLS + +#endif diff --git a/support/support_become_root.c b/support/support_become_root.c new file mode 100644 index 0000000..d13954c --- /dev/null +++ b/support/support_become_root.c @@ -0,0 +1,40 @@ +/* Acquire root privileges. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#include +#include +#include + +bool +support_become_root (void) +{ +#ifdef CLONE_NEWUSER + if (unshare (CLONE_NEWUSER | CLONE_NEWNS) == 0) + /* Even if we do not have UID zero, we have extended privileges at + this point. */ + return true; +#endif + if (setuid (0) != 0) + { + printf ("warning: could not become root outside namespace (%m)\n"); + return false; + } + return true; +} diff --git a/support/support_enter_network_namespace.c b/support/support_enter_network_namespace.c new file mode 100644 index 0000000..3af18e6 --- /dev/null +++ b/support/support_enter_network_namespace.c @@ -0,0 +1,74 @@ +/* Enter a network namespace. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static bool in_uts_namespace; + +bool +support_enter_network_namespace (void) +{ +#ifdef CLONE_NEWUTS + if (unshare (CLONE_NEWUTS) == 0) + in_uts_namespace = true; + else + printf ("warning: unshare (CLONE_NEWUTS) failed: %m\n"); +#endif + +#ifdef CLONE_NEWNET + if (unshare (CLONE_NEWNET) == 0) + { + /* Bring up the loopback interface. */ + int fd = xsocket (AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); + struct ifreq req; + strcpy (req.ifr_name, "lo"); + TEST_VERIFY_EXIT (ioctl (fd, SIOCGIFFLAGS, &req) == 0); + bool already_up = req.ifr_flags & IFF_UP; + if (already_up) + /* This means that we likely have not achieved isolation from + the parent namespace. */ + printf ("warning: loopback interface already exists" + " in new network namespace\n"); + else + { + req.ifr_flags |= IFF_UP | IFF_RUNNING; + TEST_VERIFY_EXIT (ioctl (fd, SIOCSIFFLAGS, &req) == 0); + } + close (fd); + + return !already_up; + } +#endif + printf ("warning: could not enter network namespace\n"); + return false; +} + +bool +support_in_uts_namespace (void) +{ + return in_uts_namespace; +} diff --git a/support/tst-support-namespace.c b/support/tst-support-namespace.c new file mode 100644 index 0000000..bd2a2a6 --- /dev/null +++ b/support/tst-support-namespace.c @@ -0,0 +1,34 @@ +/* Test entering namespaces. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static int +do_test (void) +{ + if (support_become_root ()) + printf ("info: acquired root-like privileges\n"); + if (support_enter_network_namespace ()) + printf ("info: entered network namespace\n"); + if (support_in_uts_namespace ()) + printf ("info: also entered UTS namespace\n"); + return 0; +} + +#include diff --git a/support/xsocket.c b/support/xsocket.c new file mode 100644 index 0000000..9ebe63f --- /dev/null +++ b/support/xsocket.c @@ -0,0 +1,36 @@ +/* socket with error checking. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#include +#include +#include + +int +xsocket (int domain, int type, int protocol) +{ + int fd = socket (domain, type, protocol); + if (fd < 0) + { + support_record_failure (); + printf ("error: socket (%d, %d, %d): %m\n", domain, type, protocol); + exit (1); + } + return fd; +} diff --git a/support/xsocket.h b/support/xsocket.h new file mode 100644 index 0000000..e9ff49e --- /dev/null +++ b/support/xsocket.h @@ -0,0 +1,27 @@ +/* Error-checking wrappers for socket functions. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef SUPPORT_XSOCKET_H +#define SUPPORT_XSOCKET_H + +#include +#include + +int xsocket (int, int, int); + +#endif /* SUPPORT_XSOCKET_H */