nspawn: allow access to device nodes listed in --bind= and --bind-ro= switches
authorStefan Junker <code@stefanjunker.de>
Thu, 14 May 2015 20:51:05 +0000 (22:51 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 14 May 2015 20:51:05 +0000 (22:51 +0200)
https://bugs.freedesktop.org/show_bug.cgi?id=90385

src/nspawn/nspawn.c
src/shared/util.c
src/shared/util.h

index fbf2344..8aa7b45 100644 (file)
@@ -2210,6 +2210,7 @@ static int register_machine(pid_t pid, int local_ifindex) {
         } else {
                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
                 char **i;
+                unsigned j;
 
                 r = sd_bus_message_new_method_call(
                                 bus,
@@ -2276,6 +2277,24 @@ static int register_machine(pid_t pid, int local_ifindex) {
                 if (r < 0)
                         return bus_log_create_error(r);
 
+                for (j = 0; j < arg_n_custom_mounts; j++) {
+                        CustomMount *cm = &arg_custom_mounts[j];
+
+                        if (cm->type != CUSTOM_MOUNT_BIND)
+                                continue;
+
+                        r = is_device_node(cm->source);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to stat %s: %m", cm->source);
+
+                        if (r) {
+                                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
+                                        cm->source, cm->read_only ? "r" : "rw");
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to append message arguments: %m");
+                        }
+                }
+
                 if (arg_kill_signal != 0) {
                         r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", arg_kill_signal);
                         if (r < 0)
index 72711e1..dda88bd 100644 (file)
@@ -5435,6 +5435,15 @@ int is_dir(const char* path, bool follow) {
         return !!S_ISDIR(st.st_mode);
 }
 
+int is_device_node(const char *path) {
+        struct stat info;
+
+        if (lstat(path, &info) < 0)
+                return -errno;
+
+        return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
+}
+
 int unquote_first_word(const char **p, char **ret, UnquoteFlags flags) {
         _cleanup_free_ char *s = NULL;
         size_t allocated = 0, sz = 0;
index 0c81e3d..22f505c 100644 (file)
@@ -852,6 +852,7 @@ int take_password_lock(const char *root);
 
 int is_symlink(const char *path);
 int is_dir(const char *path, bool follow);
+int is_device_node(const char *path);
 
 typedef enum UnquoteFlags {
         UNQUOTE_RELAX     = 1,