File libgcrypt-check-re-open-dev_random-after-fork.patch of Package libgcrypt.14858

From 319f55e6e5793c59f1ba4cfe481b562bca42194d Mon Sep 17 00:00:00 2001
From: Werner Koch <wk@gnupg.org>
Date: Fri, 26 Oct 2018 13:22:16 +0200
Subject: [PATCH] random: Make sure to re-open /dev/random after a fork

* random/rndlinux.c (_gcry_rndlinux_gather_random): Detect fork and
re-open devices.
--

This mitigates about ill-behaving software which has closed the
standard fds but later dups them to /dev/null.

GnuPG-bug-id: 3491
Signed-off-by: Werner Koch <wk@gnupg.org>
---
 random/rndlinux.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

Index: libgcrypt-1.8.2/random/rndlinux.c
===================================================================
--- libgcrypt-1.8.2.orig/random/rndlinux.c
+++ libgcrypt-1.8.2/random/rndlinux.c
@@ -108,9 +108,10 @@ open_device (const char *name, int retry
 
 
 /* Note that the caller needs to make sure that this function is only
-   called by one thread at a time.  The function returns 0 on success
-   or true on failure (in which case the caller will signal a fatal
-   error).  */
+ * called by one thread at a time.  The function returns 0 on success
+ * or true on failure (in which case the caller will signal a fatal
+ * error).  This function should be entered only by one thread at a
+ * time. */
 int
 _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
                                           enum random_origins),
@@ -122,6 +123,11 @@ _gcry_rndlinux_gather_random (void (*add
   static int fd_configured = -1;
   static int only_urandom = -1;
   static unsigned char ever_opened;
+  static volatile pid_t my_pid; /* The volatile is there to make sure
+                                 * the compiler does not optimize the
+                                 * code away in case the getpid
+                                 * function is badly attributed. */
+  volatile pid_t apid;
   int fd;
   int n;
   byte buffer[768];
@@ -135,13 +141,13 @@ _gcry_rndlinux_gather_random (void (*add
    * use only urandom.  */
   if (only_urandom == -1)
     {
+      my_pid = getpid ();
       if ((_gcry_random_read_conf () & RANDOM_CONF_ONLY_URANDOM))
         only_urandom = 1;
       else
         only_urandom = 0;
     }
 
-
   if (!add)
     {
       /* Special mode to close the descriptors.  */
@@ -163,6 +169,25 @@ _gcry_rndlinux_gather_random (void (*add
       return 0;
     }
 
+  /* Detect a fork and close the devices so that we don't use the old
+   * file descriptors.  Note that open_device will be called in retry
+   * mode if the devices was opened by the parent process.  */
+  apid = getpid ();
+  if (my_pid != apid)
+    {
+      if (fd_random != -1)
+        {
+          close (fd_random);
+          fd_random = -1;
+        }
+      if (fd_urandom != -1)
+        {
+          close (fd_urandom);
+          fd_urandom = -1;
+        }
+      my_pid = apid;
+    }
+
 
   /* First read from a hardware source.  However let it account only
      for up to 50% (or 25% for RDRAND) of the requested bytes.  */