VERSION Patch
[p5sagit/p5-mst-13.2.git] / ext / Safe / Safe.pm
CommitLineData
cb1a09d0 1package Safe;
73c78b0a 2
3use vars qw($VERSION @ISA @EXPORT_OK);
4
cb1a09d0 5require Exporter;
6require DynaLoader;
7use Carp;
73c78b0a 8$VERSION = "1.00";
cb1a09d0 9@ISA = qw(Exporter DynaLoader);
c07a80fd 10@EXPORT_OK = qw(op_mask ops_to_mask mask_to_ops opcode opname opdesc
cb1a09d0 11 MAXO emptymask fullmask);
12
13=head1 NAME
14
15Safe - Safe extension module for Perl
16
17=head1 DESCRIPTION
18
19The Safe extension module allows the creation of compartments
20in which perl code can be evaluated. Each compartment has
21
22=over 8
23
24=item a new namespace
25
26The "root" of the namespace (i.e. "main::") is changed to a
27different package and code evaluated in the compartment cannot
28refer to variables outside this namespace, even with run-time
29glob lookups and other tricks. Code which is compiled outside
30the compartment can choose to place variables into (or share
31variables with) the compartment's namespace and only that
32data will be visible to code evaluated in the compartment.
33
34By default, the only variables shared with compartments are the
35"underscore" variables $_ and @_ (and, technically, the much less
36frequently used %_, the _ filehandle and so on). This is because
37otherwise perl operators which default to $_ will not work and neither
38will the assignment of arguments to @_ on subroutine entry.
39
40=item an operator mask
41
42Each compartment has an associated "operator mask". Recall that
43perl code is compiled into an internal format before execution.
44Evaluating perl code (e.g. via "eval" or "do 'file'") causes
45the code to be compiled into an internal format and then,
46provided there was no error in the compilation, executed.
47Code evaulated in a compartment compiles subject to the
48compartment's operator mask. Attempting to evaulate code in a
49compartment which contains a masked operator will cause the
50compilation to fail with an error. The code will not be executed.
51
52By default, the operator mask for a newly created compartment masks
53out all operations which give "access to the system" in some sense.
54This includes masking off operators such as I<system>, I<open>,
55I<chown>, and I<shmget> but does not mask off operators such as
56I<print>, I<sysread> and I<E<lt>HANDLE<gt>>. Those file operators
57are allowed since for the code in the compartment to have access
58to a filehandle, the code outside the compartment must have explicitly
59placed the filehandle variable inside the compartment.
60
61Since it is only at the compilation stage that the operator mask
62applies, controlled access to potentially unsafe operations can
63be achieved by having a handle to a wrapper subroutine (written
64outside the compartment) placed into the compartment. For example,
65
66 $cpt = new Safe;
67 sub wrapper {
68 # vet arguments and perform potentially unsafe operations
69 }
70 $cpt->share('&wrapper');
71
72=back
73
74=head2 Operator masks
75
76An operator mask exists at user-level as a string of bytes of length
77MAXO, each of which is either 0x00 or 0x01. Here, MAXO is the number
78of operators in the current version of perl. The subroutine MAXO()
79(available for export by package Safe) returns the number of operators
80in the current version of perl. Note that, unlike the beta versions of
81the Safe extension, this is a reliable count of the number of
82operators in the currently running perl executable. The presence of a
830x01 byte at offset B<n> of the string indicates that operator number
84B<n> should be masked (i.e. disallowed). The Safe extension makes
85available routines for converting from operator names to operator
86numbers (and I<vice versa>) and for converting from a list of operator
87names to the corresponding mask (and I<vice versa>).
88
89=head2 Methods in class Safe
90
91To create a new compartment, use
92
93 $cpt = new Safe;
94
95Optional arguments are (NAMESPACE, MASK), where
96
97=over 8
98
99=item NAMESPACE
100
101is the root namespace to use for the compartment (defaults to
102"Safe::Root000000000", auto-incremented for each new compartment); and
103
104=item MASK
105
106is the operator mask to use (defaults to a fairly restrictive set).
107
108=back
109
110The following methods can then be used on the compartment
111object returned by the above constructor. The object argument
112is implicit in each case.
113
114=over 8
115
116=item root (NAMESPACE)
117
118This is a get-or-set method for the compartment's namespace. With the
119NAMESPACE argument present, it sets the root namespace for the
120compartment. With no NAMESPACE argument present, it returns the
121current root namespace of the compartment.
122
123=item mask (MASK)
124
125This is a get-or-set method for the compartment's operator mask.
126With the MASK argument present, it sets the operator mask for the
127compartment. With no MASK argument present, it returns the
128current operator mask of the compartment.
129
130=item trap (OP, ...)
131
132This sets bits in the compartment's operator mask corresponding
133to each operator named in the list of arguments. Each OP can be
134either the name of an operation or its number. See opcode.h or
135opcode.pl in the main perl distribution for a canonical list of
136operator names.
137
138=item untrap (OP, ...)
139
140This resets bits in the compartment's operator mask corresponding
141to each operator named in the list of arguments. Each OP can be
142either the name of an operation or its number. See opcode.h or
143opcode.pl in the main perl distribution for a canonical list of
144operator names.
145
146=item share (VARNAME, ...)
147
148This shares the variable(s) in the argument list with the compartment.
149Each VARNAME must be the B<name> of a variable with a leading type
150identifier included. Examples of legal variable names are '$foo' for
151a scalar, '@foo' for an array, '%foo' for a hash, '&foo' for a
152subroutine and '*foo' for a glob (i.e. all symbol table entries
153associated with "foo", including scalar, array, hash, sub and filehandle).
154
155=item varglob (VARNAME)
156
157This returns a glob for the symbol table entry of VARNAME in the package
158of the compartment. VARNAME must be the B<name> of a variable without
159any leading type marker. For example,
160
161 $cpt = new Safe 'Root';
162 $Root::foo = "Hello world";
163 # Equivalent version which doesn't need to know $cpt's package name:
164 ${$cpt->varglob('foo')} = "Hello world";
165
166
167=item reval (STRING)
168
169This evaluates STRING as perl code inside the compartment. The code
170can only see the compartment's namespace (as returned by the B<root>
171method). Any attempt by code in STRING to use an operator which is
172in the compartment's mask will cause an error (at run-time of the
173main program but at compile-time for the code in STRING). The error
174is of the form "%s trapped by operation mask operation...". If an
175operation is trapped in this way, then the code in STRING will not
176be executed. If such a trapped operation occurs or any other
177compile-time or return error, then $@ is set to the error message,
178just as with an eval(). If there is no error, then the method returns
179the value of the last expression evaluated, or a return statement may
180be used, just as with subroutines and B<eval()>. Note that this
181behaviour differs from the beta distribution of the Safe extension
182where earlier versions of perl made it hard to mimic the return
183behaviour of the eval() command.
184
185=item rdo (FILENAME)
186
187This evaluates the contents of file FILENAME inside the compartment.
188See above documentation on the B<reval> method for further details.
189
190=back
191
192=head2 Subroutines in package Safe
193
194The Safe package contains subroutines for manipulating operator
195names and operator masks. All are available for export by the package.
196The canonical list of operator names is the contents of the array
197op_name defined and initialised in file F<opcode.h> of the Perl
198source distribution.
199
200=over 8
201
202=item ops_to_mask (OP, ...)
203
204This takes a list of operator names and returns an operator mask
205with precisely those operators masked.
206
207=item mask_to_ops (MASK)
208
209This takes an operator mask and returns a list of operator names
210corresponding to those operators which are masked in MASK.
211
212=item opcode (OP, ...)
213
214This takes a list of operator names and returns the corresponding
215list of opcodes (which can then be used as byte offsets into a mask).
216
217=item opname (OP, ...)
218
219This takes a list of opcodes and returns the corresponding list of
220operator names.
221
222=item fullmask
223
224This just returns a mask which has all operators masked.
225It returns the string "\1" x MAXO().
226
227=item emptymask
228
229This just returns a mask which has all operators unmasked.
230It returns the string "\0" x MAXO(). This is useful if you
231want a compartment to make use of the namespace protection
232features but do not want the default restrictive mask.
233
234=item MAXO
235
236This returns the number of operators (and hence the length of an
237operator mask). Note that, unlike the beta distributions of the
238Safe extension, this is derived from a genuine integer variable
239in the perl executable and not from a preprocessor constant.
240This means that the Safe extension is more robust in the presence
241of mismatched versions of the perl executable and the Safe extension.
242
243=item op_mask
244
245This returns the operator mask which is actually in effect at the
246time the invocation to the subroutine is compiled. In general,
247this is probably not terribly useful.
248
249=back
250
251=head2 AUTHOR
252
253Malcolm Beattie, mbeattie@sable.ox.ac.uk.
254
255=cut
256
8bb1f2cf 257my $default_root = 'Root000000000';
258
259my $default_mask;
cb1a09d0 260
261sub new {
262 my($class, $root, $mask) = @_;
263 my $obj = {};
264 bless $obj, $class;
8bb1f2cf 265 $obj->root(defined($root) ? $root : ("Safe::".$default_root++));
cb1a09d0 266 $obj->mask(defined($mask) ? $mask : $default_mask);
267 # We must share $_ and @_ with the compartment or else ops such
268 # as split, length and so on won't default to $_ properly, nor
269 # will passing argument to subroutines work (via @_). In fact,
270 # for reasons I don't completely understand, we need to share
271 # the whole glob *_ rather than $_ and @_ separately, otherwise
272 # @_ in non default packages within the compartment don't work.
273 *{$obj->root . "::_"} = *_;
274 return $obj;
275}
276
8bb1f2cf 277sub DESTROY {
278 my($obj) = @_;
279 my $root = $obj->root();
280 if ($root =~ /^Safe::(Root\d+)$/){
281 $root = $1;
282 delete $ {"Safe::"}{"$root\::"};
283 }
284}
285
cb1a09d0 286sub root {
287 my $obj = shift;
288 if (@_) {
289 $obj->{Root} = $_[0];
290 } else {
291 return $obj->{Root};
292 }
293}
294
295sub mask {
296 my $obj = shift;
297 if (@_) {
298 $obj->{Mask} = verify_mask($_[0]);
299 } else {
300 return $obj->{Mask};
301 }
302}
303
304sub verify_mask {
305 my($mask) = @_;
306 if (length($mask) != MAXO() || $mask !~ /^[\0\1]+$/) {
307 croak("argument is not a mask");
308 }
309 return $mask;
310}
311
312sub trap {
313 my $obj = shift;
314 $obj->setmaskel("\1", @_);
315}
316
317sub untrap {
318 my $obj = shift;
319 $obj->setmaskel("\0", @_);
320}
321
322sub emptymask { "\0" x MAXO() }
323sub fullmask { "\1" x MAXO() }
324
325sub setmaskel {
326 my $obj = shift;
327 my $val = shift;
328 croak("bad value for mask element") unless $val eq "\0" || $val eq "\1";
329 my $maskref = \$obj->{Mask};
330 my ($op, $opcode);
331 foreach $op (@_) {
332 $opcode = ($op =~ /^\d/) ? $op : opcode($op);
333 substr($$maskref, $opcode, 1) = $val;
334 }
335}
336
337sub share {
338 my $obj = shift;
339 my $root = $obj->root();
340 my ($arg);
341 foreach $arg (@_) {
342 my $var;
343 ($var = $arg) =~ s/^(.)//;
344 my $caller = caller;
345 *{$root."::$var"} = ($1 eq '$') ? \${$caller."::$var"}
346 : ($1 eq '@') ? \@{$caller."::$var"}
347 : ($1 eq '%') ? \%{$caller."::$var"}
348 : ($1 eq '*') ? *{$caller."::$var"}
349 : ($1 eq '&') ? \&{$caller."::$var"}
350 : croak(qq(No such variable type for "$1$var"));
351 }
352}
353
354sub varglob {
355 my ($obj, $var) = @_;
356 return *{$obj->root()."::$var"};
357}
358
359sub reval {
360 my ($obj, $expr) = @_;
361 my $root = $obj->{Root};
362 my $mask = $obj->{Mask};
363 verify_mask($mask);
364
365 my $evalsub = eval sprintf(<<'EOT', $root);
366 package %s;
367 sub {
368 eval $expr;
369 }
370EOT
371 return safe_call_sv($root, $mask, $evalsub);
372}
373
374sub rdo {
375 my ($obj, $file) = @_;
376 my $root = $obj->{Root};
377 my $mask = $obj->{Mask};
378 verify_mask($mask);
379
380 $file =~ s/"/\\"/g; # just in case the filename contains any double quotes
381 my $evalsub = eval sprintf(<<'EOT', $root, $file);
382 package %s;
383 sub {
384 do "%s";
385 }
386EOT
387 return safe_call_sv($root, $mask, $evalsub);
388}
389
73c78b0a 390bootstrap Safe $VERSION;
cb1a09d0 391
c07a80fd 392$default_mask = fullmask;
393my $name;
394while (defined ($name = <DATA>)) {
395 chomp $name;
396 next if $name =~ /^#/;
397 my $code = opcode($name);
398 substr($default_mask, $code, 1) = "\0";
399}
cb1a09d0 400
4011;
c07a80fd 402
403__DATA__
404null
405stub
406scalar
407pushmark
408wantarray
409const
410gvsv
411gv
412gelem
413padsv
414padav
415padhv
416padany
417pushre
418rv2gv
419rv2sv
420av2arylen
421rv2cv
422anoncode
423prototype
424refgen
425srefgen
426ref
427bless
428glob
429readline
430rcatline
431regcmaybe
432regcomp
433match
434subst
435substcont
436trans
437sassign
438aassign
439chop
440schop
441chomp
442schomp
443defined
444undef
445study
446pos
447preinc
448i_preinc
449predec
450i_predec
451postinc
452i_postinc
453postdec
454i_postdec
455pow
456multiply
457i_multiply
458divide
459i_divide
460modulo
461i_modulo
462repeat
463add
464i_add
465subtract
466i_subtract
467concat
468stringify
469left_shift
470right_shift
471lt
472i_lt
473gt
474i_gt
475le
476i_le
477ge
478i_ge
479eq
480i_eq
481ne
482i_ne
483ncmp
484i_ncmp
485slt
486sgt
487sle
488sge
489seq
490sne
491scmp
492bit_and
493bit_xor
494bit_or
495negate
496i_negate
497not
498complement
499atan2
500sin
501cos
502rand
503srand
504exp
505log
506sqrt
507int
508hex
509oct
510abs
511length
512substr
513vec
514index
515rindex
516sprintf
517formline
518ord
519chr
520crypt
521ucfirst
522lcfirst
523uc
524lc
525quotemeta
526rv2av
527aelemfast
528aelem
529aslice
530each
531values
532keys
533delete
534exists
535rv2hv
536helem
537hslice
538split
539join
540list
541lslice
542anonlist
543anonhash
544splice
545push
546pop
547shift
548unshift
549reverse
550grepstart
551grepwhile
552mapstart
553mapwhile
554range
555flip
556flop
557and
558or
559xor
560cond_expr
561andassign
562orassign
563method
564entersub
565leavesub
566caller
567warn
568die
569reset
570lineseq
571nextstate
572dbstate
573unstack
574enter
575leave
576scope
577enteriter
578iter
579enterloop
580leaveloop
581return
582last
583next
584redo
585goto
586close
587fileno
588tie
589untie
590dbmopen
591dbmclose
592sselect
593select
594getc
595read
596enterwrite
597leavewrite
598prtf
599print
600sysread
601syswrite
602send
603recv
604eof
605tell
606seek
607truncate
608fcntl
609ioctl
610sockpair
611bind
612connect
613listen
614accept
615shutdown
616gsockopt
617ssockopt
618getsockname
619ftrwrite
620ftsvtx
621open_dir
622readdir
623telldir
624seekdir
625rewinddir
626kill
627getppid
628getpgrp
629setpgrp
630getpriority
631setpriority
632time
633tms
634localtime
635alarm
636dofile
637entereval
638leaveeval
639entertry
640leavetry
641ghbyname
642ghbyaddr
643ghostent
644gnbyname
645gnbyaddr
646gnetent
647gpbyname
648gpbynumber
649gprotoent
650gsbyname
651gsbyport
652gservent
653shostent
654snetent
655sprotoent
656sservent
657ehostent
658enetent
659eprotoent
660eservent
661gpwnam
662gpwuid
663gpwent
664spwent
665epwent
666ggrnam
667ggrgid
668ggrent
669sgrent
670egrent