sergot / openssl

OpenSSL bindings for Perl 6
MIT License
14 stars 31 forks source link

Explicitly pass a buffer to ERR_error_string [fix segfault] #9

Closed ugexe closed 9 years ago

ugexe commented 9 years ago

It seems that ERR_error_string will randomly segfault when it is called:

# ok - port 443
nickl@localhost:~/perl6/io-socket-ssl$ perl6 -Ilib -e 'use IO::Socket::SSL; my $ssl = IO::Socket::SSL.new(:host<github.com>, :port(443));'

# not ok - port 80
# error is expected
nickl@localhost:~/perl6/io-socket-ssl$ perl6 -Ilib -e 'use IO::Socket::SSL; my $ssl = IO::Socket::SSL.new(:host<github.com>, :port(80));'
err code: 336130315
error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number

# not ok - port 80
# exactly the same command as before, but this time it segfaults
nickl@localhost:~/perl6/io-socket-ssl$ perl6 -Ilib -e 'use IO::Socket::SSL; my $ssl = IO::Socket::SSL.new(:host<google.com>, :port(80));'
err code: 336130315
Segmentation fault

This behavior can be averted by putting some statements (like say 1; say 1; say 1;) between:

my $e = OpenSSL::ERR::ERR_get_error();
loop {
    # say 1;
    # say 1;
    # say 1;

    # ...

    # or you can put the statements outside loop
    # as long as they are inbetween $e =

    # random segfault unless `say` comments above uncommented
    say OpenSSL::ERR::ERR_error_string($e);
}

The less statements between the two, the more often the segfault will occur.

According to to the C header definition for ERR_error_string, it can accept a 'char *ret' argument which was not being passed. I'd guess it this problem has something to do with nativecall and how buffer/char is used by ERR_error_string_n().

In any case, this PR appears to prevent this particular segfault from reoccuring for me. But I can't explain exactly why.