Compare commits

..

2 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek ee00d1e95e pid1: do not fail if we get EPERM while setting up network name
In a user namespace container:
Feb 28 12:45:53 0b2420135953 systemd[1]: Starting Home Manager...
Feb 28 12:45:53 0b2420135953 systemd[21]: systemd-homed.service: Failed to set up network namespacing: Operation not permitted
Feb 28 12:45:53 0b2420135953 systemd[21]: systemd-homed.service: Failed at step NETWORK spawning /usr/lib/systemd/systemd-homed: Operation not permitted
Feb 28 12:45:53 0b2420135953 systemd[1]: systemd-homed.service: Main process exited, code=exited, status=225/NETWORK
Feb 28 12:45:53 0b2420135953 systemd[1]: systemd-homed.service: Failed with result 'exit-code'.
Feb 28 12:45:53 0b2420135953 systemd[1]: Failed to start Home Manager.

We should treat this similarly to the case where network namespace are not
supported at all.

https://bugzilla.redhat.com/show_bug.cgi?id=1807465
2020-02-29 19:33:19 +09:00
Nate Jones ecf63c9102 execute: Make '+' exec prefix ignore PrivateTmp=yes
The man pages state that the '+' prefix in Exec* directives should
ignore filesystem namespacing options such as PrivateTmp. Now it does.

This is very similar to #8842, just with PrivateTmp instead of
PrivateDevices.
2020-02-29 19:32:01 +09:00
5 changed files with 29 additions and 16 deletions

View File

@ -2565,17 +2565,6 @@ static int apply_mount_namespace(
assert(context); 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. */
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");
}
if (params->flags & EXEC_APPLY_CHROOT) { if (params->flags & EXEC_APPLY_CHROOT) {
root_image = context->root_image; root_image = context->root_image;
@ -2588,7 +2577,18 @@ static int apply_mount_namespace(
return r; return r;
needs_sandboxing = (params->flags & EXEC_APPLY_SANDBOXING) && !(command->flags & EXEC_COMMAND_FULLY_PRIVILEGED); needs_sandboxing = (params->flags & EXEC_APPLY_SANDBOXING) && !(command->flags & EXEC_COMMAND_FULLY_PRIVILEGED);
if (needs_sandboxing) if (needs_sandboxing) {
/* 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");
}
ns_info = (NamespaceInfo) { ns_info = (NamespaceInfo) {
.ignore_protect_paths = false, .ignore_protect_paths = false,
.private_dev = context->private_devices, .private_dev = context->private_devices,
@ -2600,7 +2600,7 @@ static int apply_mount_namespace(
.mount_apivfs = context->mount_apivfs, .mount_apivfs = context->mount_apivfs,
.private_mounts = context->private_mounts, .private_mounts = context->private_mounts,
}; };
else if (!context->dynamic_user && root_dir) } else if (!context->dynamic_user && root_dir)
/* /*
* If DynamicUser=no and RootDirectory= is set then lets pass a relaxed * If DynamicUser=no and RootDirectory= is set then lets pass a relaxed
* sandbox info, otherwise enforce it, don't ignore protected paths and * sandbox info, otherwise enforce it, don't ignore protected paths and
@ -3511,13 +3511,17 @@ static int exec_child(
if (ns_type_supported(NAMESPACE_NET)) { if (ns_type_supported(NAMESPACE_NET)) {
r = setup_netns(runtime->netns_storage_socket); r = setup_netns(runtime->netns_storage_socket);
if (r < 0) { if (r == -EPERM)
log_unit_warning_errno(unit, r,
"PrivateNetwork=yes is configured, but network namespace setup failed, ignoring: %m");
else if (r < 0) {
*exit_status = EXIT_NETWORK; *exit_status = EXIT_NETWORK;
return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m"); return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m");
} }
} else if (context->network_namespace_path) { } else if (context->network_namespace_path) {
*exit_status = EXIT_NETWORK; *exit_status = EXIT_NETWORK;
return log_unit_error_errno(unit, SYNTHETIC_ERRNO(EOPNOTSUPP), "NetworkNamespacePath= is not supported, refusing."); return log_unit_error_errno(unit, SYNTHETIC_ERRNO(EOPNOTSUPP),
"NetworkNamespacePath= is not supported, refusing.");
} else } else
log_unit_warning(unit, "PrivateNetwork=yes is configured, but the kernel does not support network namespaces, ignoring."); log_unit_warning(unit, "PrivateNetwork=yes is configured, but the kernel does not support network namespaces, ignoring.");
} }

View File

@ -294,6 +294,7 @@ static void test_exec_privatetmp(Manager *m) {
test(__func__, m, "exec-privatetmp-yes.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED); test(__func__, m, "exec-privatetmp-yes.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
test(__func__, m, "exec-privatetmp-no.service", 0, CLD_EXITED); test(__func__, m, "exec-privatetmp-no.service", 0, CLD_EXITED);
test(__func__, m, "exec-privatetmp-disabled-by-prefix.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
unlink("/tmp/test-exec_privatetmp"); unlink("/tmp/test-exec_privatetmp");
} }

View File

@ -109,6 +109,7 @@ test_data_files = '''
test-execute/exec-privatenetwork-yes.service test-execute/exec-privatenetwork-yes.service
test-execute/exec-privatetmp-no.service test-execute/exec-privatetmp-no.service
test-execute/exec-privatetmp-yes.service test-execute/exec-privatetmp-yes.service
test-execute/exec-privatetmp-disabled-by-prefix.service
test-execute/exec-protecthome-tmpfs-vs-protectsystem-strict.service test-execute/exec-protecthome-tmpfs-vs-protectsystem-strict.service
test-execute/exec-protectkernellogs-yes-capabilities.service test-execute/exec-protectkernellogs-yes-capabilities.service
test-execute/exec-protectkernellogs-no-capabilities.service test-execute/exec-protectkernellogs-no-capabilities.service

View File

@ -10,7 +10,6 @@ ExecStart=touch /tmp/a ; /bin/sh -c 'touch /tmp/b' ; touch /tmp/c
ExecStart=test -f /tmp/a ExecStart=test -f /tmp/a
ExecStart=!test -f /tmp/b ExecStart=!test -f /tmp/b
ExecStart=!!test -f /tmp/c ExecStart=!!test -f /tmp/c
ExecStart=+test -f /tmp/c
ExecStartPost=rm /tmp/a /tmp/b /tmp/c ExecStartPost=rm /tmp/a /tmp/b /tmp/c
PrivateTmp=true PrivateTmp=true

View File

@ -0,0 +1,8 @@
[Unit]
Description=Test for PrivateTmp=yes with prefix
[Service]
ExecStart=/bin/sh -x -c 'test ! -f /tmp/test-exec_privatetmp'
ExecStart=+/bin/sh -x -c 'test -f /tmp/test-exec_privatetmp'
Type=oneshot
PrivateTmp=yes