diff options
author | Nick Cleaton <nick@cleaton.net> | 2010-03-07 15:27:31 +0100 |
---|---|---|
committer | Rafael Garcia-Suarez <rgs@consttype.org> | 2010-03-07 22:14:58 +0100 |
commit | 305aa7ae7250ccd59885f2ac5fa4f5fde410f98a (patch) | |
tree | 5b17ab23fc12a138c31cee40e06ac59f776e13e0 /dist/Safe | |
parent | 47e9bce17f6c887ae177ab3580e24e7b130669c4 (diff) | |
download | perl-305aa7ae7250ccd59885f2ac5fa4f5fde410f98a.tar.gz |
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::"
Diffstat (limited to 'dist/Safe')
-rw-r--r-- | dist/Safe/Safe.pm | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/dist/Safe/Safe.pm b/dist/Safe/Safe.pm index 059c6fb240..30458325d1 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); } } |