Skip Menu |

This queue is for tickets about the FCGI-ProcManager CPAN distribution.

Report information
The Basics
Id: 128322
Status: new
Priority: 0/
Queue: FCGI-ProcManager

People
Owner: Nobody in particular
Requestors: gragory.mail [...] gmail.com
Cc:
AdminCc:

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



Subject: Race condition with signal handling
Hello! I found the race condition which can provide: 1. segmentation fault in child 2. memory leak 3. hang on in sig handler subroutine The problem manifests itself because of unsafe signal processing via sigaction. The signal handler call $hash{key}++ and the main code calls if($hash{key}), and if we receive the signal during the perl's $hash{key} operation, we will change the same $hash{key}, and will get undefined behavior. In the attachment (test.pl) you can see a script which shows how the race works. Some outputs of running this script perl-5.26.2 $ perl test.pl FastCGI: manager (pid 19350): initialized FastCGI: manager (pid 19350): server (pid 19351) started FastCGI: server (pid 19351): initialized Attempt to free unreferenced scalar: SV 0x55a2611743c0 at /usr/lib64/perl5/vendor_perl/5.26.2/FCGI/ProcManager.pm line 585. Attempt to free unreferenced scalar: SV 0x55a2611743c0 at test.pl line 29. Attempt to free unreferenced scalar: SV 0x55a2611743d8 at /usr/lib64/perl5/vendor_perl/5.26.2/FCGI/ProcManager.pm line 585. Attempt to free unreferenced scalar: SV 0x55a2611743f0 at /usr/lib64/perl5/vendor_perl/5.26.2/FCGI/ProcManager.pm line 585. pid exited with status 11 FastCGI: manager (pid 19350): perl-5.22.1 $ perl test.pl FastCGI: manager (pid 364262): initialized FastCGI: manager (pid 364262): server (pid 364263) started FastCGI: server (pid 364263): initialized pid exited with status 139 FastCGI: manager (pid 364262): $ perl /test.pl FastCGI: manager (pid 364264): initialized FastCGI: manager (pid 364264): server (pid 364265) started FastCGI: server (pid 364265): initialized Attempt to free unreferenced scalar: SV 0x23d9fc0, Perl interpreter: 0x21c6010 at ./test.pl line 31. pid exited with status 139 FastCGI: manager (pid 364264): $ perl test.pl FastCGI: manager (pid 367294): initialized FastCGI: manager (pid 367294): server (pid 367295) started FastCGI: server (pid 367295): initialized panic: leave_scope inconsistency 63 at /usr/share/perl5/FCGI/ProcManager.pm line 541. pid exited with status 139 FastCGI: manager (pid 367294): $ perl test.pl FastCGI: manager (pid 367326): initialized FastCGI: manager (pid 367326): server (pid 367327) started FastCGI: server (pid 367327): initialized Attempt to free unreferenced scalar: SV 0x29d5068, Perl interpreter: 0x27ce010 at ./test.pl line 29. Attempt to free unreferenced scalar: SV 0x29d5080, Perl interpreter: 0x27ce010 at ./test.pl line 29. pid exited with status 139 FastCGI: manager (pid 367326): The solution is to add SIGTERM, SIGHUP into sigprocmask before checking the receieved signal and to restore old_procmask after check (see attachment patch)
Subject: patch
Download patch
application/octet-stream 1.1k

Message body not shown because it is not plain text.

Subject: test.pl
#!/usr/bin/env perl use strict; use warnings; package ProcManager::Test; use parent 'FCGI::ProcManager'; use POSIX qw(:sys_wait_h); sub pm_wait { my ($this) = FCGI::ProcManager::self_or_default(@_); while (1) { kill HUP => keys %{$this->{PIDS}}; my $pid; while (($pid = waitpid(-1, WNOHANG)) > 0) { print "pid exited with status $?\n"; delete $this->{PIDS}->{$pid}; $this->pm_abort(); } } } package main; my $manager = ProcManager::Test->new({n_processes => 1}); $manager->pm_manage(); while (1) { 1 while $manager->pm_received_signal("HUP"); }
Втр Янв 22 06:45:26 2019, gragory.mail@gmail.com писал: Show quoted text
> Hello! > I found the race condition which can provide: > 1. segmentation fault in child > 2. memory leak > 3. hang on in sig handler subroutine > > The problem manifests itself because of unsafe signal processing via > sigaction. The signal handler call $hash{key}++ and the main code > calls if($hash{key}), and if we receive the signal during the perl's > $hash{key} operation, we will change the same $hash{key}, and will get > undefined behavior. In the attachment (test.pl) you can see a script > which shows how the race works. Some outputs of running this script > > perl-5.26.2 > $ perl test.pl > FastCGI: manager (pid 19350): initialized > FastCGI: manager (pid 19350): server (pid 19351) started > FastCGI: server (pid 19351): initialized > Attempt to free unreferenced scalar: SV 0x55a2611743c0 at > /usr/lib64/perl5/vendor_perl/5.26.2/FCGI/ProcManager.pm line 585. > Attempt to free unreferenced scalar: SV 0x55a2611743c0 at test.pl line > 29. > Attempt to free unreferenced scalar: SV 0x55a2611743d8 at > /usr/lib64/perl5/vendor_perl/5.26.2/FCGI/ProcManager.pm line 585. > Attempt to free unreferenced scalar: SV 0x55a2611743f0 at > /usr/lib64/perl5/vendor_perl/5.26.2/FCGI/ProcManager.pm line 585. > pid exited with status 11 > FastCGI: manager (pid 19350): > > perl-5.22.1 > $ perl test.pl > FastCGI: manager (pid 364262): initialized > FastCGI: manager (pid 364262): server (pid 364263) started > FastCGI: server (pid 364263): initialized > pid exited with status 139 > FastCGI: manager (pid 364262): > > $ perl /test.pl > FastCGI: manager (pid 364264): initialized > FastCGI: manager (pid 364264): server (pid 364265) started > FastCGI: server (pid 364265): initialized > Attempt to free unreferenced scalar: SV 0x23d9fc0, Perl interpreter: > 0x21c6010 at ./test.pl line 31. > pid exited with status 139 > FastCGI: manager (pid 364264): > > $ perl test.pl > FastCGI: manager (pid 367294): initialized > FastCGI: manager (pid 367294): server (pid 367295) started > FastCGI: server (pid 367295): initialized > panic: leave_scope inconsistency 63 at > /usr/share/perl5/FCGI/ProcManager.pm line 541. > pid exited with status 139 > FastCGI: manager (pid 367294): > > $ perl test.pl > FastCGI: manager (pid 367326): initialized > FastCGI: manager (pid 367326): server (pid 367327) started > FastCGI: server (pid 367327): initialized > Attempt to free unreferenced scalar: SV 0x29d5068, Perl interpreter: > 0x27ce010 at ./test.pl line 29. > Attempt to free unreferenced scalar: SV 0x29d5080, Perl interpreter: > 0x27ce010 at ./test.pl line 29. > pid exited with status 139 > FastCGI: manager (pid 367326): > > The solution is to add SIGTERM, SIGHUP into sigprocmask before > checking the receieved signal and to restore old_procmask after check > (see attachment patch)
And maby add ->safe(1) and ->mask(POSIX::SigSet->new(SIGTERM, SIGHUP)) to sigaction objects