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

