Hi Lukas,

On 05/23/2018 09:48 PM, Lukas Tribus wrote:
> Hello,
> 
> 
> On 23 May 2018 at 18:29, Emeric Brun <[email protected]> wrote:
>> This issue was due to openssl-1.1.1 which re-seed after an elapsed time or 
>> number of request.
>>
>> If /dev/urandom is used as seeding source when haproxy is chrooted it fails 
>> to re-open /dev/urandom ....
>>
>> By defaut the openssl-1.1.1 configure script uses the syscall getrandom as 
>> seeding source and fallback on /dev/urandom if not available.
>>
>> So you don't face the issue if your openssl-1.1.1 is compiled to use 
>> getrandom
>>
>> But getrandom syscall is available only since kernel > 3.17 and the main 
>> point: for glibc > 2.25.
>>
>> With openssl-1.1.1 you can check this this way:
>> # ./openssl-1.1.1/openssl version -r
>> Seeding source: getrandom-syscall
> 
> I have glibc 2.23 (Ubuntu 16.04) and openssl shows "os-specific", even
> if kernel headers are installed while compiling, yet -pre6 does not
> hang for me in chroot (-pre4 did):
> 
> lukas@dev:~/libsslbuild/bin$ uname -r
> 4.4.0-109-generic
> lukas@dev:~/libsslbuild/bin$ ./openssl version
> OpenSSL 1.1.1-pre6 (beta) 1 May 2018
> lukas@dev:~/libsslbuild/bin$ ./openssl version -r
> Seeding source: os-specific
> lukas@dev:~/libsslbuild/bin$
> 
> 
> But, stracing haproxy shows that the library IS ACTUALLY using
> getrandom(). So the "Seeding source" output of the executable is
> wrong. Gonna dig into this as well, but seeing how my haproxy
> executable uses getrandom() calls, this perfectly explains why I did
> not see this in -pre6 (which has the build-workaround for < libc 2.25,
> while pre4 did not, so it did not use the getrandom() call).

in pre6 there is a news wrapping function on getrandom which have different 
fallback way to use the syscall.

Perhaps the openssl -r output depends of that (if getrandom was found from 
glibc or if a syscall loaded from a different way and considered os-specific).

@Lukas Which build-workarround did you use?

In my case i've patched openssl to define SYS_getrandom (depending of the arch) 
and i set --with-rand-seed=getrandom

You may have a more elegant way to do that without a patch.

/*
 * syscall_random(): Try to get random data using a system call
 * returns the number of bytes returned in buf, or <= 0 on error.
 */
int syscall_random(void *buf, size_t buflen)
{
#  if defined(OPENSSL_HAVE_GETRANDOM)
    return (int)getrandom(buf, buflen, 0);
#  endif

#  if defined(__linux) && defined(SYS_getrandom)
    return (int)syscall(SYS_getrandom, buf, buflen, 0);
#  endif

#  if defined(__FreeBSD__) && defined(KERN_ARND)
    return (int)sysctl_random(buf, buflen);
#  endif

   /* Supported since OpenBSD 5.6 */
#  if defined(__OpenBSD__) && OpenBSD >= 201411
    return getentropy(buf, buflen);
#  endif

    return -1;
}

My patch:
--- openssl-1.1.1-pre6/crypto/rand/rand_unix.c.ori      2018-05-22 
14:06:03.490771549 +0200
+++ openssl-1.1.1-pre6/crypto/rand/rand_unix.c  2018-05-22 14:14:33.133237079 
+0200
@@ -173,6 +173,26 @@
 #   define OPENSSL_HAVE_GETRANDOM
 #  endif

+# if defined(__linux)
+#   include <sys/syscall.h>
+#if !defined(SYS_getrandom)
+#if !defined(__NR_getrandom)
+#if defined(__powerpc__) || defined(__powerpc64__)
+#define __NR_getrandom 236
+#elif defined(__sparc__) || defined(__sparc64__)
+#define __NR_getrandom 347 
+#elif defined(__x86_64__)
+#define __NR_getrandom 318
+#elif defined (__i386__)
+#define __NR_getrandom 355
+#elif defined (__s390__) || defined(__s390x__)
+#define __NR_getrandom 249
+#endif /* $arch */
+#endif /* __NR_getrandom */
+#   define SYS_getrandom __NR_getrandom
+#endif
+#endif
+
 #  if defined(OPENSSL_HAVE_GETRANDOM)
 #   include <sys/random.h>
 #  endif
~


> 
> 
> @Sander it looks like openssl folks won't change their mind about
> this. You have to either upgrade to a kernel more recent than 3.17 so
> that getrandom() can be used, or make /dev/xrandom available within
> your chroot.
> 
> 
> 
> Lukas
> 

Emeric

Reply via email to