Skip Menu |

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

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

People
Owner: Nobody in particular
Requestors: TODDR [...] cpan.org
Cc:
AdminCc:

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



Subject: dh initialization at BEGIN time breaks perlcc and other perl code compilers.
Sorry for the slow report. This broke in 1.958. When you re-run a program with a frozen handle on a new process, it causes a segfault. Patch coming shortly.
On Wed May 07 17:49:40 2014, TODDR wrote: Show quoted text
> Sorry for the slow report. This broke in 1.958. When you re-run a > program with a frozen handle on a new process, it causes a segfault. > Patch coming shortly.
Sorry, but I don't understand what you mean with "re-run a program with a frozen handle on a new process". Can you provide some code to reproduce the problem?
Show quoted text
> Sorry, but I don't understand what you mean with "re-run a program > with a frozen handle on a new process". Can you provide some code to > reproduce the problem?
perlcc allows you to build a binary with a frozen state of the program as of the BEGIN block. This allows for very fast program execution, allowing you to run perl programs via CGI you wouldn't normally be able to do. This is the original reported issue to perlcc or B::C, which is the module. https://code.google.com/p/perl-compiler/issues/detail?id=317
From: rurban [...] x-ray.at
In detail, to reproduce it, force install perlcc (B::C) and do perlcc -S -O3 -r -e'use Net::SSLeay(); use IO::Socket::SSL(); Net::SSLeay::OpenSSL_add_ssl_algorithms(); my $ssl_ctx = IO::Socket::SSL::SSL_Context->new(SSL_server => 1); print q(ok)' $dh in %DEFAULT_SSL_SERVER_ARGS will be a random handle to the memory location of the Net::SSLeay library, and this handle needs to be initialized at run-time, not compile-time. Basically the same issue as [cpan #94069] with Net::DNS and Encode, using Encode XS handles at compile-time.
On Wed May 07 18:32:04 2014, rurban@x-ray.at wrote: Show quoted text
> In detail, to reproduce it, force install perlcc (B::C) and do > > perlcc -S -O3 -r -e'use Net::SSLeay(); > use IO::Socket::SSL(); > Net::SSLeay::OpenSSL_add_ssl_algorithms(); > my $ssl_ctx = IO::Socket::SSL::SSL_Context->new(SSL_server => 1); > print q(ok)' > > $dh in %DEFAULT_SSL_SERVER_ARGS will be a random handle to the memory > location of the Net::SSLeay library, and this handle needs to be > initialized at run-time, not compile-time.
Hi, as far as I understand your problem it boils down to using non-perl Code (e.g. XS module) and perlcc fails to freeze the state of this code and restore it later. In this case I don't think that the issue can be solved for IO::Socket::SSL. It could be resolved for the special case of the SSL_dh parameter, but there are other initializations in the code which cannot be fixed this way: - when loading IO::Socket::SSL it will run various initialization, e.g. to add algorithms, load error strings etc. - According to Net::SSLeay (see the part about threading) these kind of initializations should be done in the main program, and not in each thread in the case of multithreaded programs. Otherwise this might lead to strange crashes (and I've seen such crashes when people try to require IO::Socket::SSL per thread). - so just doing these initializations on first use, like you do with the SSL_dh parameter, is not an option, because the first use might not be in the main thread. So currently I see no way to solve the problem in a way which does not introduce worse problems. And just fixing the SSL_dh case and leaving the other problems in also not an option for me, because it only fixes part of the problem, but obscures the rest so it might make it even harder too debug. That's why I will set this bug for now at rejected, but if you have a good idea, how the whole issue can be resolved without creating new problems feel free to reopen it. Sorry for not being that helpful, Steffen
On Thu May 08 14:18:17 2014, SULLR wrote: Show quoted text
> On Wed May 07 18:32:04 2014, rurban@x-ray.at wrote:
> > In detail, to reproduce it, force install perlcc (B::C) and do > > > > perlcc -S -O3 -r -e'use Net::SSLeay(); > > use IO::Socket::SSL(); > > Net::SSLeay::OpenSSL_add_ssl_algorithms(); > > my $ssl_ctx = IO::Socket::SSL::SSL_Context->new(SSL_server => 1); > > print q(ok)' > > > > $dh in %DEFAULT_SSL_SERVER_ARGS will be a random handle to the memory > > location of the Net::SSLeay library, and this handle needs to be > > initialized at run-time, not compile-time.
> > Hi, > as far as I understand your problem it boils down to using non-perl > Code (e.g. XS module) and perlcc fails to freeze the state of this > code and restore it later. In this case I don't think that the issue > can be solved for IO::Socket::SSL. It could be resolved for the > special case of the SSL_dh parameter, but there are other > initializations in the code which cannot be fixed this way: > - when loading IO::Socket::SSL it will run various initialization, > e.g. to add algorithms, load error strings etc. > - According to Net::SSLeay (see the part about threading) these kind > of initializations should be done in the main program, and not in each > thread in the case of multithreaded programs. Otherwise this might > lead to strange crashes (and I've seen such crashes when people try to > require IO::Socket::SSL per thread). > - so just doing these initializations on first use, like you do with > the SSL_dh parameter, is not an option, because the first use might > not be in the main thread. > > So currently I see no way to solve the problem in a way which does not > introduce worse problems. And just fixing the SSL_dh case and leaving > the other problems in also not an option for me, because it only fixes > part of the problem, but obscures the rest so it might make it even > harder too debug. > > That's why I will set this bug for now at rejected, but if you have a > good idea, how the whole issue can be resolved without creating new > problems feel free to reopen it. > > Sorry for not being that helpful, > Steffen
<rant>I really start wondering now why most germans are so unhelpful and don't understand the simple technical issues and solutions behind.</rant> Only the compile-time dh handle is a problem, not any other Net::SSLeay handles. And only IO::Socket::SSL is to blame, not any other causes. For people running into this problem (creating a compiled IO::Socket::SSL server), please use our dropin fork cPanel::IO::Socket::SSL. -- Reini Urban
Show quoted text
> <rant>I really start wondering now why most germans are so unhelpful > and don't understand the simple technical issues and solutions > behind.</rant>
I feel sorry for you that you have this kind of experiences. These germans must be really terrible. Show quoted text
> Only the compile-time dh handle is a problem, not any other > Net::SSLeay handles. And only IO::Socket::SSL is to blame, not any > other causes.
I will try to illustrate my point with a simple code: use IO::Socket::SSL; my $cl = IO::Socket::SSL->new("www.google.de:443") or die "$!,$SSL_ERROR"; print $cl->peer_certificate("subject"); This code connects to google and prints the certificate information. It works fine with plain perl, e.g. without perlcc. It also compiles without problems with perlcc but the compiled program will not work. It will not crash (there is is SSL_dh* on the client side, so it is not affected by the issue) but it will not be able to SSL connect to google. But, if you add Net::SSLeay::add_ssl_algorithms() before trying to connect, the compiled version will work too because this function initializes the internal OpenSSL structures. And while these structures already got initialized by calling this function inside IO::Socket::SSL during compile time, the initialization got lost during compilation with perlcc because it is inside a C library and not in Perl variables. With the argumentation from https://github.com/noxxi/p5-io-socket-ssl/pull/13 one should move the OpenSSL initialization from compile time to run time, i.e. do it on first use like done with SSL_dh in this patch. But inside a multithreaded program the first use might not happen in the main thread, which might cause the application to crash (see thread safety documentation for Net::SSLeay and OpenSSL). So a safe place might be to do any such initialization but before run time, so that it will be the first thing the compiled binary does, i.e. before executing any user code which depends on the finished initialization. From experiments with perlcc it looks like, that INIT would be the correct place to do this, am I right? In this case I could reopen the bug and try to move all the initialization into INIT. Regards, the terrible german.
Show quoted text
> From experiments with perlcc it looks like, that INIT > would be the correct place to do this, am I right? In this case I > could reopen the bug and try to move all the initialization into INIT.
fixed in 1.995 by moving the relevant parts into INIT section. This fixes both the problem with SSL_dh and additionally it is no longer needed to explicitly call Net::SSLeay::add_ssl_algorithms().
Show quoted text
> > fixed in 1.995 by moving the relevant parts into INIT section. This > fixes both the problem with SSL_dh and additionally it is no longer > needed to explicitly call Net::SSLeay::add_ssl_algorithms().
Unfortunately this breaks if IO::Socket::SSL is not included with 'use' but 'require', with and without perlcc. So with 1.996 there is a separate function init which is called at compile time and need to be called explicitly if the module is included with 'use' and perlcc is used. This behavior is also documented. If perlcc would make a variable available, so that one could detect if the code running from a compiled binary one could probable remove this workaround. At the moment one could compare the process ids from the BEGIN block with the INIT block, but this only works in most cases and fails if the pid of perlcc matches the pid of the process if executed later.
Show quoted text
> If perlcc would make a variable available, so that one could detect if > the code running from a compiled binary one could probable remove this > workaround. At the moment one could compare the process ids from the > BEGIN block with the INIT block, but this only works in most cases and > fails if the pid of perlcc matches the pid of the process if executed > later.
Fortunatly I've found out that for all supported version of Net::SSLeay library_init() returns if the initialization was needed or not and does this based on a variable in C-code. This makes it possible to encapsulate the support for perlcc completly inside IO::Socket::SSL, i.e. no more workarounds needed for a user of perlcc. It also does not need to explicitly call Net::SSLeay::OpenSSL_add_ssl_algorithms with perlcc, like still needed by cPanel::IO::Socket::SSL.