From d01cd40196eb18d859b3c416505ceb1d4ba398ac Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 13 Feb 2017 19:24:01 +0100 Subject: machined: when copying files from/to userns containers chown to root This changes the file copy logic of machined to set the UID/GID of all copied files to 0 if the host and container do not share the same user namespace. Fixes: #4078 --- src/machine/machine-dbus.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/machine') diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 13d68553df..29fc68b90f 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -1055,10 +1055,12 @@ finish: int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *src, *dest, *host_path, *container_path, *host_basename, *host_dirname, *container_basename, *container_dirname; _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 }; + CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE; _cleanup_close_ int hostfd = -1; Machine *m = userdata; bool copy_from; pid_t child; + uid_t uid_shift; char *t; int r; @@ -1097,6 +1099,10 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro if (r == 0) return 1; /* Will call us back */ + r = machine_get_uid_shift(m, &uid_shift); + if (r < 0) + return r; + copy_from = strstr(sd_bus_message_get_member(message), "CopyFrom"); if (copy_from) { @@ -1151,10 +1157,13 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro goto child_fail; } + /* Run the actual copy operation. Note that when an UID shift is set we'll either clamp the UID/GID to + * 0 or to the actual UID shift depending on the direction we copy. If no UID shift is set we'll copy + * the UID/GIDs as they are. */ if (copy_from) - r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, COPY_REFLINK|COPY_MERGE); + r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, uid_shift == 0 ? UID_INVALID : 0, uid_shift == 0 ? GID_INVALID : 0, copy_flags); else - r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, COPY_REFLINK|COPY_MERGE); + r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, uid_shift == 0 ? UID_INVALID : uid_shift, uid_shift == 0 ? GID_INVALID : uid_shift, copy_flags); hostfd = safe_close(hostfd); containerfd = safe_close(containerfd); -- cgit v1.2.3-54-g00ecf