summaryrefslogtreecommitdiff
path: root/src/machine
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2017-02-13 19:24:01 +0100
committerLennart Poettering <lennart@poettering.net>2017-02-17 10:22:28 +0100
commitd01cd40196eb18d859b3c416505ceb1d4ba398ac (patch)
tree65baa4f5219dd3414aa3b5038301b678a463e976 /src/machine
parent1c876927e4e63b90f72dd32cbc949a16948fe39e (diff)
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
Diffstat (limited to 'src/machine')
-rw-r--r--src/machine/machine-dbus.c13
1 files changed, 11 insertions, 2 deletions
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);