Further improvements to the security fix in 16ac9e9a4185d3315152ade5286d4dd3d25bff32
Nick Cleaton [Sun, 7 Mar 2010 14:27:31 +0000 (15:27 +0100)]
- 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::"

dist/Safe/Safe.pm

index 059c6fb..3045832 100644 (file)
@@ -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);
     }
 }