xref: /openbsd-src/gnu/usr.bin/perl/dist/Safe/Safe.pm (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
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