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