From 93c6bb51b6a3c80577fd823d0108c1dfcf01a0ce Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Thu, 27 Oct 2016 09:20:18 +0200 Subject: core: move the code that setups namespaces on its own function --- src/core/execute.c | 101 ++++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 47 deletions(-) (limited to 'src/core/execute.c') diff --git a/src/core/execute.c b/src/core/execute.c index 5e7d7c25d7..2908ba8fa3 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2003,6 +2003,59 @@ static int compile_read_write_paths( return 0; } +static int apply_mount_namespace(Unit *u, const ExecContext *context, + const ExecParameters *params, + ExecRuntime *runtime) { + int r; + _cleanup_free_ char **rw = NULL; + char *tmp = NULL, *var = NULL; + const char *root_dir = NULL; + NameSpaceInfo ns_info = { + .private_dev = context->private_devices, + .protect_control_groups = context->protect_control_groups, + .protect_kernel_tunables = context->protect_kernel_tunables, + .protect_kernel_modules = context->protect_kernel_modules, + }; + + /* The runtime struct only contains the parent of the private /tmp, + * which is non-accessible to world users. Inside of it there's a /tmp + * that is sticky, and that's the one we want to use here. */ + + if (context->private_tmp && runtime) { + if (runtime->tmp_dir) + tmp = strjoina(runtime->tmp_dir, "/tmp"); + if (runtime->var_tmp_dir) + var = strjoina(runtime->var_tmp_dir, "/tmp"); + } + + r = compile_read_write_paths(context, params, &rw); + if (r < 0) + return r; + + if (params->flags & EXEC_APPLY_CHROOT) + root_dir = context->root_directory; + + r = setup_namespace(root_dir, &ns_info, rw, + context->read_only_paths, + context->inaccessible_paths, + tmp, + var, + context->protect_home, + context->protect_system, + context->mount_flags); + + /* If we couldn't set up the namespace this is probably due to a + * missing capability. In this case, silently proceeed. */ + if (IN_SET(r, -EPERM, -EACCES)) { + log_open(); + log_unit_debug_errno(u, r, "Failed to set up namespace, assuming containerized execution, ignoring: %m"); + log_close(); + r = 0; + } + + return r; +} + static void append_socket_pair(int *array, unsigned *n, int pair[2]) { assert(array); assert(n); @@ -2466,57 +2519,11 @@ static int exec_child( needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime); if (needs_mount_namespace) { - _cleanup_free_ char **rw = NULL; - char *tmp = NULL, *var = NULL; - NameSpaceInfo ns_info = { - .private_dev = context->private_devices, - .protect_control_groups = context->protect_control_groups, - .protect_kernel_tunables = context->protect_kernel_tunables, - .protect_kernel_modules = context->protect_kernel_modules, - }; - - /* The runtime struct only contains the parent - * of the private /tmp, which is - * non-accessible to world users. Inside of it - * there's a /tmp that is sticky, and that's - * the one we want to use here. */ - - if (context->private_tmp && runtime) { - if (runtime->tmp_dir) - tmp = strjoina(runtime->tmp_dir, "/tmp"); - if (runtime->var_tmp_dir) - var = strjoina(runtime->var_tmp_dir, "/tmp"); - } - - r = compile_read_write_paths(context, params, &rw); + r = apply_mount_namespace(unit, context, params, runtime); if (r < 0) { *exit_status = EXIT_NAMESPACE; return r; } - - r = setup_namespace( - (params->flags & EXEC_APPLY_CHROOT) ? context->root_directory : NULL, - &ns_info, - rw, - context->read_only_paths, - context->inaccessible_paths, - tmp, - var, - context->protect_home, - context->protect_system, - context->mount_flags); - - /* If we couldn't set up the namespace this is - * probably due to a missing capability. In this case, - * silently proceeed. */ - if (r == -EPERM || r == -EACCES) { - log_open(); - log_unit_debug_errno(unit, r, "Failed to set up namespace, assuming containerized execution, ignoring: %m"); - log_close(); - } else if (r < 0) { - *exit_status = EXIT_NAMESPACE; - return r; - } } if (context->working_directory_home) -- cgit v1.2.3-54-g00ecf From e7f1e7c6e2f91f3cad5eadfcc6ab9673caedb838 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Thu, 27 Oct 2016 09:21:44 +0200 Subject: core: move apply working directory code into its own apply_working_directory() --- src/core/execute.c | 52 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-) (limited to 'src/core/execute.c') diff --git a/src/core/execute.c b/src/core/execute.c index 2908ba8fa3..642add0360 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2056,6 +2056,33 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context, return r; } +static int apply_working_directory(const ExecContext *context, + const ExecParameters *params, + const char *working_directory, + const bool needs_mount_ns) { + + if (params->flags & EXEC_APPLY_CHROOT) { + if (!needs_mount_ns && context->root_directory) + if (chroot(context->root_directory) < 0) + return -errno; + + if (chdir(working_directory) < 0 && + !context->working_directory_missing_ok) + return -errno; + + } else { + const char *d; + + d = strjoina(strempty(context->root_directory), "/", + strempty(working_directory)); + if (chdir(d) < 0 && + !context->working_directory_missing_ok) + return -errno; + } + + return 0; +} + static void append_socket_pair(int *array, unsigned *n, int pair[2]) { assert(array); assert(n); @@ -2542,27 +2569,10 @@ static int exec_child( } } - if (params->flags & EXEC_APPLY_CHROOT) { - if (!needs_mount_namespace && context->root_directory) - if (chroot(context->root_directory) < 0) { - *exit_status = EXIT_CHROOT; - return -errno; - } - - if (chdir(wd) < 0 && - !context->working_directory_missing_ok) { - *exit_status = EXIT_CHDIR; - return -errno; - } - } else { - const char *d; - - d = strjoina(strempty(context->root_directory), "/", strempty(wd)); - if (chdir(d) < 0 && - !context->working_directory_missing_ok) { - *exit_status = EXIT_CHDIR; - return -errno; - } + r = apply_working_directory(context, params, wd, needs_mount_namespace); + if (r < 0) { + *exit_status = EXIT_CHROOT; + return r; } #ifdef HAVE_SELINUX -- cgit v1.2.3-54-g00ecf From 2b3c1b9e9d7a09b1f974f8d702da8ebaeff036f6 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Thu, 27 Oct 2016 09:28:54 +0200 Subject: core: get the working directory value inside apply_working_directory() Improve apply_working_directory() and lets get the current working directory inside of it. --- src/core/execute.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'src/core/execute.c') diff --git a/src/core/execute.c b/src/core/execute.c index 642add0360..0b6fcc9ac7 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2017,6 +2017,8 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context, .protect_kernel_modules = context->protect_kernel_modules, }; + assert(context); + /* The runtime struct only contains the parent of the private /tmp, * which is non-accessible to world users. Inside of it there's a /tmp * that is sticky, and that's the one we want to use here. */ @@ -2058,27 +2060,31 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context, static int apply_working_directory(const ExecContext *context, const ExecParameters *params, - const char *working_directory, + const char *home, const bool needs_mount_ns) { + const char *d; + const char *wd; + + assert(context); + + if (context->working_directory_home) + wd = home; + else if (context->working_directory) + wd = context->working_directory; + else + wd = "/"; if (params->flags & EXEC_APPLY_CHROOT) { if (!needs_mount_ns && context->root_directory) if (chroot(context->root_directory) < 0) return -errno; - if (chdir(working_directory) < 0 && - !context->working_directory_missing_ok) - return -errno; - - } else { - const char *d; + d = wd; + } else + d = strjoina(strempty(context->root_directory), "/", strempty(wd)); - d = strjoina(strempty(context->root_directory), "/", - strempty(working_directory)); - if (chdir(d) < 0 && - !context->working_directory_missing_ok) - return -errno; - } + if (chdir(d) < 0 && !context->working_directory_missing_ok) + return -errno; return 0; } @@ -2219,7 +2225,7 @@ static int exec_child( _cleanup_free_ char *mac_selinux_context_net = NULL; _cleanup_free_ gid_t *supplementary_gids = NULL; const char *username = NULL, *groupname = NULL; - const char *home = NULL, *shell = NULL, *wd; + const char *home = NULL, *shell = NULL; dev_t journal_stream_dev = 0; ino_t journal_stream_ino = 0; bool needs_mount_namespace; @@ -2553,13 +2559,6 @@ static int exec_child( } } - if (context->working_directory_home) - wd = home; - else if (context->working_directory) - wd = context->working_directory; - else - wd = "/"; - /* Drop group as early as possbile */ if ((params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged) { r = enforce_groups(context, gid, supplementary_gids, ngids); @@ -2569,7 +2568,7 @@ static int exec_child( } } - r = apply_working_directory(context, params, wd, needs_mount_namespace); + r = apply_working_directory(context, params, home, needs_mount_namespace); if (r < 0) { *exit_status = EXIT_CHROOT; return r; -- cgit v1.2.3-54-g00ecf From 50b3dfb9d64872025450aa63765206720be471d6 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Tue, 25 Oct 2016 16:24:35 +0200 Subject: core: lets apply working directory just after mount namespaces This makes applying groups after applying the working directory, this may allow some flexibility but at same it is not a big deal since we don't execute or do anything between applying working directory and droping groups. --- src/core/execute.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/core/execute.c') diff --git a/src/core/execute.c b/src/core/execute.c index 0b6fcc9ac7..a9e39f6fd7 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2559,6 +2559,13 @@ static int exec_child( } } + /* Apply just after mount namespace setup */ + r = apply_working_directory(context, params, home, needs_mount_namespace); + if (r < 0) { + *exit_status = EXIT_CHROOT; + return r; + } + /* Drop group as early as possbile */ if ((params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged) { r = enforce_groups(context, gid, supplementary_gids, ngids); @@ -2568,12 +2575,6 @@ static int exec_child( } } - r = apply_working_directory(context, params, home, needs_mount_namespace); - if (r < 0) { - *exit_status = EXIT_CHROOT; - return r; - } - #ifdef HAVE_SELINUX if ((params->flags & EXEC_APPLY_PERMISSIONS) && mac_selinux_use() && -- cgit v1.2.3-54-g00ecf From 59e856c7d33e8260d0ac3a8e21318d6f0768d75b Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Thu, 27 Oct 2016 09:39:20 +0200 Subject: core: make unit argument const for apply seccomp functions --- src/core/execute.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/execute.c') diff --git a/src/core/execute.c b/src/core/execute.c index a9e39f6fd7..7f343c4902 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1470,7 +1470,7 @@ finish: return r; } -static int apply_protect_sysctl(Unit *u, const ExecContext *c) { +static int apply_protect_sysctl(const Unit *u, const ExecContext *c) { scmp_filter_ctx seccomp; int r; @@ -1501,7 +1501,7 @@ finish: return r; } -static int apply_protect_kernel_modules(Unit *u, const ExecContext *c) { +static int apply_protect_kernel_modules(const Unit *u, const ExecContext *c) { assert(c); /* Turn off module syscalls on ProtectKernelModules=yes */ @@ -1512,7 +1512,7 @@ static int apply_protect_kernel_modules(Unit *u, const ExecContext *c) { return seccomp_load_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM)); } -static int apply_private_devices(Unit *u, const ExecContext *c) { +static int apply_private_devices(const Unit *u, const ExecContext *c) { assert(c); /* If PrivateDevices= is set, also turn off iopl and all @raw-io syscalls. */ -- cgit v1.2.3-54-g00ecf