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

Alejandro Colomar via Mutt-dev <[email protected]>
Newsgroups gmane.mail.mutt.devel
Message-ID <aed9xnpJldwTEl2t@devuan>
Hi Kevin,

On 2026-04-21T21:20:17+0800, Kevin J. McCarthy wrote:
> 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.

AFAIK, these days getrandom(2) doesn't block except in weird cases at
boot.

The manual page random(7) needs to be updated, but I need someone expert
in the matter to send and discuss patches.  (CC += Mingye)

BTW, Greg, would you be able to help with that?

> 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.

It makes sense to start with getrandom(2), since as you say, it's easy
to swap to it.


Cheers,
Alex

> 
> 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



-- 
<https://www.alejandro-colomar.es>
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEES7Jt9u9GbmlWADAi64mZXMKQwqkFAmnnfsoACgkQ64mZXMKQ
wql7XA//ckZoFWdJrv+4Xr0Mt5HKhv7XxSNqMPBEpQge9dCMRfOmM3rog2aJsLwZ
/GM1LUv0eqcuHY92RcEpt9e6oj/XOeE5+UnSp/r0UYuX38lY/dMHGa4mubcUH3sc
fnYWFxLC/97A1QwqPscNDE6gBl6Kzf+XOqE+FgA5G9dkqsJ/KsGASQSYO6IkVZWq
VQxmU2FhnEmrk0t+YIcCBLgR0IJMmlwT2mCmysa3P+kZ3fwNoaC39lYArRt9349f
RaL3Oz+yuloxJ8ZIA8DRaIPJCppwAux9YIkW9HAvmMuuTVQvRmj5R0CjJim+eMi6
chPLyZHfCY5Iv4pUxy0GMllTGOcbsCMqmWyBAW2BGTwgx/13Wq1ZaIOeqzYU+6ZY
ekp7murzz0TYS+zvWOZBeiZ1gzF5AnIu+olumdg3VkiRQsM/x4D/JLIKZ7wqxZxf
tjY3uU/BEM5Fzp9uhzl5joxzzZtiLANk5T5dnoMdBvDDaTtKqhT5vBdRPRy+5s4m
b5dJB2Tqs0dcdS2GnXEEmnKYudhS2s+ui0107UMfDCwDlK7zL5LTHGDiuIoVXKqi
SnpbFCjvB6QSP2ze8JjNnSNyTMKwJntMHW017u31UI2GVeRYRVApxjjCUZS/EcDw
aEH/QMVuQSS+hBfngeY561lTFgnUQ3HMsZgW3k4HAb4ZYK29HOg=
=nMjz
-----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.