Commit add40469 authored by Colin Walters's avatar Colin Walters

Drop -newnet variant

This was just a hack which worked around a RHEL6 kernel bug.  I no
longer care about RHEL6; linux-user-chroot is now just RHEL7 only.
parent 9e8f2ee9
...@@ -25,12 +25,6 @@ linux_user_chroot_SOURCES = \ ...@@ -25,12 +25,6 @@ linux_user_chroot_SOURCES = \
linux_user_chroot_CFLAGS = $(AM_CFLAGS) $(LIBSECCOMP_CFLAGS) linux_user_chroot_CFLAGS = $(AM_CFLAGS) $(LIBSECCOMP_CFLAGS)
linux_user_chroot_LDFLAGS = $(LIBSECCOMP_LIBS) linux_user_chroot_LDFLAGS = $(LIBSECCOMP_LIBS)
if BUILD_NEWNET_HELPER
bin_PROGRAMS += linux-user-chroot-newnet
endif
linux_user_chroot_newnet_SOURCES = src/linux-user-chroot-newnet.c
linux_user_chroot_newnet_CFLAGS = $(AM_CFLAGS) linux_user_chroot_newnet_CFLAGS = $(AM_CFLAGS)
if BUILD_DOCUMENTATION if BUILD_DOCUMENTATION
......
newnet helper
-------------
This is an optional helper program that simply allows calling
CLONE_NEWNET and executing a child process. The reason this program
exists as an option is because on some Linux kernel configurations
(e.g. with the netfilter kernel module loaded), it's expensive to
create new network namespaces, and it may actually fail.
linux-user-chroot is intended to create namespaces quite dynamically,
but this conflicts somewhat with the goals of the developers who
contributed the functionality for typically more static "containers".
If you don't need this helper as a workaround, don't build it.
Caveat
------
This helper program does NOT restrict further execution of setuid
binaries. Otherwise, you couldn't run linux-user-chroot inside of it,
and that would defeat the point.
However I don't believe the attack surface exposed by making an empty
network namespace is very high - it does mean that e.g. one could make
"sudo" fail to look up the username if it's configured to use LDAP.
But most setuid programs *should* be carefully checking errors
anyways.
Building
--------
To enable building this helper, pass --enable-newnet-helper to
configure.
Running
-------
$ linux-user-chroot-newnet curl http://google.com
curl: (6) Could not resolve host: google.com; Unknown error
$ linux-user-chroot-newnet /bin/bash
$ # you're now in a shell without networking
...@@ -34,12 +34,6 @@ AC_ARG_ENABLE(documentation, ...@@ -34,12 +34,6 @@ AC_ARG_ENABLE(documentation,
enable_documentation=yes) enable_documentation=yes)
AM_CONDITIONAL(BUILD_DOCUMENTATION, test x$enable_documentation = xyes) AM_CONDITIONAL(BUILD_DOCUMENTATION, test x$enable_documentation = xyes)
AC_ARG_ENABLE(newnet-helper,
AC_HELP_STRING([--enable-newnet-helper],
[build newnet helper (see README.newnet)]),,
enable_newnet_helper=no)
AM_CONDITIONAL(BUILD_NEWNET_HELPER, test x$enable_newnet_helper = xyes)
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile
]) ])
......
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil -*-
*
* newnet-suid: Allow allocating a new empty network namespace as
* non-root. This program is just a workaround for the kernel
* requiring large-order allocations (e.g. 4 pages) per network
* namespace.
*
* Copyright 2012 Colin Walters <walters@verbum.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it would be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <sched.h>
static void fatal (const char *message, ...) __attribute__ ((noreturn)) __attribute__ ((format (printf, 1, 2)));
static void fatal_errno (const char *message) __attribute__ ((noreturn));
static void
fatal (const char *fmt,
...)
{
va_list args;
va_start (args, fmt);
vfprintf (stderr, fmt, args);
putc ('\n', stderr);
va_end (args);
exit (1);
}
static void
fatal_errno (const char *message)
{
perror (message);
exit (1);
}
int
main (int argc,
char **argv)
{
const char *program;
uid_t ruid, euid, suid;
gid_t rgid, egid, sgid;
char **program_argv;
int child_status = 0;
pid_t child;
if (argc <= 0)
return 1;
argc--;
argv++;
if (argc < 1)
fatal ("PROGRAM [ARGS]... Run PROGRAM in an isolated network namespace");
program = argv[0];
program_argv = argv;
if (getresgid (&rgid, &egid, &sgid) < 0)
fatal_errno ("getresgid");
if (getresuid (&ruid, &euid, &suid) < 0)
fatal_errno ("getresuid");
if (rgid == 0)
rgid = ruid;
if ((child = syscall (__NR_clone, SIGCHLD | CLONE_NEWNET, NULL)) < 0)
perror ("clone");
if (child == 0)
{
/* Switch back to the uid of our invoking process. These calls are
* irrevocable - see setuid(2) */
if (setgid (rgid) < 0)
fatal_errno ("setgid");
if (setuid (ruid) < 0)
fatal_errno ("setuid");
if (execvp (program, program_argv) < 0)
fatal_errno ("execv");
}
/* Let's also setuid back in the parent - there's no reason to stay uid 0, and
* it's just better to drop privileges. */
if (setgid (rgid) < 0)
fatal_errno ("setgid");
if (setuid (ruid) < 0)
fatal_errno ("setuid");
/* Kind of lame to sit around blocked in waitpid, but oh well. */
if (waitpid (child, &child_status, 0) < 0)
fatal_errno ("waitpid");
if (WIFEXITED (child_status))
return WEXITSTATUS (child_status);
else
return 1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment