[openssl-dev] [openssl.org #3771] bug: s_client loop at 100% cpu
Rainer Jung
rainer.jung at kippdata.de
Mon Mar 30 08:27:24 UTC 2015
Am 30.03.2015 um 09:51 schrieb John Denker via RT:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Contrast the following two examples:
>
> #1:
> time : | openssl s_client -connect www.openssl.org:443 >& /dev/null
>
> real 0m0.545s
> user 0m0.000s
> sys 0m0.000s
>
> #2:
> time : | openssl s_client -quiet -connect www.openssl.org:443 >& /dev/null
>
> real 0m21.255s
> user 0m9.500s
> sys 0m11.180s
>
> - -----------
>
> Note the numerology: 21.225 - 9.5 - 11.18 = 0.545
> That means that if you discount the half second it takes to actually
> fetch the certificate, s_client was using 100% of the cpu the whole
> time ... for more than 20 seconds.
>
> I cannot imagine why it loops when "-quiet" is specified and not
> otherwise. I cannot imagine why it loops for 20.5 seconds instead
> of 20.5 minutes or 20.5 hours.
>
> This is 100% reproducible chez moi, although the timings naturally
> vary by a little bit.
>
>
> (gdb) where
> #0 0x00007ffff7903653 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:81
> #1 0x0000000000434d73 in s_client_main (argc=0, argv=0x7fffffffe680) at s_client.c:1794
> #2 0x00000000004039a8 in do_cmd (prog=0x990540, argc=4, argv=0x7fffffffe660) at openssl.c:470
> #3 0x00000000004035b8 in main (Argc=4, Argv=0x7fffffffe660) at openssl.c:366
That's maybe due to your chosen pipe shell construct. I can see the same
behavior, if I choose to let s_client read from /dev/null and set
"-quiet". It then loops trying to read from /dev/null, getting 0 bytes
but not EOF back. Without -quiet this does not happen. More precisely it
seems to happen with -ign_eof, which is set as a side effect of -quiet.
Reading from /dev/null without -ign_eof lets s_client end immediately
after the connect, with -ign_eof it hangs for 20 seconds (web server
timeout?) and eats 1 CPU during that time doing a lot of reads from
/dev/null.
The behavior is probably due to the following code snippet in s_client:
...
i = raw_read_stdin(cbuf, BUFSIZZ);
if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) {
BIO_printf(bio_err, "DONE\n");
ret = 0;
goto shut;
}
Here I expect i==0, so without -ign_eof the code breaks the loop and
goes to "shut".
So this probably works as designed and when just running
openssl s_client -connect www.openssl.org:443
you shouldn't notice CPU hogging. Why -ign_eof is set as a side effect
of -quiet I do not know.
Regards,
Rainer
More information about the openssl-dev
mailing list