summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-07-19 21:17:49 +0200
committerGitHub <noreply@github.com>2016-07-19 21:17:49 +0200
commit069a92c6581a2ee4fc0f0f9430f54412e6e3026b (patch)
tree02fb11f404687d06d5c7a5792c7e425604f16c30 /src
parent4526e15d064c77a61cf79c595c3384effd66d31b (diff)
parent2a624c36e646e9ef8d204a506b12e7dbd380e111 (diff)
Merge pull request #3685 from kinvolk/alessandro/inaccessible-paths
namespace: unify limit behavior on non-directory paths
Diffstat (limited to 'src')
-rw-r--r--src/basic/mount-util.c18
-rw-r--r--src/basic/mount-util.h2
-rw-r--r--src/core/dbus-execute.c25
-rw-r--r--src/core/execute.c36
-rw-r--r--src/core/execute.h2
-rw-r--r--src/core/load-fragment-gperf.gperf.m49
-rw-r--r--src/core/mount-setup.c14
-rw-r--r--src/core/namespace.c49
-rw-r--r--src/core/namespace.h6
-rw-r--r--src/shared/bus-unit-util.c3
10 files changed, 107 insertions, 57 deletions
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index 90b7a885a8..63dff3dd5c 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -532,3 +532,21 @@ int repeat_unmount(const char *path, int flags) {
done = true;
}
}
+
+const char* mode_to_inaccessible_node(mode_t mode) {
+ switch(mode & S_IFMT) {
+ case S_IFREG:
+ return "/run/systemd/inaccessible/reg";
+ case S_IFDIR:
+ return "/run/systemd/inaccessible/dir";
+ case S_IFCHR:
+ return "/run/systemd/inaccessible/chr";
+ case S_IFBLK:
+ return "/run/systemd/inaccessible/blk";
+ case S_IFIFO:
+ return "/run/systemd/inaccessible/fifo";
+ case S_IFSOCK:
+ return "/run/systemd/inaccessible/sock";
+ }
+ return NULL;
+}
diff --git a/src/basic/mount-util.h b/src/basic/mount-util.h
index bdb525d6b0..f46989ebb3 100644
--- a/src/basic/mount-util.h
+++ b/src/basic/mount-util.h
@@ -49,4 +49,6 @@ union file_handle_union {
char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
};
+const char* mode_to_inaccessible_node(mode_t mode);
+
#define FILE_HANDLE_INIT { .handle.handle_bytes = MAX_HANDLE_SZ }
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 644b9561b5..b2ef3db491 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -695,9 +695,12 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -1323,8 +1326,8 @@ int bus_exec_context_set_transient_property(
return 1;
- } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) {
-
+ } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
+ "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
_cleanup_strv_free_ char **l = NULL;
char ***dirs;
char **p;
@@ -1346,12 +1349,12 @@ int bus_exec_context_set_transient_property(
if (mode != UNIT_CHECK) {
_cleanup_free_ char *joined = NULL;
- if (streq(name, "ReadWriteDirectories"))
- dirs = &c->read_write_dirs;
- else if (streq(name, "ReadOnlyDirectories"))
- dirs = &c->read_only_dirs;
- else /* "InaccessibleDirectories" */
- dirs = &c->inaccessible_dirs;
+ if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
+ dirs = &c->read_write_paths;
+ else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
+ dirs = &c->read_only_paths;
+ else /* "InaccessiblePaths" */
+ dirs = &c->inaccessible_paths;
if (strv_length(l) == 0) {
*dirs = strv_free(*dirs);
diff --git a/src/core/execute.c b/src/core/execute.c
index f4f5723c35..05dc1aaec1 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1507,9 +1507,9 @@ static bool exec_needs_mount_namespace(
assert(context);
assert(params);
- if (!strv_isempty(context->read_write_dirs) ||
- !strv_isempty(context->read_only_dirs) ||
- !strv_isempty(context->inaccessible_dirs))
+ if (!strv_isempty(context->read_write_paths) ||
+ !strv_isempty(context->read_only_paths) ||
+ !strv_isempty(context->inaccessible_paths))
return true;
if (context->mount_flags != 0)
@@ -1933,9 +1933,9 @@ static int exec_child(
r = setup_namespace(
params->apply_chroot ? context->root_directory : NULL,
- context->read_write_dirs,
- context->read_only_dirs,
- context->inaccessible_dirs,
+ context->read_write_paths,
+ context->read_only_paths,
+ context->inaccessible_paths,
tmp,
var,
context->private_devices,
@@ -2324,9 +2324,9 @@ void exec_context_done(ExecContext *c) {
c->pam_name = mfree(c->pam_name);
- c->read_only_dirs = strv_free(c->read_only_dirs);
- c->read_write_dirs = strv_free(c->read_write_dirs);
- c->inaccessible_dirs = strv_free(c->inaccessible_dirs);
+ c->read_only_paths = strv_free(c->read_only_paths);
+ c->read_write_paths = strv_free(c->read_write_paths);
+ c->inaccessible_paths = strv_free(c->inaccessible_paths);
if (c->cpuset)
CPU_FREE(c->cpuset);
@@ -2732,21 +2732,21 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
if (c->pam_name)
fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
- if (strv_length(c->read_write_dirs) > 0) {
- fprintf(f, "%sReadWriteDirs:", prefix);
- strv_fprintf(f, c->read_write_dirs);
+ if (strv_length(c->read_write_paths) > 0) {
+ fprintf(f, "%sReadWritePaths:", prefix);
+ strv_fprintf(f, c->read_write_paths);
fputs("\n", f);
}
- if (strv_length(c->read_only_dirs) > 0) {
- fprintf(f, "%sReadOnlyDirs:", prefix);
- strv_fprintf(f, c->read_only_dirs);
+ if (strv_length(c->read_only_paths) > 0) {
+ fprintf(f, "%sReadOnlyPaths:", prefix);
+ strv_fprintf(f, c->read_only_paths);
fputs("\n", f);
}
- if (strv_length(c->inaccessible_dirs) > 0) {
- fprintf(f, "%sInaccessibleDirs:", prefix);
- strv_fprintf(f, c->inaccessible_dirs);
+ if (strv_length(c->inaccessible_paths) > 0) {
+ fprintf(f, "%sInaccessiblePaths:", prefix);
+ strv_fprintf(f, c->inaccessible_paths);
fputs("\n", f);
}
diff --git a/src/core/execute.h b/src/core/execute.h
index cacf66cf51..73b8a119b0 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -152,7 +152,7 @@ struct ExecContext {
bool smack_process_label_ignore;
char *smack_process_label;
- char **read_write_dirs, **read_only_dirs, **inaccessible_dirs;
+ char **read_write_paths, **read_only_paths, **inaccessible_paths;
unsigned long mount_flags;
uint64_t capability_bounding_set;
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index fe1006830b..6a5c16a000 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -80,9 +80,12 @@ $1.LimitMSGQUEUE, config_parse_limit, RLIMIT_MSGQ
$1.LimitNICE, config_parse_limit, RLIMIT_NICE, offsetof($1, exec_context.rlimit)
$1.LimitRTPRIO, config_parse_limit, RLIMIT_RTPRIO, offsetof($1, exec_context.rlimit)
$1.LimitRTTIME, config_parse_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit)
-$1.ReadWriteDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_write_dirs)
-$1.ReadOnlyDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_only_dirs)
-$1.InaccessibleDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.inaccessible_dirs)
+$1.ReadWriteDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_write_paths)
+$1.ReadOnlyDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_only_paths)
+$1.InaccessibleDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.inaccessible_paths)
+$1.ReadWritePaths, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_write_paths)
+$1.ReadOnlyPaths, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_only_paths)
+$1.InaccessiblePaths, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.inaccessible_paths)
$1.PrivateTmp, config_parse_bool, 0, offsetof($1, exec_context.private_tmp)
$1.PrivateNetwork, config_parse_bool, 0, offsetof($1, exec_context.private_network)
$1.PrivateDevices, config_parse_bool, 0, offsetof($1, exec_context.private_devices)
diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index f9c9b4a91f..5d8ab0ec70 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -28,6 +28,7 @@
#include "cgroup-util.h"
#include "dev-setup.h"
#include "efivars.h"
+#include "fs-util.h"
#include "label.h"
#include "log.h"
#include "macro.h"
@@ -403,9 +404,16 @@ int mount_setup(bool loaded_policy) {
* really needs to stay for good, otherwise software that
* copied sd-daemon.c into their sources will misdetect
* systemd. */
- mkdir_label("/run/systemd", 0755);
- mkdir_label("/run/systemd/system", 0755);
- mkdir_label("/run/systemd/inaccessible", 0000);
+ (void) mkdir_label("/run/systemd", 0755);
+ (void) mkdir_label("/run/systemd/system", 0755);
+ (void) mkdir_label("/run/systemd/inaccessible", 0000);
+ /* Set up inaccessible items */
+ (void) mknod("/run/systemd/inaccessible/reg", S_IFREG | 0000, 0);
+ (void) mkdir_label("/run/systemd/inaccessible/dir", 0000);
+ (void) mknod("/run/systemd/inaccessible/chr", S_IFCHR | 0000, makedev(0, 0));
+ (void) mknod("/run/systemd/inaccessible/blk", S_IFBLK | 0000, makedev(0, 0));
+ (void) mkfifo("/run/systemd/inaccessible/fifo", 0000);
+ (void) mknod("/run/systemd/inaccessible/sock", S_IFSOCK | 0000, 0);
return 0;
}
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 203d122810..722538caf1 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -278,6 +278,7 @@ static int apply_mount(
const char *what;
int r;
+ struct stat target;
assert(m);
@@ -287,12 +288,22 @@ static int apply_mount(
/* First, get rid of everything that is below if there
* is anything... Then, overmount it with an
- * inaccessible directory. */
+ * inaccessible path. */
umount_recursive(m->path, 0);
- what = "/run/systemd/inaccessible";
- break;
+ r = lstat(m->path, &target);
+ if (r != 0) {
+ if (m->ignore && errno == ENOENT)
+ return 0;
+ return -errno;
+ }
+ what = mode_to_inaccessible_node(target.st_mode);
+ if (what == NULL) {
+ log_debug("File type not supported. Note that symlinks are not allowed");
+ return -ELOOP;
+ }
+ break;
case READONLY:
case READWRITE:
/* Nothing to mount here, we just later toggle the
@@ -317,12 +328,16 @@ static int apply_mount(
assert(what);
r = mount(what, m->path, NULL, MS_BIND|MS_REC, NULL);
- if (r >= 0)
+ if (r >= 0) {
log_debug("Successfully mounted %s to %s", what, m->path);
- else if (m->ignore && errno == ENOENT)
- return 0;
-
- return r;
+ return r;
+ }
+ else {
+ if (m->ignore && errno == ENOENT)
+ return 0;
+ log_debug("Failed mounting %s to %s: %s", what, m->path, strerror(errno));
+ return -errno;
+ }
}
static int make_read_only(BindMount *m) {
@@ -347,9 +362,9 @@ static int make_read_only(BindMount *m) {
int setup_namespace(
const char* root_directory,
- char** read_write_dirs,
- char** read_only_dirs,
- char** inaccessible_dirs,
+ char** read_write_paths,
+ char** read_only_paths,
+ char** inaccessible_paths,
const char* tmp_dir,
const char* var_tmp_dir,
bool private_dev,
@@ -368,9 +383,9 @@ int setup_namespace(
return -errno;
n = !!tmp_dir + !!var_tmp_dir +
- strv_length(read_write_dirs) +
- strv_length(read_only_dirs) +
- strv_length(inaccessible_dirs) +
+ strv_length(read_write_paths) +
+ strv_length(read_only_paths) +
+ strv_length(inaccessible_paths) +
private_dev +
(protect_home != PROTECT_HOME_NO ? 3 : 0) +
(protect_system != PROTECT_SYSTEM_NO ? 2 : 0) +
@@ -378,15 +393,15 @@ int setup_namespace(
if (n > 0) {
m = mounts = (BindMount *) alloca0(n * sizeof(BindMount));
- r = append_mounts(&m, read_write_dirs, READWRITE);
+ r = append_mounts(&m, read_write_paths, READWRITE);
if (r < 0)
return r;
- r = append_mounts(&m, read_only_dirs, READONLY);
+ r = append_mounts(&m, read_only_paths, READONLY);
if (r < 0)
return r;
- r = append_mounts(&m, inaccessible_dirs, INACCESSIBLE);
+ r = append_mounts(&m, inaccessible_paths, INACCESSIBLE);
if (r < 0)
return r;
diff --git a/src/core/namespace.h b/src/core/namespace.h
index b54b7b47d6..1aedf5f208 100644
--- a/src/core/namespace.h
+++ b/src/core/namespace.h
@@ -40,9 +40,9 @@ typedef enum ProtectSystem {
} ProtectSystem;
int setup_namespace(const char *chroot,
- char **read_write_dirs,
- char **read_only_dirs,
- char **inaccessible_dirs,
+ char **read_write_paths,
+ char **read_only_paths,
+ char **inaccessible_paths,
const char *tmp_dir,
const char *var_tmp_dir,
bool private_dev,
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index 04471e2373..94ffa8af87 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -453,7 +453,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
}
r = sd_bus_message_append(m, "v", "i", oa);
- } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) {
+ } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
+ "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
const char *p;
r = sd_bus_message_open_container(m, 'v', "as");