grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] unix exec: avoid atexit handlers when child exits


From: Vladimir 'phcoder' Serbinenko
Subject: Re: [PATCH] unix exec: avoid atexit handlers when child exits
Date: Wed, 30 Aug 2017 13:20:45 +0000

Comitted, thanks

Le Mon, Aug 28, 2017 à 8:58 PM, Patrick Steinhardt <address@hidden> a écrit :
The `grub_util_exec_redirect_all` helper function can be used to
spawn an executable and redirect its output to some files. After calling
`fork()`, the parent will wait for the child to terminate with
`waitpid()` while the child prepares its file descriptors, environment
and finally calls `execvp()`. If something in the children's setup
fails, it will stop by calling `exit(127)`.

Calling `exit()` will cause any function registered via `atexit()` to be
executed, which is usually the wrong thing to do in a child. And
actually, one can easily observe faulty behaviour on musl-based systems
without modprobe(8) installed: executing `grub-install --help` will call
`grub_util_exec_redirect_all` with "modprobe", which obviously fails if
modprobe(8) is not installed. Due to the child now exiting and invoking
the `atexit()` handlers, it will clean up some data structures of the
parent and cause it to be deadlocked in the `waitpid()` syscall.

The issue can easily be fixed by calling `_exit(127)` instead, which is
especially designed to be called when the atexit-handlers should not be
executed.

Signed-off-by: Patrick Steinhardt <address@hidden>
---
 grub-core/osdep/unix/exec.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/grub-core/osdep/unix/exec.c b/grub-core/osdep/unix/exec.c
index 935ff120e..db3259f65 100644
--- a/grub-core/osdep/unix/exec.c
+++ b/grub-core/osdep/unix/exec.c
@@ -99,7 +99,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file,
        {
          fd = open (stdin_file, O_RDONLY);
          if (fd < 0)
-           exit (127);
+           _exit (127);
          dup2 (fd, STDIN_FILENO);
          close (fd);
        }
@@ -108,7 +108,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file,
        {
          fd = open (stdout_file, O_WRONLY | O_CREAT, 0700);
          if (fd < 0)
-           exit (127);
+           _exit (127);
          dup2 (fd, STDOUT_FILENO);
          close (fd);
        }
@@ -117,7 +117,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file,
        {
          fd = open (stderr_file, O_WRONLY | O_CREAT, 0700);
          if (fd < 0)
-           exit (127);
+           _exit (127);
          dup2 (fd, STDERR_FILENO);
          close (fd);
        }
@@ -126,7 +126,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file,
       setenv ("LC_ALL", "C", 1);

       execvp ((char *) argv[0], (char **) argv);
-      exit (127);
+      _exit (127);
     }
   waitpid (pid, &status, 0);
   if (!WIFEXITED (status))
--
2.14.1


_______________________________________________
Grub-devel mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/grub-devel

reply via email to

[Prev in Thread] Current Thread [Next in Thread]