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