[glib/wip/avoid-searching-path-2-66: 1/3] spawn: Don't set a search path if we don't want to search PATH




commit 22c7e0a74abba82b878528e5d6d16324815ed70f
Author: Simon McVittie <smcv collabora com>
Date:   Wed Jan 27 10:53:22 2021 +0000

    spawn: Don't set a search path if we don't want to search PATH
    
    do_exec() and g_execute() rely on being passed a NULL search path
    if we intend to avoid searching the PATH, but since the refactoring
    in commit 62ce66d4, this was never done. This resulted in some spawn
    calls searching the PATH when it was not intended.
    
    Spawn calls that go through the posix_spawn fast-path were unaffected.
    
    The deprecated gtester utility, as used in GTK 3, relies on the
    ability to run an executable from the current working directory by
    omitting the G_SPAWN_SEARCH_PATH flag. This *mostly* worked, because
    our fallback PATH ends with ".". However, if an executable of the
    same name existed in /usr/bin or /bin, it would run that instead of the
    intended test: in particular, GTK 3's build-time tests failed if
    ImageMagick happens to be installed, because gtester would accidentally
    run display(1) instead of testsuite/gdk/display.
    
    Fixes: 62ce66d4 "gspawn: Don’t use getenv() in async-signal-safe context"
    Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=977961

 glib/gspawn.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
---
diff --git a/glib/gspawn.c b/glib/gspawn.c
index c37ac7c84..0b9473022 100644
--- a/glib/gspawn.c
+++ b/glib/gspawn.c
@@ -1819,7 +1819,7 @@ fork_exec_with_fds (gboolean              intermediate_child,
   if (search_path && chosen_search_path == NULL)
     chosen_search_path = g_getenv ("PATH");
 
-  if (chosen_search_path == NULL)
+  if ((search_path || search_path_from_envp) && chosen_search_path == NULL)
     {
       /* There is no 'PATH' in the environment.  The default
        * * search path in libc is the current directory followed by
@@ -1834,14 +1834,27 @@ fork_exec_with_fds (gboolean              intermediate_child,
       chosen_search_path = "/bin:/usr/bin:.";
     }
 
+  if (search_path || search_path_from_envp)
+    g_assert (chosen_search_path != NULL);
+  else
+    g_assert (chosen_search_path == NULL);
+
   /* Allocate a buffer which the fork()ed child can use to assemble potential
    * paths for the binary to exec(), combining the argv[0] and elements from
    * the chosen_search_path. This can’t be done in the child because malloc()
    * (or alloca()) are not async-signal-safe (see `man 7 signal-safety`).
    *
    * Add 2 for the nul terminator and a leading `/`. */
-  search_path_buffer_len = strlen (chosen_search_path) + strlen (argv[0]) + 2;
-  search_path_buffer = g_malloc (search_path_buffer_len);
+  if (chosen_search_path != NULL)
+    {
+      search_path_buffer_len = strlen (chosen_search_path) + strlen (argv[0]) + 2;
+      search_path_buffer = g_malloc (search_path_buffer_len);
+    }
+
+  if (search_path || search_path_from_envp)
+    g_assert (search_path_buffer != NULL);
+  else
+    g_assert (search_path_buffer == NULL);
 
   /* And allocate a buffer which is 2 elements longer than @argv, so that if
    * script_execute() has to be called later on, it can build a wrapper argv


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