From 44c988b2c608855db5dd5000050b24476a73411e Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 25 Jul 2022 10:05:23 -0400 Subject: [PATCH] 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 --- src/perl/lib/OpenSRF/Server.pm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 = ''; -- 2.11.0