From: Bill Erickson Date: Mon, 25 Jul 2022 14:05:23 +0000 (-0400) Subject: LP1953044 Avoid ref to free'd array in Server child maintenance X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=refs%2Fheads%2Fuser%2Fberick%2Flp1953044-loop-freed-value;p=working%2FOpenSRF.git LP1953044 Avoid ref to free'd array in Server child maintenance The Server active_list array is replaced / rebuilt during child process maintenance. Because of this, referencing the array ref can lead to the below error if child process maintance occurs via signal mid-loop. server: died with error Use of freed value in iteration at /usr/lib/x86_64-linux-gnu/perl/5.28/IO/Select.pm line 70. Avoid requiring array dereferencing on a potentially freed value by creating a local array containing the original contents of idle_list. Additionally, sanity check the child objects to verify they are not in the middle of getting cleaned up. Signed-off-by: Bill Erickson --- diff --git a/src/perl/lib/OpenSRF/Server.pm b/src/perl/lib/OpenSRF/Server.pm index 52c53d2..0078fbc 100644 --- a/src/perl/lib/OpenSRF/Server.pm +++ b/src/perl/lib/OpenSRF/Server.pm @@ -422,7 +422,14 @@ sub check_status { # refresh the read_set handles in case we lost a child in the previous iteration my $read_set = IO::Select->new; - $read_set->add($_->{pipe_to_child}) for @{$self->{active_list}}; + + # Copy the array so there's no chance we try to reference a + # free'd array ref in the loop below as a result of child + # process maintenance. + my @active = @{$self->{active_list}}; + + $read_set->add($_->{pipe_to_child}) for + grep {$_ && $_->{pipe_to_child}} @active; if(my @handles = $read_set->can_read(($block) ? undef : 0)) { my $pid = '';