[systemd-commits] src/nspawn

Dave Reisner dreisner at kemper.freedesktop.org
Thu Sep 19 11:52:01 PDT 2013


 src/nspawn/nspawn.c |   29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

New commits:
commit d2421337f6e7d5a6730599e929232689acb09394
Author: Dave Reisner <dreisner at archlinux.org>
Date:   Thu Sep 19 14:30:07 2013 -0400

    nspawn: be less liberal about creating bind mount destinations
    
    Previously, if a file's bind mount destination didn't exist, nspawn
    would blindly create a directory, and the subsequent bind mount would
    fail. Examine the filetype of the source and ensure that, if the
    destination does not exist, that it is created appropriately.
    
    Also go one step further and ensure that the filetypes of the source
    and destination match.

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index f820860..a0809da 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);



More information about the systemd-commits mailing list