diff --git a/Makefile-libglnx.am b/Makefile-libglnx.am index e094ef67f271c318c8beb872033521b31623019e..a812755eeb2c80908723ed0c1e1b80b431db1f5f 100644 --- a/Makefile-libglnx.am +++ b/Makefile-libglnx.am @@ -35,8 +35,6 @@ libglnx_la_SOURCES = \ $(libglnx_srcpath)/glnx-fdio.c \ $(libglnx_srcpath)/glnx-lockfile.h \ $(libglnx_srcpath)/glnx-lockfile.c \ - $(libglnx_srcpath)/glnx-libcontainer.h \ - $(libglnx_srcpath)/glnx-libcontainer.c \ $(libglnx_srcpath)/glnx-missing-syscall.h \ $(libglnx_srcpath)/glnx-missing.h \ $(libglnx_srcpath)/glnx-xattrs.h \ diff --git a/README.md b/README.md index 50a5f90da0d43e073f2ddcdc51f0427b2f1fea58..241f5cef2315d92047418e8a27d7f28f01777a51 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ Features: - APIs also have a `GError` parameter - High level "shutil", somewhat inspired by Python's - A "console" API for tty output - - Some basic container utility functions - A backport of the GLib cleanup macros for projects which can't yet take a dependency on 2.40. diff --git a/glnx-libcontainer.c b/glnx-libcontainer.c deleted file mode 100644 index 6b9a2d640da365085f6635f0988da30315fb404b..0000000000000000000000000000000000000000 --- a/glnx-libcontainer.c +++ /dev/null @@ -1,313 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Portions derived from src/nspawn/nspawn.c: - * Copyright 2010 Lennart Poettering - * - * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org> - * - * This program 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 of the licence or (at - * your option) any later version. - * - * This 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 this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include <string.h> -#include <glib-unix.h> -#include <sys/mount.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <stdio.h> -#include <gio/gunixoutputstream.h> - -#include "glnx-libcontainer.h" -#include "glnx-dirfd.h" - -#include "glnx-backport-autocleanups.h" -#include "glnx-local-alloc.h" - -static void _perror_fatal (const char *message) __attribute__ ((noreturn)); - -static void -_perror_fatal (const char *message) -{ - perror (message); - exit (1); -} - -typedef enum { - CONTAINER_UNINIT = 0, - CONTAINER_YES = 1, - CONTAINER_NO = 2 -} ContainerDetectionState; - -static gboolean -currently_in_container (void) -{ - static gsize container_detected = CONTAINER_UNINIT; - - if (g_once_init_enter (&container_detected)) - { - ContainerDetectionState tmp_state = CONTAINER_NO; - struct stat stbuf; - - /* http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface/ */ - if (getenv ("container") != NULL - || stat ("/.dockerinit", &stbuf) == 0) - tmp_state = CONTAINER_YES; - /* But since Docker isn't on board, yet, so... - http://stackoverflow.com/questions/23513045/how-to-check-if-a-process-is-running-inside-docker-container */ - g_once_init_leave (&container_detected, tmp_state); - } - return container_detected == CONTAINER_YES; -} - -#if 0 -static gboolean -glnx_libcontainer_bind_mount_readonly (const char *path, GError **error) -{ - gboolean ret = FALSE; - - if (mount (path, path, NULL, MS_BIND | MS_PRIVATE, NULL) != 0) - { - int errsv = errno; - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "mount(%s, MS_BIND): %s", - path, - g_strerror (errsv)); - goto out; - } - if (mount (path, path, NULL, MS_BIND | MS_PRIVATE | MS_REMOUNT | MS_RDONLY, NULL) != 0) - { - int errsv = errno; - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "mount(%s, MS_BIND | MS_RDONLY): %s", - path, - g_strerror (errsv)); - goto out; - } - - ret = TRUE; - out: - return ret; -} -#endif - -/* Based on code from nspawn.c; assumes process cwd is the target */ -static int -glnx_libcontainer_make_api_mounts (void) -{ - typedef struct MountPoint { - const char *what; - const char *where; - const char *type; - const char *options; - unsigned long flags; - gboolean fatal; - } MountPoint; - - static const MountPoint mount_table[] = { - { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, TRUE }, - { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, TRUE }, /* Bind mount first */ - { NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, TRUE }, /* Then, make it r/o */ - { "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, TRUE }, - { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, TRUE }, - { "devpts", "/dev/pts", "devpts","newinstance,ptmxmode=0666,mode=620,gid=5", MS_NOSUID|MS_NOEXEC, TRUE }, - { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, TRUE }, - { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, TRUE }, - { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, FALSE }, /* Bind mount first */ - { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, FALSE }, /* Then, make it r/o */ - }; - - unsigned k; - - for (k = 0; k < G_N_ELEMENTS(mount_table); k++) - { - const char *where = mount_table[k].where; - int t; - - g_assert (where[0] == '/'); - where++; - - t = mkdir (where, 0755); - if (t < 0 && errno != EEXIST) - { - if (!mount_table[k].fatal) - continue; - return -1; - } - - if (mount (mount_table[k].what, - where, - mount_table[k].type, - mount_table[k].flags, - mount_table[k].options) < 0) - { - if (errno == ENOENT && !mount_table[k].fatal) - continue; - return -1; - } - } - - return 0; -} - -static int -glnx_libcontainer_prep_dev (const char *dest_devdir) -{ - glnx_fd_close int src_fd = -1; - glnx_fd_close int dest_fd = -1; - struct stat stbuf; - guint i; - static const char *const devnodes[] = { "null", "zero", "full", "random", "urandom", "tty" }; - - src_fd = openat (AT_FDCWD, "/dev", O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); - if (src_fd == -1) - return -1; - - dest_fd = openat (AT_FDCWD, dest_devdir, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); - if (dest_fd == -1) - return -1; - - for (i = 0; i < G_N_ELEMENTS (devnodes); i++) - { - const char *nodename = devnodes[i]; - - if (fstatat (src_fd, nodename, &stbuf, 0) == -1) - { - if (errno == ENOENT) - continue; - else - return -1; - } - - if (mknodat (dest_fd, nodename, stbuf.st_mode, stbuf.st_rdev) != 0) - return -1; - if (fchmodat (dest_fd, nodename, stbuf.st_mode, 0) != 0) - return -1; - } - - return 0; -} - -pid_t -glnx_libcontainer_run_chroot_at_private (int dfd, - const char *binary, - char **argv) -{ - /* Make most new namespaces; note our use of CLONE_NEWNET means we - * have no networking in the container root. - */ - const int cloneflags = - SIGCHLD | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | CLONE_SYSVSEM | CLONE_NEWUTS; - pid_t child; - gboolean in_container = currently_in_container (); - - if (!in_container) - { - if ((child = syscall (__NR_clone, cloneflags, NULL)) < 0) - return -1; - } - else - { - if ((child = fork ()) < 0) - return -1; - } - - if (child != 0) - return child; - - if (!in_container) - { - if (mount (NULL, "/", "none", MS_PRIVATE | MS_REC, NULL) != 0) - { - if (errno == EINVAL) - { - /* Ok, we may be inside a mock chroot or the like. In - * that case, let's just fall back to not - * containerizing. - */ - in_container = TRUE; - } - else - _perror_fatal ("mount: "); - } - - if (!in_container) - { - if (mount (NULL, "/", "none", MS_PRIVATE | MS_REMOUNT | MS_NOSUID, NULL) != 0) - _perror_fatal ("mount (MS_NOSUID): "); - } - } - - if (fchdir (dfd) != 0) - _perror_fatal ("fchdir: "); - - if (!in_container) - { - if (glnx_libcontainer_make_api_mounts () != 0) - _perror_fatal ("preparing api mounts: "); - - if (glnx_libcontainer_prep_dev ("dev") != 0) - _perror_fatal ("preparing /dev: "); - - if (mount (".", ".", NULL, MS_BIND | MS_PRIVATE, NULL) != 0) - _perror_fatal ("mount (MS_BIND)"); - - if (mount (".", "/", NULL, MS_MOVE, NULL) != 0) - _perror_fatal ("mount (MS_MOVE)"); - } - - if (chroot (".") != 0) - _perror_fatal ("chroot: "); - - if (chdir ("/") != 0) - _perror_fatal ("chdir: "); - - /* Environment variables like PATH in the end are distribution - * specific. The most correct thing would be to run through PAM, - * but that's a huge level of pain. We'd like to drive towards a - * standard /usr/bin (i.e. unified sbin too), but for now this is - * pretty compatible. - */ - setenv ("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 1); - - if (binary[0] == '/') - { - if (execv (binary, argv) != 0) - _perror_fatal ("execv: "); - } - else - { - if (execvp (binary, argv) != 0) - _perror_fatal ("execvp: "); - } - - g_assert_not_reached (); -} - -pid_t -glnx_libcontainer_run_chroot_private (const char *dest, - const char *binary, - char **argv) -{ - glnx_fd_close int dfd = -1; - - dfd = glnx_opendirat_with_errno (AT_FDCWD, dest, TRUE); - if (dfd < 0) - return -1; - - return glnx_libcontainer_run_chroot_at_private (dfd, binary, argv); -} diff --git a/glnx-libcontainer.h b/glnx-libcontainer.h deleted file mode 100644 index 9ac83d40d30aae83b0c8fc13e9851dff6f6b28ea..0000000000000000000000000000000000000000 --- a/glnx-libcontainer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2014,2015 Colin Walters <walters@verbum.org> - * - * This program 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 of the licence or (at - * your option) any later version. - * - * This 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 this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#pragma once - -#include <gio/gio.h> -#include <sched.h> -#include <sys/mount.h> -#include <sys/types.h> -#include <sys/prctl.h> -#include <sys/fsuid.h> -#include <sys/syscall.h> -#include <sys/wait.h> -#include <sys/capability.h> -#include <sched.h> - -pid_t glnx_libcontainer_run_chroot_at_private (int root_dfd, - const char *binary, - char **argv); - -pid_t glnx_libcontainer_run_chroot_private (const char *dest, - const char *binary, - char **argv); diff --git a/libglnx.h b/libglnx.h index 451740d2acbb805d5fb05d7c91348160448d1292..a5b23d07e59bd50d2ef555aebe4e5049de4e547e 100644 --- a/libglnx.h +++ b/libglnx.h @@ -33,7 +33,6 @@ G_BEGIN_DECLS #include <glnx-dirfd.h> #include <glnx-shutil.h> #include <glnx-xattrs.h> -#include <glnx-libcontainer.h> #include <glnx-console.h> #include <glnx-fdio.h>