Permalink
Browse files

Fix forkmount to work with 4.8 and higher

A new restriction was placed in the 4.8 kernel that mkdir will return
EOVERFLOW if the resulting uid/gid is outside of the container's map.

This is a problem for us as we only attach to the mount namespace.

So to fix that, we must detect that the kernel supports userns and that
the container is in a userns, then attach.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
  • Loading branch information...
1 parent 6ddb409 commit 6ff0b5f3b73e0431785e2da1cf0913d6e3e5fd8d @stgraber stgraber committed Oct 6, 2016
Showing with 34 additions and 0 deletions.
  1. +34 −0 lxd/nsexec.go
View
@@ -368,9 +368,43 @@ void create(char *src, char *dest) {
void forkmount(char *buf, char *cur, ssize_t size) {
char *src, *dest, *opts;
+ char nspath[PATH_MAX];
+ char userns_source[PATH_MAX];
+ char userns_target[PATH_MAX];
+
ADVANCE_ARG_REQUIRED();
int pid = atoi(cur);
+ sprintf(nspath, "/proc/%d/ns/user", pid);
+ if (access(nspath, F_OK) == 0) {
+ if (readlink("/proc/self/ns/user", userns_source, 18) < 0) {
+ fprintf(stderr, "Failed readlink of source namespace: %s\n", strerror(errno));
+ _exit(1);
+ }
+
+ if (readlink(nspath, userns_target, PATH_MAX) < 0) {
+ fprintf(stderr, "Failed readlink of target namespace: %s\n", strerror(errno));
+ _exit(1);
+ }
+
+ if (strncmp(userns_source, userns_target, PATH_MAX) != 0) {
+ if (dosetns(pid, "user") < 0) {
+ fprintf(stderr, "Failed setns to container user namespace: %s\n", strerror(errno));
+ _exit(1);
+ }
+
+ if (setuid(0) < 0) {
+ fprintf(stderr, "Failed setuid to container root user: %s\n", strerror(errno));
+ _exit(1);
+ }
+
+ if (setgid(0) < 0) {
+ fprintf(stderr, "Failed setgid to container root group: %s\n", strerror(errno));
+ _exit(1);
+ }
+ }
+ }
+
if (dosetns(pid, "mnt") < 0) {
fprintf(stderr, "Failed setns to container mount namespace: %s\n", strerror(errno));
_exit(1);

0 comments on commit 6ff0b5f

Please sign in to comment.