Skip Menu |

This queue is for tickets about the IO-Socket-SSL CPAN distribution.

Report information
The Basics
Id: 120643
Status: resolved
Priority: 0/
Queue: IO-Socket-SSL

People
Owner: Nobody in particular
Requestors: 'spro^^*%*^6ut# [...] &$%*c
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Memory leak
This simple script does an HTTP request with ::INET or ::SSL. The $server variable has to be set to some test server of your own that can take the DoSing that this script inflicts on it. #!perl warn $$; use IO::Socket::INET; use IO::Socket::SSL; $server = 'put your own server here'; if (shift()) { $mod = "IO::Socket::SSL"; $port = 443 } else { $mod = "IO::Socket::INET"; $port = 80 } while (1) { my $sock = new $mod PeerAddr => $server, PeerPort => $port, or die $!; $sock->autoflush(); print $sock "GET / HTTP/1.1\r\nHost: $server\r\nContent-Length: 0\r\n\r\n"; my $response = join '', <$sock> or die $!; } __END__ If you save it as ‘test’, then $ perl test will run it with ::INET and $ perl test 1 will run it with ::SSL. If you run ‘top’ in a separate window, you can see that the memory usage stays constant with ::INET, but constantly increases with ::SSL. This is with IO::Socket::SSL version 2.047 and Net::SSLeay version 1.80. I see the same results with both perl 5.14.0 and perl 5.24.0. On another perl installation (5.10.1), I have IO::Socket::SSL 1.31 and Net::SSLeay 1.35, and there is no memory leak. I was trying to switch a long-running script over to doing secure connections, but it could never run to completion, as it would get killed after reaching 10GB of memory usage. So for now I have switched it back to using HTTP, which I don’t really want to do, but is currently my only choice.
Am Fr 17. Mär 2017, 09:37:01, SPROUT schrieb: Show quoted text
> This simple script does an HTTP request with ::INET or ::SSL. The > $server variable has to be set to some test server of your own that > can take the DoSing that this script inflicts on it. >
Thanks for reporting the problem. I can now reproduce it and it looks like that it is related to OCSP stapling. I'm working on it but as a workaround you can add SSL_ocsp_mode => SSL_OCSP_NO_STAPLE
Subject: [rt.cpan.org #120643]
Date: Fri, 14 Apr 2017 23:35:51 +0300
To: bug-IO-Socket-SSL [...] rt.cpan.org
From: xcdc dxcx <xcdcdxcx [...] gmail.com>
Hello. I think I have identified the source of the bug. The leak happens because on non-threaded perls, $use_threads is always 0 and with that, the calls to 1) $self->close and 2) Net::SSLeay::CTX_free($ctx); in destructors (sub DESTROY) are never reached. Here is a small patch for 2.047 that attempts to fix this: diff --git a/lib/IO/Socket/SSL.pm b/lib/IO/Socket/SSL.pm index 95d2350..6566636 100644 --- a/lib/IO/Socket/SSL.pm +++ b/lib/IO/Socket/SSL.pm @@ -1991,7 +1991,7 @@ sub DESTROY { my $self = shift or return; my $ssl = ${*$self}{_SSL_object} or return; delete $SSL_OBJECT{$ssl}; - if ($use_threads and delete $CREATED_IN_THIS_THREAD{$ssl}) { + if (!$use_threads or delete $CREATED_IN_THIS_THREAD{$ssl}) { $self->close(_SSL_in_DESTROY => 1, SSL_no_shutdown => 1) if ${*$self}{'_SSL_opened'}; } @@ -2825,7 +2825,7 @@ sub DESTROY { my $self = shift; if ( my $ctx = $self->{context} ) { $DEBUG>=3 && DEBUG("free ctx $ctx open=".join( " ",keys %CTX_CREATED_IN_THIS_THREAD )); - if ($use_threads and delete $CTX_CREATED_IN_THIS_THREAD{$ctx} ) { + if (!$use_threads or delete $CTX_CREATED_IN_THIS_THREAD{$ctx} ) { # remove any verify callback for this context if ( $self->{verify_mode}) { $DEBUG>=3 && DEBUG("free ctx $ctx callback" );
On Fri Apr 14 16:36:01 2017, xcdcdxcx@gmail.com wrote: Show quoted text
> Hello. I think I have identified the source of the bug. > > The leak happens because on non-threaded perls, $use_threads is always 0 > and with that, the calls to > > 1) $self->close > > and > > 2) Net::SSLeay::CTX_free($ctx); > > in destructors (sub DESTROY) are never reached. > > Here is a small patch for 2.047 that attempts to fix this: > > > > diff --git a/lib/IO/Socket/SSL.pm b/lib/IO/Socket/SSL.pm > index 95d2350..6566636 100644 > --- a/lib/IO/Socket/SSL.pm > +++ b/lib/IO/Socket/SSL.pm > @@ -1991,7 +1991,7 @@ sub DESTROY { > my $self = shift or return; > my $ssl = ${*$self}{_SSL_object} or return; > delete $SSL_OBJECT{$ssl}; > - if ($use_threads and delete $CREATED_IN_THIS_THREAD{$ssl}) { > + if (!$use_threads or delete $CREATED_IN_THIS_THREAD{$ssl}) { > $self->close(_SSL_in_DESTROY => 1, SSL_no_shutdown => 1) > if ${*$self}{'_SSL_opened'}; > } > @@ -2825,7 +2825,7 @@ sub DESTROY { > my $self = shift; > if ( my $ctx = $self->{context} ) { > $DEBUG>=3 && DEBUG("free ctx $ctx open=".join( " ",keys > %CTX_CREATED_IN_THIS_THREAD )); > - if ($use_threads and delete $CTX_CREATED_IN_THIS_THREAD{$ctx} ) { > + if (!$use_threads or delete $CTX_CREATED_IN_THIS_THREAD{$ctx} ) { > # remove any verify callback for this context > if ( $self->{verify_mode}) { > $DEBUG>=3 && DEBUG("free ctx $ctx callback" );
Thank you. That patch works for me.
Am Fr 14. Apr 2017, 16:36:01, xcdcdxcx@gmail.com schrieb: Show quoted text
> Hello. I think I have identified the source of the bug. > > The leak happens because on non-threaded perls, $use_threads is always 0 > and with that, the calls to
Thanks for the patch. It fixes one leak and is included in 2.048 (just released). The other leak I see is in Net::SSLeay OCSP handling and a patch is attached to RT#121192.