[Pkg-openssl-devel] Re: OpenSSL bug in libcrypto.so:RAND_poll()
crashes apache2 @ startup
Christoph Martin
martin at uni-mainz.de
Tue Apr 4 08:36:53 UTC 2006
Hi Vito,
vito at hostway.com schrieb:
> Hello Christoph,
>
> Included below is an email I've already submitted to openssl-bugs at openssl.org,
> you may want to get the debian package updated to fix this bug for debian users.
Thanks for your report and the patch. I did not see any feedback on your
mail to openssl-bugs. Did you get any reply on your patch proposal?
Christoph
> -------------------------------------------------------------------------
>
> Hello,
>
> I have found a bug in libcrypto.so which causes Apache2 to crash or
> deadlock when a few hundred virtual hosts are configured in a
> SSL-enabled Apache2 instance.
>
> The problem is Apache2 opens a number of files per virtual host before
> initializing libcrypto.so's random seed, given enough virtual hosts the
> file descriptor the RAND_poll() open() gets when it opens its entropy
> source will exceed FD_SETSIZE. This is a serious problem because RAND_poll()
> internally uses select() to watch for data ready to be read from the
> entropy source. When the fd exceeds FD_SETSIZE (1024 on modern linux
> systems) this will cause deadlocks / segfaults.
>
> I have created a patch to convert this to use poll() which does not have
> this limitation and is much better suited for watching a single file
> descriptor. The patch is included below. I'm not sure if you guys need
> to make this check if poll() is available in the system to keep things
> portable, but if the select() call needs to be kept when poll() is
> unavailable, it has to deal with fd >= FD_SETSIZE and not give it to
> select().
>
> This was using 0.9.7e-3sarge1 from debian stable as the original source tree, I
> checked the 0.9.7i source on openssl.org and the related code is the same.
>
> It's a relatively high priority because it makes apache2 flip out when it gets
> hit, might wanna get a fixed version out soon.
>
> Thanks for the OpenSSL project,
> Vito Caputo
> Hostway Linux Systems Developer
>
>
>
>
>
> --- rand_unix.c.orig 2006-03-21 17:01:24.000000000 -0600
> +++ rand_unix.c 2006-03-21 21:58:12.000000000 -0600
> @@ -114,6 +114,7 @@
> #include "cryptlib.h"
> #include <openssl/rand.h>
> #include "rand_lcl.h"
> +#include <sys/poll.h>
>
> #if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS))
>
> @@ -124,6 +125,7 @@
> #include <unistd.h>
> #include <time.h>
>
> +
> #ifdef __OpenBSD__
> int RAND_poll(void)
> {
> @@ -165,53 +167,37 @@ int RAND_poll(void)
> * have this. Use /dev/urandom if you can as /dev/random may block
> * if it runs out of random entries. */
>
> - for (randomfile = randomfiles; *randomfile && n < ENTROPY_NEEDED; randomfile++)
> - {
> + for (randomfile = randomfiles; *randomfile && n < ENTROPY_NEEDED; randomfile++) {
> if ((fd = open(*randomfile, O_RDONLY|O_NONBLOCK
> #ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
> our controlling tty */
> - |O_NOCTTY
> + |O_NOCTTY
> #endif
> #ifdef O_NOFOLLOW /* Fail if the file is a symbolic link */
> - |O_NOFOLLOW
> + |O_NOFOLLOW
> #endif
> - )) >= 0)
> - {
> - struct timeval t = { 0, 10*1000 }; /* Spend 10ms on
> - each file. */
> + )) >= 0) {
> int r;
> - fd_set fset;
> + struct pollfd rfd = {fd, POLLIN, 0};
> + int t = 10; /* Spend 10ms on each file. */
> +
> + /* Patched to use poll() instead of select(), sometimes this gets called
> + * with >= FD_SETSIZE files opened already (apache2).
> + * When fd is >= FD_SETSIZE the behavior is undefined (likely a buffer
> + * overflow...), I observed segfaults & deadlocks.
> + * 3/21/2006 - Vito Caputo - <vito at hostway.com> */
>
> - do
> - {
> - FD_ZERO(&fset);
> - FD_SET(fd, &fset);
> + do {
> r = -1;
>
> - if (select(fd+1,&fset,NULL,NULL,&t) < 0)
> - t.tv_usec=0;
> - else if (FD_ISSET(fd, &fset))
> - {
> - r=read(fd,(unsigned char *)tmpbuf+n,
> - ENTROPY_NEEDED-n);
> - if (r > 0)
> - n += r;
> - }
> -
> - /* Some Unixen will update t, some
> - won't. For those who won't, give
> - up here, otherwise, we will do
> - this once again for the remaining
> - time. */
> - if (t.tv_usec == 10*1000)
> - t.tv_usec=0;
> + if((poll(&rfd, 1, t) > 0) && (rfd.revents & POLLIN)) {
> + r = read(fd, (unsigned char *)tmpbuf + n, ENTROPY_NEEDED - n);
> + if(r > 0) n += r;
> }
> - while ((r > 0 || (errno == EINTR || errno == EAGAIN))
> - && t.tv_usec != 0 && n < ENTROPY_NEEDED);
> -
> + } while((r > 0 || (errno == EINTR || errno == EAGAIN)) && n < ENTROPY_NEEDED);
> close(fd);
> - }
> }
> + }
> #endif
>
> #ifdef DEVRANDOM_EGD
>
--
============================================================================
Christoph Martin, EDV der Verwaltung, Uni-Mainz, Germany
Internet-Mail: Christoph.Martin at Verwaltung.Uni-Mainz.DE
Telefon: +49-6131-3926337
Fax: +49-6131-3922856
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 252 bytes
Desc: OpenPGP digital signature
Url : http://lists.alioth.debian.org/pipermail/pkg-openssl-devel/attachments/20060404/73624476/signature.pgp
More information about the Pkg-openssl-devel
mailing list