From: Rafael Garcia-Suarez Date: Fri, 4 Oct 2002 19:44:48 +0000 (+0000) Subject: Fix bug #17744, suggested by Andreas Jurenda, X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=33f7e1aa9bf0173d92dc0c0b35d57754dbf6c87e;p=p5sagit%2Fp5-mst-13.2.git Fix bug #17744, suggested by Andreas Jurenda, tweaked by rgs (security hole in Safe). p4raw-id: //depot/perl@17976 --- diff --git a/MANIFEST b/MANIFEST index df57030..38e5616 100644 --- a/MANIFEST +++ b/MANIFEST @@ -570,6 +570,7 @@ ext/re/re.t see if re pragma works ext/re/re.xs re extension external subroutines ext/Safe/safe1.t See if Safe works ext/Safe/safe2.t See if Safe works +ext/Safe/safe3.t See if Safe works ext/SDBM_File/Makefile.PL SDBM extension makefile writer ext/SDBM_File/sdbm.t See if SDBM_File works ext/SDBM_File/sdbm/biblio SDBM kit diff --git a/ext/Opcode/Safe.pm b/ext/Opcode/Safe.pm index e8efaa9..8d875ef 100644 --- a/ext/Opcode/Safe.pm +++ b/ext/Opcode/Safe.pm @@ -214,11 +214,11 @@ sub reval { # Create anon sub ref in root of compartment. # Uses a closure (on $expr) to pass in the code to be executed. # (eval on one line to keep line numbers as expected by caller) - my $evalcode = sprintf('package %s; sub { eval $expr; }', $root); + my $evalcode = sprintf('package %s; sub { @_ = (); eval $expr; }', $root); my $evalsub; - if ($strict) { use strict; $evalsub = eval $evalcode; } - else { no strict; $evalsub = eval $evalcode; } + if ($strict) { use strict; $evalsub = eval $evalcode; } + else { no strict; $evalsub = eval $evalcode; } return Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub); } diff --git a/ext/Safe/safe3.t b/ext/Safe/safe3.t new file mode 100644 index 0000000..c924762 --- /dev/null +++ b/ext/Safe/safe3.t @@ -0,0 +1,33 @@ +#!perl + +BEGIN { + if ($ENV{PERL_CORE}) { + chdir 't' if -d 't'; + @INC = '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bOpcode\b/ + && $Config{'extensions'} !~ /\bPOSIX\b/ + && $Config{'osname'} ne 'VMS') + { + print "1..0\n"; + exit 0; + } + } +} + +use strict; +use warnings; +use POSIX qw(ceil); +use Test::More tests => 1; +use Safe; + +my $safe = new Safe; +$safe->deny('add'); + +# Attempt to change the opmask from within the safe compartment +$safe->reval( qq{\$_[1] = q/\0/ x } . ceil( Opcode::opcodes / 8 ) ); + +# Check that it didn't work +$safe->reval( q{$x + $y} ); +like( $@, qr/^'?addition \(\+\)'? trapped by operation mask/, + 'opmask still in place' );