Package: gettext
Version: 1.0-5
Severity: important
Tags: patch
User: [email protected]
Usertags: origin-ubuntu stonking

Dear maintainer,

With glibc >= 2.44, <spawn.h> declares posix_spawn_file_actions_addchdir
as an asm redirection alias (__REDIRECT_NTH) to
posix_spawn_file_actions_addchdir_np according to POSIX.1-2024.

gnulib sets REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=1, compiling
spawn_faction_addchdir.c which returns posix_spawn_file_actions_addchdir_np.
Because asm redirection cannot be undone by #undef, gcc emits the function
definition as posix_spawn_file_actions_addchdir_np, calling itself in an
infinite recursion.

On i386, this causes an immediate SIGSEGV (exit code 139) during gnulib
tests. On amd64 and arm64, it hangs test-execute.sh and
test-posix_spawn-chdir, leading to FTBFS on Ubuntu stonking (LP: #2167365).

In glibc >= 2.44, posix_spawn_file_actions_addchdir is already provided
natively by libc. Guarding spawn_faction_addchdir.c when defined __GLIBC__
&& defined __USE_XOPEN2K24XSI prevents the recursive definition and allows
clean compilation and test suite execution.

Attached is the patch addressing this issue.

Thanks,
Viktor Pashaiev <[email protected]>

--- a/gettext-tools/gnulib-lib/spawn_faction_addchdir.c
+++ b/gettext-tools/gnulib-lib/spawn_faction_addchdir.c
@@ -28,43 +28,58 @@
 
 /* Add an action to FILE-ACTIONS which tells the implementation to call
    'chdir' to the given directory during the 'spawn' call.  */
+#if !REPLACE_POSIX_SPAWN
+
+# if defined __GLIBC__ && defined __USE_XOPEN2K24XSI
+/* In glibc >= 2.44, <spawn.h> already defines 
posix_spawn_file_actions_addchdir
+   as an alias to posix_spawn_file_actions_addchdir_np. Defining it here would
+   create a recursive call to itself and shadow libc.so.6. */
+typedef int gl_posix_spawn_file_actions_addchdir_unused_t;
+# else
 int
 posix_spawn_file_actions_addchdir (posix_spawn_file_actions_t *file_actions,
                                    const char *path)
-#undef posix_spawn_file_actions_addchdir
+#  undef posix_spawn_file_actions_addchdir
 {
-#if !REPLACE_POSIX_SPAWN
   return posix_spawn_file_actions_addchdir_np (file_actions, path);
-#else
-  {
-    /* Copy PATH, because the caller may free it before calling posix_spawn()
-       or posix_spawnp().  */
-    char *path_copy = strdup (path);
-    if (path_copy == NULL)
-      return ENOMEM;
+}
+# endif
+
+#else
+
+int
+posix_spawn_file_actions_addchdir (posix_spawn_file_actions_t *file_actions,
+                                   const char *path)
+# undef posix_spawn_file_actions_addchdir
+{
+  /* Copy PATH, because the caller may free it before calling posix_spawn()
+     or posix_spawnp().  */
+  char *path_copy = strdup (path);
+  if (path_copy == NULL)
+    return ENOMEM;
+
+  /* Allocate more memory if needed.  */
+  if (file_actions->_used == file_actions->_allocated
+      && __posix_spawn_file_actions_realloc (file_actions) != 0)
+    {
+      /* This can only mean we ran out of memory.  */
+      free (path_copy);
+      return ENOMEM;
+    }
+
+  {
+    struct __spawn_action *rec;
+
+    /* Add the new value.  */
+    rec = &file_actions->_actions[file_actions->_used];
+    rec->tag = spawn_do_chdir;
+    rec->action.chdir_action.path = path_copy;
+
+    /* Account for the new entry.  */
+    ++file_actions->_used;
+
+    return 0;
+  }
 }
+
+#endif

Reply via email to