external/gpgmepp/UnpackedTarball_gpgmepp.mk |    1 
 external/gpgmepp/macos-tdf152524.patch      |  102 ++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+)

New commits:
commit be132c413c49175a27a55cfe3e42c748b5660a92
Author:     Patrick Luby <guibmac...@gmail.com>
AuthorDate: Fri Mar 22 09:44:51 2024 -0400
Commit:     Christian Lohmaier <lohmaier+libreoff...@googlemail.com>
CommitDate: Fri Mar 22 20:29:33 2024 +0100

    tdf#152524 fix crash by changing the macOS fork() and exec() process
    
    This fix backports commit 839cf255e2670fdf8e974af38432aacf63be4e90
    and commit 3c6c5ef5d1c4f555b465bf56cf9d99e4d67224cc.
    
    Change-Id: I5dd397a1ab624a048c8892c870b991b381a94f9c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165174
    Reviewed-by: Patrick Luby <guibomac...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Jenkins
    Reviewed-by: Christian Lohmaier <lohmaier+libreoff...@googlemail.com>

diff --git a/external/gpgmepp/UnpackedTarball_gpgmepp.mk 
b/external/gpgmepp/UnpackedTarball_gpgmepp.mk
index d7b7a8ab4dbe..dcbda38d591d 100644
--- a/external/gpgmepp/UnpackedTarball_gpgmepp.mk
+++ b/external/gpgmepp/UnpackedTarball_gpgmepp.mk
@@ -34,5 +34,6 @@ $(eval $(call gb_UnpackedTarball_add_patches,gpgmepp, \
     external/gpgmepp/w32-include.patch \
     external/gpgmepp/Wincompatible-function-pointer-types.patch \
     external/gpgmepp/macos-macports-path.patch \
+    external/gpgmepp/macos-tdf152524.patch \
 ))
 # vim: set noet sw=4 ts=4:
diff --git a/external/gpgmepp/macos-tdf152524.patch 
b/external/gpgmepp/macos-tdf152524.patch
new file mode 100644
index 000000000000..c1cdd047dba8
--- /dev/null
+++ b/external/gpgmepp/macos-tdf152524.patch
@@ -0,0 +1,102 @@
+--- src/posix-io.c     2023-02-01 11:50:48
++++ src/posix-io.c     2024-03-21 09:50:24
+@@ -67,6 +67,13 @@
+ #include "priv-io.h"
+ #include "sema.h"
+ #include "debug.h"
++
++#if HAVE_MACOS_SYSTEM
++#include <dispatch/dispatch.h>
++#include <spawn.h>
++
++extern char **environ;
++#endif
+ 
+ 
+ #ifdef USE_LINUX_GETDENTS
+@@ -515,6 +522,15 @@
+     }
+   return 0;
+ }
++
++
++#if HAVE_MACOS_SYSTEM
++static int
++_gpgme_io_spawn_macos (const char *path, char *const argv[], unsigned int 
flags,
++                     struct spawn_fd_item_s *fd_list,
++                     void (*atfork) (void *opaque, int reserved),
++                     void *atforkvalue, pid_t *r_pid);
++#endif /*HAVE_MACOS_SYSTEM*/
+ 
+ 
+ /* Returns 0 on success, -1 on error.  */
+@@ -523,6 +539,35 @@
+                struct spawn_fd_item_s *fd_list,
+                void (*atfork) (void *opaque, int reserved),
+                void *atforkvalue, pid_t *r_pid)
++#if HAVE_MACOS_SYSTEM
++{
++      /* tdf#152524 fork() and exec() in a separate libdispatch queue
++       * This is another attempt to stop the crashing in libdispatch by
++       * running fork() and exec() within a libdispatch task that will
++       * run in a sequential queue in a non-main thread.  */
++      static dispatch_queue_t queue = NULL;
++      if (!queue)
++              queue = dispatch_queue_create ("gpgmepp",
++                                             DISPATCH_QUEUE_CONCURRENT);
++      if (!queue)
++              return -1;
++
++      __block int ret = -1;
++      dispatch_sync(queue, ^{
++              ret = _gpgme_io_spawn_macos (path, argv, flags,
++                                           fd_list, atfork,
++                                           atforkvalue, r_pid);
++      });
++
++      return ret;
++}
++
++static int
++_gpgme_io_spawn_macos (const char *path, char *const argv[], unsigned int 
flags,
++                     struct spawn_fd_item_s *fd_list,
++                     void (*atfork) (void *opaque, int reserved),
++                     void *atforkvalue, pid_t *r_pid)
++#endif /*HAVE_MACOS_SYSTEM*/
+ {
+   pid_t pid;
+   int i;
+@@ -552,8 +597,15 @@
+   if (!pid)
+     {
+       /* Intermediate child to prevent zombie processes.  */
++#if HAVE_MACOS_SYSTEM
++      /* tdf#152524 fix crash by skipping second fork()
++       * Instead of calling a second fork() in the child process, replace
++       * execv() with posix_spawn(). posix_spawn() does not call any atfork
++       * handlers so the atfork handler that crashes will be skipped.  */
++#else /*HAVE_MACOS_SYSTEM*/
+       if ((pid = fork ()) == 0)
+       {
++#endif /*HAVE_MACOS_SYSTEM*/
+         /* Child.  */
+           int max_fds = -1;
+           int fd;
+@@ -664,6 +716,9 @@
+               close (fd);
+           }
+ 
++#if HAVE_MACOS_SYSTEM
++        _exit(posix_spawn(NULL, path, NULL, NULL, argv, environ));
++#else /*HAVE_MACOS_SYSTEM*/
+         execv (path, (char *const *) argv);
+         /* Hmm: in that case we could write a special status code to the
+            status-pipe.  */
+@@ -674,6 +729,7 @@
+       _exit (1);
+       else
+       _exit (0);
++#endif /*HAVE_MACOS_SYSTEM*/
+     }
+ 
+   TRACE_LOG  ("waiting for child process pid=%i", pid);

Reply via email to