namespace.c revision a610cc4f18c24a007e5a2cac21b2ecbd81e5f3c3
3802a3d3d7af51ddff31943d5514382f01265770Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek This file is part of systemd.
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek Copyright 2010 Lennart Poettering
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek (at your option) any later version.
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
301af7e4853ad0281402f8d86f5a77c6cb7ce9f4Josh Triplett /* This is ordered by priority! */
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmekstatic int append_mounts(BindMount **p, char **strv, MountMode mode) {
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek if ((mode == INACCESSIBLE || mode == READONLY || mode == READWRITE) && (*i)[0] == '-') {
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmekstatic int mount_path_compare(const void *a, const void *b) {
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek const BindMount *p = a, *q = b;
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek if (path_equal(p->path, q->path)) {
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek /* If the paths are equal, check the mode */
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek /* If the paths are not equal, then order prefixes first */
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek if (path_startswith(p->path, q->path))
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek if (path_startswith(q->path, p->path))
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmekstatic void drop_duplicates(BindMount *m, unsigned *n) {
0dc5d23c85db85f96b141d4d32deee8018e56a6aLennart Poettering for (f = m, t = m, previous = NULL; f < m+*n; f++) {
0dc5d23c85db85f96b141d4d32deee8018e56a6aLennart Poettering /* The first one wins */
0dc5d23c85db85f96b141d4d32deee8018e56a6aLennart Poettering if (previous && path_equal(f->path, previous->path))
5470c03b37d8421a903564c2c8028c8b8d67d403Lennart Poettering static const char devnodes[] =
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek char temporary_mount[] = "/tmp/namespace-dev-XXXXXX";
3cc765d2718ac9b4ff978044ceabf5ad59d73edfZbigniew Jędrzejewski-Szmek const char *d, *dev = NULL, *devpts = NULL, *devshm = NULL, *devkdbus = NULL, *devhugepages = NULL, *devmqueue = NULL, *devlog = NULL, *devptmx = NULL;
return -errno;
r = -errno;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
r = -EINVAL;
goto fail;
if (!dn) {
r = -ENOMEM;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
fail:
if (devpts)
if (devshm)
if (devkdbus)
if (devhugepages)
if (devmqueue)
if (dev) {
assert(m);
u = umask(0000);
return -errno;
r = -errno;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
if (!basepath) {
r = -ENOMEM;
goto fail;
r = -errno;
goto fail;
fail:
if (busnode) {
if (root) {
static int apply_mount(
BindMount *m,
const char *tmp_dir,
const char *var_tmp_dir) {
const char *what;
assert(m);
switch (m->mode) {
case INACCESSIBLE:
case READONLY:
case READWRITE:
case PRIVATE_TMP:
case PRIVATE_VAR_TMP:
case PRIVATE_DEV:
return mount_dev(m);
case PRIVATE_BUS_ENDPOINT:
return mount_kdbus(m);
assert(m);
int setup_namespace(
char** read_write_dirs,
char** read_only_dirs,
char** inaccessible_dirs,
char* tmp_dir,
char* var_tmp_dir,
char* bus_endpoint_path,
bool private_dev,
unsigned mount_flags) {
if (mount_flags == 0)
return -errno;
if (tmp_dir) {
if (var_tmp_dir) {
if (private_dev) {
if (bus_endpoint_path) {
r = append_mounts(&m, STRV_MAKE("-/home", "-/run/user", "-/root"), protect_home == PROTECT_HOME_READ_ONLY ? READONLY : INACCESSIBLE);
r = append_mounts(&m, protect_system == PROTECT_SYSTEM_FULL ? STRV_MAKE("/usr", "-/boot", "/etc") : STRV_MAKE("/usr", "-/boot"), READONLY);
return -errno;
goto fail;
r = make_read_only(m);
goto fail;
r = -errno;
goto fail;
fail:
if (m->done)
x = strjoin(prefix, "/systemd-private-", sd_id128_to_string(boot_id, bid), "-", id, "-XXXXXX", NULL);
return -ENOMEM;
if (!mkdtemp(x))
return -errno;
RUN_WITH_UMASK(0000) {
return -errno;
*path = x;
x = NULL;
rmdir(t);
rmdir(a);
free(a);
*tmp_dir = a;
*var_tmp_dir = b;
} control = {};
return -errno;
r = -errno;
goto fail;
r = -errno;
goto fail;
if (netns < 0) {
r = -errno;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
fail: