Re: Random MIME boundary needed? (was: Security findings)

"Kevin J. McCarthy" <[email protected]>
Newsgroups gmane.mail.mutt.devel
Message-ID <aed5kfh65zdpnkIM@qinghai>
On Tue, Apr 21, 2026 at 02:32:54PM +0200, Alejandro Colomar via Mutt-dev wrote:
> On 2026-04-21T12:49:43+0200, Greg KH wrote:
> > On Tue, Apr 21, 2026 at 06:13:44PM +0800, Kevin J. McCarthy wrote:
> > > Perhaps, as Greg KH suggested we could try checking for getrandom(), and
> > > then arc4random_buf(), and if both are missing I guess fall back to what
> > > we have now?
> >
> > I would recommend that.  I would hope that most modern systems have
> > getrandom() by now.
>
> BTW, getentropy(3) --which itself calls getrandom(2)-- was added to both
> glibc and musl in the same versions as getrandom(2).  Should we prefer
> getentropy(3) or getrandom(2)?  getentropy(3) seems to have been
> standardized by POSIX.1-2024 --which I'll document in the manual page
> right now--.

One tiny advantage for getrandom(2) is the GRND_NONBLOCK flag.  But
perhaps there isn't a "real" issue there for the request sizes mutt will
be passing.

I've already been playing with the code some tonight.  This is just a
WIP below, compiled but not tested.  Of course, it would be easy to swap
to using getentropy() if you and Greg think that's a better idea.

Subject: [PATCH] WIP: new random calls

---
  configure.ac  |  4 ++++
  mutt_random.c | 44 +++++++++++++++++++++++++++++++++-----------
  mutt_random.h |  3 +--
  3 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/configure.ac b/configure.ac
index 5b455aff..456b916a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -423,6 +423,10 @@ AC_CHECK_TYPE(ssize_t, [],
  
  AC_CHECK_FUNCS(fgetpos memmove memccpy setegid srand48 strerror)
  
+dnl random data functions
+AC_CHECK_HEADERS(sys/random.h)
+AC_CHECK_FUNCS(getrandom arc4random_buf)
+
  AC_REPLACE_FUNCS([setenv strcasecmp strdup strsep strtok_r wcscasecmp])
  AC_REPLACE_FUNCS([strcasestr mkdtemp])
  
diff --git a/mutt_random.c b/mutt_random.c
index 52ba44e5..441a2de8 100644
--- a/mutt_random.c
+++ b/mutt_random.c
@@ -25,25 +25,31 @@
  
  #include <fcntl.h>
  #include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
+#ifdef HAVE_SYS_TIME_H
+  #include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_RANDOM_H
+  #include <sys/random.h>
+#endif
  
  static uint32_t z[4]; /* Keep state for LFRS113 PRNG */
  static int rand_bytes_produced = 0;
  static time_t time_last_reseed = 0;
  
-void mutt_random_bytes(char *random_bytes, int length_requested)
+static void prng_reseed(void);
+
+
+static void prng_random_bytes(char *random_bytes, size_t length_requested)
  {
    /* Reseed every day or after more than a 100000 random bytes produced */
    if (time(NULL) - time_last_reseed > 86400 || rand_bytes_produced > 100000)
-    mutt_reseed();
+    prng_reseed();
  
    uint32_t b;
  
    /* The loop below is our implementation of the LFRS113 PRNG algorithm by
     * Pierre L'Ecuyer */
-  for (int i = length_requested; i > 0;)
+  for (size_t i = length_requested; i > 0;)
    {
      b    = ((z[0] <<  6) ^ z[0]) >> 13;
      z[0] = ((z[0] & 4294967294U) << 18) ^ b;
@@ -56,17 +62,17 @@ void mutt_random_bytes(char *random_bytes, int length_requested)
  
      b    = z[0] ^ z[1] ^ z[2] ^ z[3];
  
-    if (--i >= 0) random_bytes[i] = (b >> 24) & 0xFF;
-    if (--i >= 0) random_bytes[i] = (b >> 16) & 0xFF;
-    if (--i >= 0) random_bytes[i] = (b >>  8) & 0xFF;
-    if (--i >= 0) random_bytes[i] = (b)       & 0xFF;
+    if (i > 0) random_bytes[--i] = (b >> 24) & 0xFF;
+    if (i > 0) random_bytes[--i] = (b >> 16) & 0xFF;
+    if (i > 0) random_bytes[--i] = (b >>  8) & 0xFF;
+    if (i > 0) random_bytes[--i] = (b)       & 0xFF;
    }
    rand_bytes_produced += length_requested;
  
    return;
  }
  
-void mutt_reseed(void)
+static void prng_reseed(void)
  {
    uint32_t t[4];                /* Temp seed values from /dev/urandom */
    char computer_says_no = TRUE; /* Whether /dev/urandom was usable */
@@ -106,6 +112,22 @@ void mutt_reseed(void)
        z[i] ^= t[i];
  }
  
+/* Generate length_requested random bytes of data */
+void mutt_random_bytes(char *random_bytes, size_t length_requested)
+{
+#if defined(HAVE_GETRANDOM)
+  size_t res;
+
+  res = getrandom(random_bytes, length_requested, GRND_NONBLOCK);
+  if ((res == (size_t) -1) || (res < length_requested))
+    prng_random_bytes(random_bytes, length_requested);
+#elif defined(HAVE_ARC4RANDOM_BUF)
+  arc4random_buf(random_bytes, length_requested);
+#else
+  prng_random_bytes(random_bytes, length_requested);
+#endif
+}
+
  /* Generate and Base64 encode 96 random bits and fill the buffer
     output_B64 with the result. */
  void mutt_base64_random96(char output_B64[static 17])
diff --git a/mutt_random.h b/mutt_random.h
index ed9fdf29..0417e0d6 100644
--- a/mutt_random.h
+++ b/mutt_random.h
@@ -25,6 +25,5 @@ typedef union random64
  } RANDOM64;
  
  void mutt_base64_random96(char output_B64[static 17]);
-void mutt_random_bytes(char *random_bytes, int length_requested);
-void mutt_reseed(void);
+void mutt_random_bytes(char *random_bytes, size_t length_requested);
  #endif
-- 
2.53.0



-- 
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEiXWpszqjeRA4XFMIre92hIAxa9oFAmnneZEACgkQre92hIAx
a9rcYw//QBujchbt8ua2NWVt68yRkqLLZye2W7/oIFbqpqyB07M+otuwyQGeh/SF
U0STT71U6dvhglZWwlDp0CTg/2/DpnwNDYy5d/JGZSQ/n4n5iPd3YIAtJHU1OUDO
tfCy6CUnpdeSEaCWq0Sa1m/tsVbEWAqHEhZs2fPjinQ16n51UGv2FZxQIn66c1ct
/mDRXQKBwBrwEKNaj1hdEKGq/NF7AiwlzKhygygR1mxkQi64E5J+LMy3gpeFm/sS
7rr24/1s8y5x8aeYfJkw6IC191liIfojutfPuVQJX4unhLb72n7UQCjy6x+jt//L
m/5X5UBLuwFkIxdh6iG5h6AkqjQQsjDjOTQzv+BPoEXLBi9uwjGMKjI979BCECMg
9JkA+zuc9//rQamifwlwAFIluC/8ZNa0FlofA5Xj+u7vI6koWmiPOcpx4OxROOIs
/6VjUHK+TnUeOQtyseLCdsTfwOTDgjMZjJcOZz4qPO7UXHqqJqVgF8+S45FtWjVG
FWqEF7bFi3QLcQ7NrvGb/o8ZtI45y/yfI6GzpiNo1V1exOtbOu1g6ECNj99ljQJa
4KRr73WoKWTpHItVylcoEdm+qUmPfQdWMncA2VNW5gWz/4IG+coRbQczu0bIBdui
ji/sBY1ueZmbiD0jJAh5+dnvfsZ8bw4PUihM3q1wWilJCRQ4S74=
=Jdn1
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.