summaryrefslogtreecommitdiff
path: root/dist/Safe
diff options
context:
space:
mode:
authorNick Cleaton <nick@cleaton.net>2010-03-07 15:27:31 +0100
committerRafael Garcia-Suarez <rgs@consttype.org>2010-03-07 22:14:58 +0100
commit305aa7ae7250ccd59885f2ac5fa4f5fde410f98a (patch)
tree5b17ab23fc12a138c31cee40e06ac59f776e13e0 /dist/Safe
parent47e9bce17f6c887ae177ab3580e24e7b130669c4 (diff)
downloadperl-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.pm15
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);
}
}