1b39c5158Smillertpackage Safe; 2b39c5158Smillert 3b39c5158Smillertuse 5.003_11; 4898184e3Ssthenuse Scalar::Util qw(reftype refaddr); 5b39c5158Smillert 6*3d61058aSafresh1$Safe::VERSION = "2.46"; 7b39c5158Smillert 8b39c5158Smillert# *** Don't declare any lexicals above this point *** 9b39c5158Smillert# 10b39c5158Smillert# This function should return a closure which contains an eval that can't 11b39c5158Smillert# see any lexicals in scope (apart from __ExPr__ which is unavoidable) 12b39c5158Smillert 13b39c5158Smillertsub lexless_anon_sub { 14b39c5158Smillert # $_[0] is package; 15b39c5158Smillert # $_[1] is strict flag; 16b39c5158Smillert my $__ExPr__ = $_[2]; # must be a lexical to create the closure that 17b39c5158Smillert # can be used to pass the value into the safe 18b39c5158Smillert # world 19b39c5158Smillert 20b39c5158Smillert # Create anon sub ref in root of compartment. 21b39c5158Smillert # Uses a closure (on $__ExPr__) to pass in the code to be executed. 22b39c5158Smillert # (eval on one line to keep line numbers as expected by caller) 23b39c5158Smillert eval sprintf 24*3d61058aSafresh1 'package %s; %s sub { @_=(); local *SIG; eval q[my $__ExPr__;] . $__ExPr__; }', 25898184e3Ssthen $_[0], $_[1] ? 'use strict;' : ''; 26b39c5158Smillert} 27b39c5158Smillert 28898184e3Ssthenuse strict; 29b39c5158Smillertuse Carp; 30b39c5158SmillertBEGIN { eval q{ 31b39c5158Smillert use Carp::Heavy; 32b39c5158Smillert} } 33b39c5158Smillert 34b39c5158Smillertuse B (); 35b39c5158SmillertBEGIN { 36b39c5158Smillert no strict 'refs'; 37b39c5158Smillert if (defined &B::sub_generation) { 38b39c5158Smillert *sub_generation = \&B::sub_generation; 39b39c5158Smillert } 40b39c5158Smillert else { 41b39c5158Smillert # fake sub generation changing for perls < 5.8.9 42b39c5158Smillert my $sg; *sub_generation = sub { ++$sg }; 43b39c5158Smillert } 44b39c5158Smillert} 45b39c5158Smillert 46b39c5158Smillertuse Opcode 1.01, qw( 47b39c5158Smillert opset opset_to_ops opmask_add 48b39c5158Smillert empty_opset full_opset invert_opset verify_opset 49b39c5158Smillert opdesc opcodes opmask define_optag opset_to_hex 50b39c5158Smillert); 51b39c5158Smillert 52b39c5158Smillert*ops_to_opset = \&opset; # Temporary alias for old Penguins 53b39c5158Smillert 54b39c5158Smillert# Regular expressions and other unicode-aware code may need to call 55b39c5158Smillert# utf8->SWASHNEW (via perl's utf8.c). That will fail unless we share the 56b39c5158Smillert# SWASHNEW method. 57b39c5158Smillert# Sadly we can't just add utf8::SWASHNEW to $default_share because perl's 58b39c5158Smillert# utf8.c code does a fetchmethod on SWASHNEW to check if utf8.pm is loaded, 59b39c5158Smillert# and sharing makes it look like the method exists. 60b39c5158Smillert# The simplest and most robust fix is to ensure the utf8 module is loaded when 61b39c5158Smillert# Safe is loaded. Then we can add utf8::SWASHNEW to $default_share. 62b39c5158Smillertrequire utf8; 63b39c5158Smillert# we must ensure that utf8_heavy.pl, where SWASHNEW is defined, is loaded 64898184e3Ssthen# but without depending on too much knowledge of that implementation detail. 65898184e3Ssthen# This code (//i on a unicode string) should ensure utf8 is fully loaded 66898184e3Ssthen# and also loads the ToFold SWASH, unless things change so that these 67898184e3Ssthen# particular code points don't cause it to load. 68b39c5158Smillert# (Swashes are cached internally by perl in PL_utf8_* variables 69b39c5158Smillert# independent of being inside/outside of Safe. So once loaded they can be) 70eac174f2Safresh1do { my $a = pack('U',0x100); $a =~ m/\x{1234}/; $a =~ tr/\x{1234}//; }; 71b39c5158Smillert# now we can safely include utf8::SWASHNEW in $default_share defined below. 72b39c5158Smillert 73b39c5158Smillertmy $default_root = 0; 74b39c5158Smillert# share *_ and functions defined in universal.c 75b39c5158Smillert# Don't share stuff like *UNIVERSAL:: otherwise code from the 76b39c5158Smillert# compartment can 0wn functions in UNIVERSAL 77b39c5158Smillertmy $default_share = [qw[ 78b39c5158Smillert *_ 79b39c5158Smillert &PerlIO::get_layers 80*3d61058aSafresh1 &UNIVERSAL::import 81b39c5158Smillert &UNIVERSAL::isa 82b39c5158Smillert &UNIVERSAL::can 83*3d61058aSafresh1 &UNIVERSAL::unimport 84b39c5158Smillert &UNIVERSAL::VERSION 85b39c5158Smillert &utf8::is_utf8 86b39c5158Smillert &utf8::valid 87b39c5158Smillert &utf8::encode 88b39c5158Smillert &utf8::decode 89b39c5158Smillert &utf8::upgrade 90b39c5158Smillert &utf8::downgrade 91b39c5158Smillert &utf8::native_to_unicode 92b39c5158Smillert &utf8::unicode_to_native 93b39c5158Smillert &utf8::SWASHNEW 94b39c5158Smillert $version::VERSION 95b39c5158Smillert $version::CLASS 96b39c5158Smillert $version::STRICT 97b39c5158Smillert $version::LAX 98b39c5158Smillert @version::ISA 99b39c5158Smillert], ($] < 5.010 && qw[ 100b39c5158Smillert &utf8::SWASHGET 101b39c5158Smillert]), ($] >= 5.008001 && qw[ 102b39c5158Smillert &Regexp::DESTROY 103b39c5158Smillert]), ($] >= 5.010 && qw[ 104b39c5158Smillert &re::is_regexp 105b39c5158Smillert &re::regname 106b39c5158Smillert &re::regnames 107b39c5158Smillert &re::regnames_count 108b39c5158Smillert &UNIVERSAL::DOES 109b39c5158Smillert &version::() 110b39c5158Smillert &version::new 111b39c5158Smillert &version::("" 112b39c5158Smillert &version::stringify 113b39c5158Smillert &version::(0+ 114b39c5158Smillert &version::numify 115b39c5158Smillert &version::normal 116b39c5158Smillert &version::(cmp 117b39c5158Smillert &version::(<=> 118b39c5158Smillert &version::vcmp 119b39c5158Smillert &version::(bool 120b39c5158Smillert &version::boolean 121b39c5158Smillert &version::(nomethod 122b39c5158Smillert &version::noop 123b39c5158Smillert &version::is_alpha 124b39c5158Smillert &version::qv 125b39c5158Smillert &version::vxs::declare 126b39c5158Smillert &version::vxs::qv 127b39c5158Smillert &version::vxs::_VERSION 128b39c5158Smillert &version::vxs::stringify 129b39c5158Smillert &version::vxs::new 130b39c5158Smillert &version::vxs::parse 131898184e3Ssthen &version::vxs::VCMP 132b39c5158Smillert]), ($] >= 5.011 && qw[ 133b39c5158Smillert &re::regexp_pattern 134898184e3Ssthen]), ($] >= 5.010 && $] < 5.014 && qw[ 135898184e3Ssthen &Tie::Hash::NamedCapture::FETCH 136898184e3Ssthen &Tie::Hash::NamedCapture::STORE 137898184e3Ssthen &Tie::Hash::NamedCapture::DELETE 138898184e3Ssthen &Tie::Hash::NamedCapture::CLEAR 139898184e3Ssthen &Tie::Hash::NamedCapture::EXISTS 140898184e3Ssthen &Tie::Hash::NamedCapture::FIRSTKEY 141898184e3Ssthen &Tie::Hash::NamedCapture::NEXTKEY 142898184e3Ssthen &Tie::Hash::NamedCapture::SCALAR 143898184e3Ssthen &Tie::Hash::NamedCapture::flags 144b39c5158Smillert])]; 14591f110e0Safresh1if (defined $Devel::Cover::VERSION) { 14691f110e0Safresh1 push @$default_share, '&Devel::Cover::use_file'; 14791f110e0Safresh1} 148b39c5158Smillert 149b39c5158Smillertsub new { 150b39c5158Smillert my($class, $root, $mask) = @_; 151b39c5158Smillert my $obj = {}; 152b39c5158Smillert bless $obj, $class; 153b39c5158Smillert 154b39c5158Smillert if (defined($root)) { 155b39c5158Smillert croak "Can't use \"$root\" as root name" 156b39c5158Smillert if $root =~ /^main\b/ or $root !~ /^\w[:\w]*$/; 157b39c5158Smillert $obj->{Root} = $root; 158b39c5158Smillert $obj->{Erase} = 0; 159b39c5158Smillert } 160b39c5158Smillert else { 161b39c5158Smillert $obj->{Root} = "Safe::Root".$default_root++; 162b39c5158Smillert $obj->{Erase} = 1; 163b39c5158Smillert } 164b39c5158Smillert 165b39c5158Smillert # use permit/deny methods instead till interface issues resolved 166b39c5158Smillert # XXX perhaps new Safe 'Root', mask => $mask, foo => bar, ...; 167b39c5158Smillert croak "Mask parameter to new no longer supported" if defined $mask; 168b39c5158Smillert $obj->permit_only(':default'); 169b39c5158Smillert 170b39c5158Smillert # We must share $_ and @_ with the compartment or else ops such 171b39c5158Smillert # as split, length and so on won't default to $_ properly, nor 172b39c5158Smillert # will passing argument to subroutines work (via @_). In fact, 173b39c5158Smillert # for reasons I don't completely understand, we need to share 174b39c5158Smillert # the whole glob *_ rather than $_ and @_ separately, otherwise 175b39c5158Smillert # @_ in non default packages within the compartment don't work. 176b39c5158Smillert $obj->share_from('main', $default_share); 177b39c5158Smillert 178b39c5158Smillert Opcode::_safe_pkg_prep($obj->{Root}) if($Opcode::VERSION > 1.04); 179b39c5158Smillert 180b39c5158Smillert return $obj; 181b39c5158Smillert} 182b39c5158Smillert 183b39c5158Smillertsub DESTROY { 184b39c5158Smillert my $obj = shift; 185b39c5158Smillert $obj->erase('DESTROY') if $obj->{Erase}; 186b39c5158Smillert} 187b39c5158Smillert 188b39c5158Smillertsub erase { 189b39c5158Smillert my ($obj, $action) = @_; 190b39c5158Smillert my $pkg = $obj->root(); 191b39c5158Smillert my ($stem, $leaf); 192b39c5158Smillert 193b39c5158Smillert no strict 'refs'; 194b39c5158Smillert $pkg = "main::$pkg\::"; # expand to full symbol table name 195b39c5158Smillert ($stem, $leaf) = $pkg =~ m/(.*::)(\w+::)$/; 196b39c5158Smillert 197b39c5158Smillert # The 'my $foo' is needed! Without it you get an 198b39c5158Smillert # 'Attempt to free unreferenced scalar' warning! 199b39c5158Smillert my $stem_symtab = *{$stem}{HASH}; 200b39c5158Smillert 201b39c5158Smillert #warn "erase($pkg) stem=$stem, leaf=$leaf"; 202b39c5158Smillert #warn " stem_symtab hash ".scalar(%$stem_symtab)."\n"; 203b39c5158Smillert # ", join(', ', %$stem_symtab),"\n"; 204b39c5158Smillert 205b39c5158Smillert# delete $stem_symtab->{$leaf}; 206b39c5158Smillert 207b39c5158Smillert my $leaf_glob = $stem_symtab->{$leaf}; 208b39c5158Smillert my $leaf_symtab = *{$leaf_glob}{HASH}; 209b39c5158Smillert# warn " leaf_symtab ", join(', ', %$leaf_symtab),"\n"; 210b39c5158Smillert %$leaf_symtab = (); 211b39c5158Smillert #delete $leaf_symtab->{'__ANON__'}; 212b39c5158Smillert #delete $leaf_symtab->{'foo'}; 213b39c5158Smillert #delete $leaf_symtab->{'main::'}; 214b39c5158Smillert# my $foo = undef ${"$stem\::"}{"$leaf\::"}; 215b39c5158Smillert 216b39c5158Smillert if ($action and $action eq 'DESTROY') { 217b39c5158Smillert delete $stem_symtab->{$leaf}; 218b39c5158Smillert } else { 219b39c5158Smillert $obj->share_from('main', $default_share); 220b39c5158Smillert } 221b39c5158Smillert 1; 222b39c5158Smillert} 223b39c5158Smillert 224b39c5158Smillert 225b39c5158Smillertsub reinit { 226b39c5158Smillert my $obj= shift; 227b39c5158Smillert $obj->erase; 228b39c5158Smillert $obj->share_redo; 229b39c5158Smillert} 230b39c5158Smillert 231b39c5158Smillertsub root { 232b39c5158Smillert my $obj = shift; 233b39c5158Smillert croak("Safe root method now read-only") if @_; 234b39c5158Smillert return $obj->{Root}; 235b39c5158Smillert} 236b39c5158Smillert 237b39c5158Smillert 238b39c5158Smillertsub mask { 239b39c5158Smillert my $obj = shift; 240b39c5158Smillert return $obj->{Mask} unless @_; 241b39c5158Smillert $obj->deny_only(@_); 242b39c5158Smillert} 243b39c5158Smillert 244b39c5158Smillert# v1 compatibility methods 245b39c5158Smillertsub trap { shift->deny(@_) } 246b39c5158Smillertsub untrap { shift->permit(@_) } 247b39c5158Smillert 248b39c5158Smillertsub deny { 249b39c5158Smillert my $obj = shift; 250b39c5158Smillert $obj->{Mask} |= opset(@_); 251b39c5158Smillert} 252b39c5158Smillertsub deny_only { 253b39c5158Smillert my $obj = shift; 254b39c5158Smillert $obj->{Mask} = opset(@_); 255b39c5158Smillert} 256b39c5158Smillert 257b39c5158Smillertsub permit { 258b39c5158Smillert my $obj = shift; 259b39c5158Smillert # XXX needs testing 260b39c5158Smillert $obj->{Mask} &= invert_opset opset(@_); 261b39c5158Smillert} 262b39c5158Smillertsub permit_only { 263b39c5158Smillert my $obj = shift; 264b39c5158Smillert $obj->{Mask} = invert_opset opset(@_); 265b39c5158Smillert} 266b39c5158Smillert 267b39c5158Smillert 268b39c5158Smillertsub dump_mask { 269b39c5158Smillert my $obj = shift; 270b39c5158Smillert print opset_to_hex($obj->{Mask}),"\n"; 271b39c5158Smillert} 272b39c5158Smillert 273b39c5158Smillert 274b39c5158Smillertsub share { 275b39c5158Smillert my($obj, @vars) = @_; 276b39c5158Smillert $obj->share_from(scalar(caller), \@vars); 277b39c5158Smillert} 278b39c5158Smillert 279b39c5158Smillert 280b39c5158Smillertsub share_from { 281b39c5158Smillert my $obj = shift; 282b39c5158Smillert my $pkg = shift; 283b39c5158Smillert my $vars = shift; 284b39c5158Smillert my $no_record = shift || 0; 285b39c5158Smillert my $root = $obj->root(); 286b39c5158Smillert croak("vars not an array ref") unless ref $vars eq 'ARRAY'; 287b39c5158Smillert no strict 'refs'; 288b39c5158Smillert # Check that 'from' package actually exists 289b39c5158Smillert croak("Package \"$pkg\" does not exist") 290b39c5158Smillert unless keys %{"$pkg\::"}; 291b39c5158Smillert my $arg; 292b39c5158Smillert foreach $arg (@$vars) { 293b39c5158Smillert # catch some $safe->share($var) errors: 294b39c5158Smillert my ($var, $type); 295b39c5158Smillert $type = $1 if ($var = $arg) =~ s/^(\W)//; 296b39c5158Smillert # warn "share_from $pkg $type $var"; 297b39c5158Smillert for (1..2) { # assign twice to avoid any 'used once' warnings 298b39c5158Smillert *{$root."::$var"} = (!$type) ? \&{$pkg."::$var"} 299b39c5158Smillert : ($type eq '&') ? \&{$pkg."::$var"} 300b39c5158Smillert : ($type eq '$') ? \${$pkg."::$var"} 301b39c5158Smillert : ($type eq '@') ? \@{$pkg."::$var"} 302b39c5158Smillert : ($type eq '%') ? \%{$pkg."::$var"} 303b39c5158Smillert : ($type eq '*') ? *{$pkg."::$var"} 304b39c5158Smillert : croak(qq(Can't share "$type$var" of unknown type)); 305b39c5158Smillert } 306b39c5158Smillert } 307b39c5158Smillert $obj->share_record($pkg, $vars) unless $no_record or !$vars; 308b39c5158Smillert} 309b39c5158Smillert 310b39c5158Smillert 311b39c5158Smillertsub share_record { 312b39c5158Smillert my $obj = shift; 313b39c5158Smillert my $pkg = shift; 314b39c5158Smillert my $vars = shift; 315b39c5158Smillert my $shares = \%{$obj->{Shares} ||= {}}; 316b39c5158Smillert # Record shares using keys of $obj->{Shares}. See reinit. 317b39c5158Smillert @{$shares}{@$vars} = ($pkg) x @$vars if @$vars; 318b39c5158Smillert} 319b39c5158Smillert 320b39c5158Smillert 321b39c5158Smillertsub share_redo { 322b39c5158Smillert my $obj = shift; 323b39c5158Smillert my $shares = \%{$obj->{Shares} ||= {}}; 324b39c5158Smillert my($var, $pkg); 325b39c5158Smillert while(($var, $pkg) = each %$shares) { 326b39c5158Smillert # warn "share_redo $pkg\:: $var"; 327b39c5158Smillert $obj->share_from($pkg, [ $var ], 1); 328b39c5158Smillert } 329b39c5158Smillert} 330b39c5158Smillert 331b39c5158Smillert 332b39c5158Smillertsub share_forget { 333b39c5158Smillert delete shift->{Shares}; 334b39c5158Smillert} 335b39c5158Smillert 336b39c5158Smillert 337b39c5158Smillertsub varglob { 338b39c5158Smillert my ($obj, $var) = @_; 339b39c5158Smillert no strict 'refs'; 340b39c5158Smillert return *{$obj->root()."::$var"}; 341b39c5158Smillert} 342b39c5158Smillert 343b39c5158Smillertsub _clean_stash { 344b39c5158Smillert my ($root, $saved_refs) = @_; 345b39c5158Smillert $saved_refs ||= []; 346b39c5158Smillert no strict 'refs'; 347b39c5158Smillert foreach my $hook (qw(DESTROY AUTOLOAD), grep /^\(/, keys %$root) { 348b39c5158Smillert push @$saved_refs, \*{$root.$hook}; 349b39c5158Smillert delete ${$root}{$hook}; 350b39c5158Smillert } 351b39c5158Smillert 352b39c5158Smillert for (grep /::$/, keys %$root) { 353b39c5158Smillert next if \%{$root.$_} eq \%$root; 354b39c5158Smillert _clean_stash($root.$_, $saved_refs); 355b39c5158Smillert } 356b39c5158Smillert} 357b39c5158Smillert 358b39c5158Smillertsub reval { 359b39c5158Smillert my ($obj, $expr, $strict) = @_; 36091f110e0Safresh1 die "Bad Safe object" unless $obj->isa('Safe'); 36191f110e0Safresh1 362b39c5158Smillert my $root = $obj->{Root}; 363b39c5158Smillert 364b39c5158Smillert my $evalsub = lexless_anon_sub($root, $strict, $expr); 365b39c5158Smillert # propagate context 366b39c5158Smillert my $sg = sub_generation(); 367b8851fccSafresh1 my @subret; 368b8851fccSafresh1 if (defined wantarray) { 369b8851fccSafresh1 @subret = (wantarray) 370b39c5158Smillert ? Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub) 371b39c5158Smillert : scalar Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub); 372b8851fccSafresh1 } 373b8851fccSafresh1 else { 374b8851fccSafresh1 Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub); 375b8851fccSafresh1 } 376b39c5158Smillert _clean_stash($root.'::') if $sg != sub_generation(); 377b39c5158Smillert $obj->wrap_code_refs_within(@subret); 378b39c5158Smillert return (wantarray) ? @subret : $subret[0]; 379b39c5158Smillert} 380b39c5158Smillert 381898184e3Ssthenmy %OID; 382b39c5158Smillert 383b39c5158Smillertsub wrap_code_refs_within { 384b39c5158Smillert my $obj = shift; 385b39c5158Smillert 386898184e3Ssthen %OID = (); 387b39c5158Smillert $obj->_find_code_refs('wrap_code_ref', @_); 388b39c5158Smillert} 389b39c5158Smillert 390b39c5158Smillert 391b39c5158Smillertsub _find_code_refs { 392b39c5158Smillert my $obj = shift; 393b39c5158Smillert my $visitor = shift; 394b39c5158Smillert 395b39c5158Smillert for my $item (@_) { 396b39c5158Smillert my $reftype = $item && reftype $item 397b39c5158Smillert or next; 398898184e3Ssthen 399898184e3Ssthen # skip references already seen 400898184e3Ssthen next if ++$OID{refaddr $item} > 1; 401898184e3Ssthen 402b39c5158Smillert if ($reftype eq 'ARRAY') { 403b39c5158Smillert $obj->_find_code_refs($visitor, @$item); 404b39c5158Smillert } 405b39c5158Smillert elsif ($reftype eq 'HASH') { 406b39c5158Smillert $obj->_find_code_refs($visitor, values %$item); 407b39c5158Smillert } 408b39c5158Smillert # XXX GLOBs? 409b39c5158Smillert elsif ($reftype eq 'CODE') { 410b39c5158Smillert $item = $obj->$visitor($item); 411b39c5158Smillert } 412b39c5158Smillert } 413b39c5158Smillert} 414b39c5158Smillert 415b39c5158Smillert 416b39c5158Smillertsub wrap_code_ref { 417b39c5158Smillert my ($obj, $sub) = @_; 41891f110e0Safresh1 die "Bad safe object" unless $obj->isa('Safe'); 419b39c5158Smillert 420b39c5158Smillert # wrap code ref $sub with _safe_call_sv so that, when called, the 421b39c5158Smillert # execution will happen with the compartment fully 'in effect'. 422b39c5158Smillert 423b39c5158Smillert croak "Not a CODE reference" 424b39c5158Smillert if reftype $sub ne 'CODE'; 425b39c5158Smillert 426b39c5158Smillert my $ret = sub { 427b39c5158Smillert my @args = @_; # lexical to close over 428b39c5158Smillert my $sub_with_args = sub { $sub->(@args) }; 429b39c5158Smillert 430b39c5158Smillert my @subret; 431b39c5158Smillert my $error; 432b39c5158Smillert do { 433b39c5158Smillert local $@; # needed due to perl_call_sv(sv, G_EVAL|G_KEEPERR) 434b39c5158Smillert my $sg = sub_generation(); 435b39c5158Smillert @subret = (wantarray) 436b39c5158Smillert ? Opcode::_safe_call_sv($obj->{Root}, $obj->{Mask}, $sub_with_args) 437b39c5158Smillert : scalar Opcode::_safe_call_sv($obj->{Root}, $obj->{Mask}, $sub_with_args); 438b39c5158Smillert $error = $@; 439b39c5158Smillert _clean_stash($obj->{Root}.'::') if $sg != sub_generation(); 440b39c5158Smillert }; 441b39c5158Smillert if ($error) { # rethrow exception 442b39c5158Smillert $error =~ s/\t\(in cleanup\) //; # prefix added by G_KEEPERR 443b39c5158Smillert die $error; 444b39c5158Smillert } 445b39c5158Smillert return (wantarray) ? @subret : $subret[0]; 446b39c5158Smillert }; 447b39c5158Smillert 448b39c5158Smillert return $ret; 449b39c5158Smillert} 450b39c5158Smillert 451b39c5158Smillert 452b39c5158Smillertsub rdo { 453b39c5158Smillert my ($obj, $file) = @_; 45491f110e0Safresh1 die "Bad Safe object" unless $obj->isa('Safe'); 45591f110e0Safresh1 456b39c5158Smillert my $root = $obj->{Root}; 457b39c5158Smillert 458b39c5158Smillert my $sg = sub_generation(); 459b39c5158Smillert my $evalsub = eval 460b39c5158Smillert sprintf('package %s; sub { @_ = (); do $file }', $root); 461b39c5158Smillert my @subret = (wantarray) 462b39c5158Smillert ? Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub) 463b39c5158Smillert : scalar Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub); 464b39c5158Smillert _clean_stash($root.'::') if $sg != sub_generation(); 465b39c5158Smillert $obj->wrap_code_refs_within(@subret); 466b39c5158Smillert return (wantarray) ? @subret : $subret[0]; 467b39c5158Smillert} 468b39c5158Smillert 469b39c5158Smillert 470b39c5158Smillert1; 471b39c5158Smillert 472b39c5158Smillert__END__ 473b39c5158Smillert 474b39c5158Smillert=head1 NAME 475b39c5158Smillert 476b39c5158SmillertSafe - Compile and execute code in restricted compartments 477b39c5158Smillert 478b39c5158Smillert=head1 SYNOPSIS 479b39c5158Smillert 480b39c5158Smillert use Safe; 481b39c5158Smillert 482b39c5158Smillert $compartment = new Safe; 483b39c5158Smillert 484b39c5158Smillert $compartment->permit(qw(time sort :browse)); 485b39c5158Smillert 486b39c5158Smillert $result = $compartment->reval($unsafe_code); 487b39c5158Smillert 488b39c5158Smillert=head1 DESCRIPTION 489b39c5158Smillert 490b39c5158SmillertThe Safe extension module allows the creation of compartments 491b39c5158Smillertin which perl code can be evaluated. Each compartment has 492b39c5158Smillert 493b39c5158Smillert=over 8 494b39c5158Smillert 495b39c5158Smillert=item a new namespace 496b39c5158Smillert 497b39c5158SmillertThe "root" of the namespace (i.e. "main::") is changed to a 498b39c5158Smillertdifferent package and code evaluated in the compartment cannot 499b39c5158Smillertrefer to variables outside this namespace, even with run-time 500b39c5158Smillertglob lookups and other tricks. 501b39c5158Smillert 502b39c5158SmillertCode which is compiled outside the compartment can choose to place 503b39c5158Smillertvariables into (or I<share> variables with) the compartment's namespace 504b39c5158Smillertand only that data will be visible to code evaluated in the 505b39c5158Smillertcompartment. 506b39c5158Smillert 507b39c5158SmillertBy default, the only variables shared with compartments are the 508b39c5158Smillert"underscore" variables $_ and @_ (and, technically, the less frequently 509b39c5158Smillertused %_, the _ filehandle and so on). This is because otherwise perl 510b39c5158Smillertoperators which default to $_ will not work and neither will the 511b39c5158Smillertassignment of arguments to @_ on subroutine entry. 512b39c5158Smillert 513b39c5158Smillert=item an operator mask 514b39c5158Smillert 515b39c5158SmillertEach compartment has an associated "operator mask". Recall that 516b39c5158Smillertperl code is compiled into an internal format before execution. 517b39c5158SmillertEvaluating perl code (e.g. via "eval" or "do 'file'") causes 518b39c5158Smillertthe code to be compiled into an internal format and then, 519b39c5158Smillertprovided there was no error in the compilation, executed. 520b39c5158SmillertCode evaluated in a compartment compiles subject to the 521b39c5158Smillertcompartment's operator mask. Attempting to evaluate code in a 522b39c5158Smillertcompartment which contains a masked operator will cause the 523b39c5158Smillertcompilation to fail with an error. The code will not be executed. 524b39c5158Smillert 525b39c5158SmillertThe default operator mask for a newly created compartment is 526b39c5158Smillertthe ':default' optag. 527b39c5158Smillert 528b39c5158SmillertIt is important that you read the L<Opcode> module documentation 529b39c5158Smillertfor more information, especially for detailed definitions of opnames, 530b39c5158Smillertoptags and opsets. 531b39c5158Smillert 532b39c5158SmillertSince it is only at the compilation stage that the operator mask 533b39c5158Smillertapplies, controlled access to potentially unsafe operations can 534b39c5158Smillertbe achieved by having a handle to a wrapper subroutine (written 535b39c5158Smillertoutside the compartment) placed into the compartment. For example, 536b39c5158Smillert 537b39c5158Smillert $cpt = new Safe; 538b39c5158Smillert sub wrapper { 539b39c5158Smillert # vet arguments and perform potentially unsafe operations 540b39c5158Smillert } 541b39c5158Smillert $cpt->share('&wrapper'); 542b39c5158Smillert 543b39c5158Smillert=back 544b39c5158Smillert 545b39c5158Smillert 546b39c5158Smillert=head1 WARNING 547b39c5158Smillert 54856d68f1eSafresh1The Safe module does not implement an effective sandbox for 54956d68f1eSafresh1evaluating untrusted code with the perl interpreter. 55056d68f1eSafresh1 55156d68f1eSafresh1Bugs in the perl interpreter that could be abused to bypass 55256d68f1eSafresh1Safe restrictions are not treated as vulnerabilities. See 55356d68f1eSafresh1L<perlsecpolicy> for additional information. 55456d68f1eSafresh1 555b39c5158SmillertThe authors make B<no warranty>, implied or otherwise, about the 556b39c5158Smillertsuitability of this software for safety or security purposes. 557b39c5158Smillert 558b39c5158SmillertThe authors shall not in any case be liable for special, incidental, 559b39c5158Smillertconsequential, indirect or other similar damages arising from the use 560b39c5158Smillertof this software. 561b39c5158Smillert 562b39c5158SmillertYour mileage will vary. If in any doubt B<do not use it>. 563b39c5158Smillert 564b39c5158Smillert 565b39c5158Smillert=head1 METHODS 566b39c5158Smillert 567b39c5158SmillertTo create a new compartment, use 568b39c5158Smillert 569b39c5158Smillert $cpt = new Safe; 570b39c5158Smillert 571b39c5158SmillertOptional argument is (NAMESPACE), where NAMESPACE is the root namespace 572b39c5158Smillertto use for the compartment (defaults to "Safe::Root0", incremented for 573b39c5158Smillerteach new compartment). 574b39c5158Smillert 575b39c5158SmillertNote that version 1.00 of the Safe module supported a second optional 576b39c5158Smillertparameter, MASK. That functionality has been withdrawn pending deeper 577b39c5158Smillertconsideration. Use the permit and deny methods described below. 578b39c5158Smillert 579b39c5158SmillertThe following methods can then be used on the compartment 580b39c5158Smillertobject returned by the above constructor. The object argument 581b39c5158Smillertis implicit in each case. 582b39c5158Smillert 583b39c5158Smillert 584b39c5158Smillert=head2 permit (OP, ...) 585b39c5158Smillert 586b39c5158SmillertPermit the listed operators to be used when compiling code in the 587b39c5158Smillertcompartment (in I<addition> to any operators already permitted). 588b39c5158Smillert 589b39c5158SmillertYou can list opcodes by names, or use a tag name; see 590b39c5158SmillertL<Opcode/"Predefined Opcode Tags">. 591b39c5158Smillert 592b39c5158Smillert=head2 permit_only (OP, ...) 593b39c5158Smillert 594b39c5158SmillertPermit I<only> the listed operators to be used when compiling code in 595b39c5158Smillertthe compartment (I<no> other operators are permitted). 596b39c5158Smillert 597b39c5158Smillert=head2 deny (OP, ...) 598b39c5158Smillert 599b39c5158SmillertDeny the listed operators from being used when compiling code in the 600b39c5158Smillertcompartment (other operators may still be permitted). 601b39c5158Smillert 602b39c5158Smillert=head2 deny_only (OP, ...) 603b39c5158Smillert 604b39c5158SmillertDeny I<only> the listed operators from being used when compiling code 605b39c5158Smillertin the compartment (I<all> other operators will be permitted, so you probably 606b39c5158Smillertdon't want to use this method). 607b39c5158Smillert 6086fb12b70Safresh1=head2 trap (OP, ...), untrap (OP, ...) 609b39c5158Smillert 610b39c5158SmillertThe trap and untrap methods are synonyms for deny and permit 611b39c5158Smillertrespectfully. 612b39c5158Smillert 613b39c5158Smillert=head2 share (NAME, ...) 614b39c5158Smillert 615b39c5158SmillertThis shares the variable(s) in the argument list with the compartment. 616b39c5158SmillertThis is almost identical to exporting variables using the L<Exporter> 617b39c5158Smillertmodule. 618b39c5158Smillert 619b39c5158SmillertEach NAME must be the B<name> of a non-lexical variable, typically 620b39c5158Smillertwith the leading type identifier included. A bareword is treated as a 621b39c5158Smillertfunction name. 622b39c5158Smillert 623b39c5158SmillertExamples of legal names are '$foo' for a scalar, '@foo' for an 624b39c5158Smillertarray, '%foo' for a hash, '&foo' or 'foo' for a subroutine and '*foo' 625b39c5158Smillertfor a glob (i.e. all symbol table entries associated with "foo", 626b39c5158Smillertincluding scalar, array, hash, sub and filehandle). 627b39c5158Smillert 628b39c5158SmillertEach NAME is assumed to be in the calling package. See share_from 629b39c5158Smillertfor an alternative method (which C<share> uses). 630b39c5158Smillert 631b39c5158Smillert=head2 share_from (PACKAGE, ARRAYREF) 632b39c5158Smillert 633b39c5158SmillertThis method is similar to share() but allows you to explicitly name the 634b39c5158Smillertpackage that symbols should be shared from. The symbol names (including 635b39c5158Smillerttype characters) are supplied as an array reference. 636b39c5158Smillert 637b39c5158Smillert $safe->share_from('main', [ '$foo', '%bar', 'func' ]); 638b39c5158Smillert 639b39c5158SmillertNames can include package names, which are relative to the specified PACKAGE. 640b39c5158SmillertSo these two calls have the same effect: 641b39c5158Smillert 642b39c5158Smillert $safe->share_from('Scalar::Util', [ 'reftype' ]); 643b39c5158Smillert $safe->share_from('main', [ 'Scalar::Util::reftype' ]); 644b39c5158Smillert 645b39c5158Smillert=head2 varglob (VARNAME) 646b39c5158Smillert 647b39c5158SmillertThis returns a glob reference for the symbol table entry of VARNAME in 648b39c5158Smillertthe package of the compartment. VARNAME must be the B<name> of a 649b39c5158Smillertvariable without any leading type marker. For example: 650b39c5158Smillert 651b39c5158Smillert ${$cpt->varglob('foo')} = "Hello world"; 652b39c5158Smillert 653b39c5158Smillerthas the same effect as: 654b39c5158Smillert 655b39c5158Smillert $cpt = new Safe 'Root'; 656b39c5158Smillert $Root::foo = "Hello world"; 657b39c5158Smillert 658b39c5158Smillertbut avoids the need to know $cpt's package name. 659b39c5158Smillert 660b39c5158Smillert 661b39c5158Smillert=head2 reval (STRING, STRICT) 662b39c5158Smillert 663b39c5158SmillertThis evaluates STRING as perl code inside the compartment. 664b39c5158Smillert 665b39c5158SmillertThe code can only see the compartment's namespace (as returned by the 666b39c5158SmillertB<root> method). The compartment's root package appears to be the 667b39c5158SmillertC<main::> package to the code inside the compartment. 668b39c5158Smillert 669b39c5158SmillertAny attempt by the code in STRING to use an operator which is not permitted 670b39c5158Smillertby the compartment will cause an error (at run-time of the main program 671b39c5158Smillertbut at compile-time for the code in STRING). The error is of the form 672b39c5158Smillert"'%s' trapped by operation mask...". 673b39c5158Smillert 674b39c5158SmillertIf an operation is trapped in this way, then the code in STRING will 675b39c5158Smillertnot be executed. If such a trapped operation occurs or any other 676b39c5158Smillertcompile-time or return error, then $@ is set to the error message, just 677b39c5158Smillertas with an eval(). 678b39c5158Smillert 679b39c5158SmillertIf there is no error, then the method returns the value of the last 680b39c5158Smillertexpression evaluated, or a return statement may be used, just as with 681b39c5158Smillertsubroutines and B<eval()>. The context (list or scalar) is determined 682b39c5158Smillertby the caller as usual. 683b39c5158Smillert 684b39c5158SmillertIf the return value of reval() is (or contains) any code reference, 685b39c5158Smillertthose code references are wrapped to be themselves executed always 686b39c5158Smillertin the compartment. See L</wrap_code_refs_within>. 687b39c5158Smillert 688b39c5158SmillertThe formerly undocumented STRICT argument sets strictness: if true 689b39c5158Smillert'use strict;' is used, otherwise it uses 'no strict;'. B<Note>: if 690b39c5158SmillertSTRICT is omitted 'no strict;' is the default. 691b39c5158Smillert 692b39c5158SmillertSome points to note: 693b39c5158Smillert 694b39c5158SmillertIf the entereval op is permitted then the code can use eval "..." to 695b39c5158Smillert'hide' code which might use denied ops. This is not a major problem 696b39c5158Smillertsince when the code tries to execute the eval it will fail because the 697b39c5158Smillertopmask is still in effect. However this technique would allow clever, 698b39c5158Smillertand possibly harmful, code to 'probe' the boundaries of what is 699b39c5158Smillertpossible. 700b39c5158Smillert 701b39c5158SmillertAny string eval which is executed by code executing in a compartment, 702b39c5158Smillertor by code called from code executing in a compartment, will be eval'd 703b39c5158Smillertin the namespace of the compartment. This is potentially a serious 704b39c5158Smillertproblem. 705b39c5158Smillert 706b39c5158SmillertConsider a function foo() in package pkg compiled outside a compartment 707b39c5158Smillertbut shared with it. Assume the compartment has a root package called 708b39c5158Smillert'Root'. If foo() contains an eval statement like eval '$foo = 1' then, 709b39c5158Smillertnormally, $pkg::foo will be set to 1. If foo() is called from the 710b39c5158Smillertcompartment (by whatever means) then instead of setting $pkg::foo, the 711b39c5158Smillerteval will actually set $Root::pkg::foo. 712b39c5158Smillert 713b39c5158SmillertThis can easily be demonstrated by using a module, such as the Socket 714b39c5158Smillertmodule, which uses eval "..." as part of an AUTOLOAD function. You can 715b39c5158Smillert'use' the module outside the compartment and share an (autoloaded) 716b39c5158Smillertfunction with the compartment. If an autoload is triggered by code in 717b39c5158Smillertthe compartment, or by any code anywhere that is called by any means 718b39c5158Smillertfrom the compartment, then the eval in the Socket module's AUTOLOAD 719b39c5158Smillertfunction happens in the namespace of the compartment. Any variables 720b39c5158Smillertcreated or used by the eval'd code are now under the control of 721b39c5158Smillertthe code in the compartment. 722b39c5158Smillert 723b39c5158SmillertA similar effect applies to I<all> runtime symbol lookups in code 724b39c5158Smillertcalled from a compartment but not compiled within it. 725b39c5158Smillert 726b39c5158Smillert=head2 rdo (FILENAME) 727b39c5158Smillert 728b39c5158SmillertThis evaluates the contents of file FILENAME inside the compartment. 7299f11ffb7Safresh1It uses the same rules as perl's built-in C<do> to locate the file, 7309f11ffb7Safresh1poossibly using C<@INC>. 7319f11ffb7Safresh1 732b39c5158SmillertSee above documentation on the B<reval> method for further details. 733b39c5158Smillert 734b39c5158Smillert=head2 root (NAMESPACE) 735b39c5158Smillert 736b39c5158SmillertThis method returns the name of the package that is the root of the 737b39c5158Smillertcompartment's namespace. 738b39c5158Smillert 739b39c5158SmillertNote that this behaviour differs from version 1.00 of the Safe module 740b39c5158Smillertwhere the root module could be used to change the namespace. That 741b39c5158Smillertfunctionality has been withdrawn pending deeper consideration. 742b39c5158Smillert 743b39c5158Smillert=head2 mask (MASK) 744b39c5158Smillert 745b39c5158SmillertThis is a get-or-set method for the compartment's operator mask. 746b39c5158Smillert 747b39c5158SmillertWith no MASK argument present, it returns the current operator mask of 748b39c5158Smillertthe compartment. 749b39c5158Smillert 750b39c5158SmillertWith the MASK argument present, it sets the operator mask for the 751b39c5158Smillertcompartment (equivalent to calling the deny_only method). 752b39c5158Smillert 753b39c5158Smillert=head2 wrap_code_ref (CODEREF) 754b39c5158Smillert 755b39c5158SmillertReturns a reference to an anonymous subroutine that, when executed, will call 756b39c5158SmillertCODEREF with the Safe compartment 'in effect'. In other words, with the 757b39c5158Smillertpackage namespace adjusted and the opmask enabled. 758b39c5158Smillert 759b39c5158SmillertNote that the opmask doesn't affect the already compiled code, it only affects 760b39c5158Smillertany I<further> compilation that the already compiled code may try to perform. 761b39c5158Smillert 762b39c5158SmillertThis is particularly useful when applied to code references returned from reval(). 763b39c5158Smillert 764b39c5158Smillert(It also provides a kind of workaround for RT#60374: "Safe.pm sort {} bug with 76556d68f1eSafresh1-Dusethreads". See L<https://rt.perl.org/rt3//Public/Bug/Display.html?id=60374> 766b39c5158Smillertfor I<much> more detail.) 767b39c5158Smillert 768b39c5158Smillert=head2 wrap_code_refs_within (...) 769b39c5158Smillert 770b39c5158SmillertWraps any CODE references found within the arguments by replacing each with the 771b39c5158Smillertresult of calling L</wrap_code_ref> on the CODE reference. Any ARRAY or HASH 772b39c5158Smillertreferences in the arguments are inspected recursively. 773b39c5158Smillert 774b39c5158SmillertReturns nothing. 775b39c5158Smillert 776b39c5158Smillert=head1 RISKS 777b39c5158Smillert 778b39c5158SmillertThis section is just an outline of some of the things code in a compartment 779b39c5158Smillertmight do (intentionally or unintentionally) which can have an effect outside 780b39c5158Smillertthe compartment. 781b39c5158Smillert 782b39c5158Smillert=over 8 783b39c5158Smillert 784b39c5158Smillert=item Memory 785b39c5158Smillert 786b39c5158SmillertConsuming all (or nearly all) available memory. 787b39c5158Smillert 788b39c5158Smillert=item CPU 789b39c5158Smillert 790b39c5158SmillertCausing infinite loops etc. 791b39c5158Smillert 792b39c5158Smillert=item Snooping 793b39c5158Smillert 794b39c5158SmillertCopying private information out of your system. Even something as 795b39c5158Smillertsimple as your user name is of value to others. Much useful information 796b39c5158Smillertcould be gleaned from your environment variables for example. 797b39c5158Smillert 798b39c5158Smillert=item Signals 799b39c5158Smillert 800b39c5158SmillertCausing signals (especially SIGFPE and SIGALARM) to affect your process. 801b39c5158Smillert 802b39c5158SmillertSetting up a signal handler will need to be carefully considered 803b39c5158Smillertand controlled. What mask is in effect when a signal handler 804b39c5158Smillertgets called? If a user can get an imported function to get an 805b39c5158Smillertexception and call the user's signal handler, does that user's 806b39c5158Smillertrestricted mask get re-instated before the handler is called? 807b39c5158SmillertDoes an imported handler get called with its original mask or 808b39c5158Smillertthe user's one? 809b39c5158Smillert 810b39c5158Smillert=item State Changes 811b39c5158Smillert 812b39c5158SmillertOps such as chdir obviously effect the process as a whole and not just 813b39c5158Smillertthe code in the compartment. Ops such as rand and srand have a similar 814b39c5158Smillertbut more subtle effect. 815b39c5158Smillert 816b39c5158Smillert=back 817b39c5158Smillert 818b39c5158Smillert=head1 AUTHOR 819b39c5158Smillert 820b39c5158SmillertOriginally designed and implemented by Malcolm Beattie. 821b39c5158Smillert 822b39c5158SmillertReworked to use the Opcode module and other changes added by Tim Bunce. 823b39c5158Smillert 824b39c5158SmillertCurrently maintained by the Perl 5 Porters, <perl5-porters@perl.org>. 825b39c5158Smillert 826b39c5158Smillert=cut 827