[systemd-devel] [PATCH] nspawn: Fix a race condition

Joel Teichroeb joel at teichroeb.net
Mon Mar 10 12:15:07 PDT 2014


If the master process registers the child before the child
has initialized, when the child tries to setup /dev/console
it gets "operation not permitted".
---
 src/nspawn/nspawn.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 92b6728..a83d1f3 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -1776,7 +1776,7 @@ finish:

 int main(int argc, char *argv[]) {

-        _cleanup_close_ int master = -1, kdbus_fd = -1, sync_fd = -1;
+        _cleanup_close_ int master = -1, kdbus_fd = -1, sync_fd = -1,
sync_fd2 = -1;
         _cleanup_close_pipe_ int kmsg_socket_pair[2] = { -1, -1 };
         _cleanup_free_ char *kdbus_domain = NULL;
         _cleanup_fdset_free_ FDSet *fds = NULL;
@@ -1925,9 +1925,11 @@ int main(int argc, char *argv[]) {

         for (;;) {
                 siginfo_t status;
+                eventfd_t x;

                 sync_fd = eventfd(0, EFD_CLOEXEC);
-                if (sync_fd < 0) {
+                sync_fd2 = eventfd(0, EFD_CLOEXEC);
+                if (sync_fd < 0 || sync_fd2 < 0) {
                         log_error("Failed to create event fd: %m");
                         goto finish;
                 }
@@ -1964,7 +1966,6 @@ int main(int argc, char *argv[]) {
                                 NULL
                         };
                         char **env_use;
-                        eventfd_t x;

                         envp[n_env] = strv_find_prefix(environ, "TERM=");
                         if (envp[n_env])
@@ -2201,6 +2202,9 @@ int main(int argc, char *argv[]) {
                                         goto child_fail;
                                 }
                         }
+                        eventfd_write(sync_fd2, 1);
+                        close_nointr_nofail(sync_fd2);
+                        sync_fd2 = -1;

                         eventfd_read(sync_fd, &x);
                         close_nointr_nofail(sync_fd);
@@ -2256,6 +2260,10 @@ int main(int argc, char *argv[]) {
                         _exit(EXIT_FAILURE);
                 }

+                eventfd_read(sync_fd2, &x);
+                close_nointr_nofail(sync_fd2);
+                sync_fd2 = -1;
+
                 fdset_free(fds);
                 fds = NULL;

-- 
1.9.0
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/systemd-devel/attachments/20140310/9c115cf4/attachment.html>


More information about the systemd-devel mailing list