From: Nick Cleaton Date: Sun, 7 Mar 2010 14:27:31 +0000 (+0100) Subject: Further improvements to the security fix in 16ac9e9a4185d3315152ade5286d4dd3d25bff32 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=305aa7ae7250ccd59885f2ac5fa4f5fde410f98a;p=p5sagit%2Fp5-mst-13.2.git Further improvements to the security fix in 16ac9e9a4185d3315152ade5286d4dd3d25bff32 - Destroy all stash entries at once to avoid race conditions. - For that we save away reference to stashes entries (not stash entries themselves like previously, to avoid trigerring tie methods) - Don't skip sub-packages that might be named "main::" --- diff --git a/dist/Safe/Safe.pm b/dist/Safe/Safe.pm index 059c6fb..3045832 100644 --- a/dist/Safe/Safe.pm +++ b/dist/Safe/Safe.pm @@ -321,16 +321,17 @@ sub varglob { } sub _clean_stash { - my ($root) = @_; - my @destroys; + my ($root, $saved_refs) = @_; + $saved_refs ||= []; no strict 'refs'; - push @destroys, delete ${$root}{DESTROY}; - push @destroys, delete ${$root}{AUTOLOAD}; - push @destroys, delete ${$root}{$_} for grep /^\(/, keys %$root; + foreach my $hook (qw(DESTROY AUTOLOAD), grep /^\(/, keys %$root) { + push @$saved_refs, \*{$root.$hook}; + delete ${$root}{$hook}; + } for (grep /::$/, keys %$root) { - next if $_ eq 'main::'; - _clean_stash($root.$_); + next if \%{$root.$_} eq \%$root; + _clean_stash($root.$_, $saved_refs); } }