X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fnspawn%2Fnspawn.c;h=a0809da7439cd730833137a2e0fee66a33cf3ecd;hb=d2421337f6e7d5a6730599e929232689acb09394;hp=fc005d9ce352f7cc763a2948c0bc7328344c7352;hpb=aea38d8047a7a9370f8545007d242ede4a5cede1;p=elogind.git diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index fc005d9ce..a0809da74 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -411,12 +411,39 @@ static int mount_binds(const char *dest, char **l, unsigned long flags) { STRV_FOREACH_PAIR(x, y, l) { _cleanup_free_ char *where = NULL; + struct stat source_st, dest_st; + + if (stat(*x, &source_st) < 0) { + log_error("failed to stat %s: %m", *x); + return -errno; + } where = strjoin(dest, "/", *y, NULL); if (!where) return log_oom(); - mkdir_p_label(where, 0755); + if (stat(where, &dest_st) == 0) { + if ((source_st.st_mode & S_IFMT) != (dest_st.st_mode & S_IFMT)) { + log_error("The file types of %s and %s do not matching. Refusing bind mount", + *x, where); + return -EINVAL; + } + } else { + /* Create the mount point, but be conservative -- refuse to create block + * and char devices. */ + if (S_ISDIR(source_st.st_mode)) + mkdir_p_label(where, 0755); + else if (S_ISFIFO(source_st.st_mode)) + mkfifo(where, 0644); + else if (S_ISSOCK(source_st.st_mode)) + mknod(where, 0644 | S_IFSOCK, 0); + else if (S_ISREG(source_st.st_mode)) + touch(where); + else { + log_error("Refusing to create mountpoint for file: %s", *x); + return -ENOTSUP; + } + } if (mount(*x, where, "bind", MS_BIND, NULL) < 0) { log_error("mount(%s) failed: %m", where); @@ -1602,7 +1629,7 @@ int main(int argc, char *argv[]) { } if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", n_fd_passed) < 0) || - (asprintf((char **)(envp + n_env++), "LISTEN_PID=%lu", (unsigned long) 1) < 0)) { + (asprintf((char **)(envp + n_env++), "LISTEN_PID=1") < 0)) { log_oom(); goto child_fail; }