[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