summaryrefslogtreecommitdiffstats
path: root/upstream/debian-unstable/man3/Safe.3perl
diff options
context:
space:
mode:
Diffstat (limited to 'upstream/debian-unstable/man3/Safe.3perl')
-rw-r--r--upstream/debian-unstable/man3/Safe.3perl387
1 files changed, 387 insertions, 0 deletions
diff --git a/upstream/debian-unstable/man3/Safe.3perl b/upstream/debian-unstable/man3/Safe.3perl
new file mode 100644
index 00000000..c69cd569
--- /dev/null
+++ b/upstream/debian-unstable/man3/Safe.3perl
@@ -0,0 +1,387 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "Safe 3perl"
+.TH Safe 3perl 2024-01-12 "perl v5.38.2" "Perl Programmers Reference Guide"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH NAME
+Safe \- Compile and execute code in restricted compartments
+.SH SYNOPSIS
+.IX Header "SYNOPSIS"
+.Vb 1
+\& use Safe;
+\&
+\& $compartment = new Safe;
+\&
+\& $compartment\->permit(qw(time sort :browse));
+\&
+\& $result = $compartment\->reval($unsafe_code);
+.Ve
+.SH DESCRIPTION
+.IX Header "DESCRIPTION"
+The Safe extension module allows the creation of compartments
+in which perl code can be evaluated. Each compartment has
+.IP "a new namespace" 8
+.IX Item "a new namespace"
+The "root" of the namespace (i.e. "main::") is changed to a
+different package and code evaluated in the compartment cannot
+refer to variables outside this namespace, even with run-time
+glob lookups and other tricks.
+.Sp
+Code which is compiled outside the compartment can choose to place
+variables into (or \fIshare\fR variables with) the compartment's namespace
+and only that data will be visible to code evaluated in the
+compartment.
+.Sp
+By default, the only variables shared with compartments are the
+"underscore" variables \f(CW$_\fR and \f(CW@_\fR (and, technically, the less frequently
+used \f(CW%_\fR, the _ filehandle and so on). This is because otherwise perl
+operators which default to \f(CW$_\fR will not work and neither will the
+assignment of arguments to \f(CW@_\fR on subroutine entry.
+.IP "an operator mask" 8
+.IX Item "an operator mask"
+Each compartment has an associated "operator mask". Recall that
+perl code is compiled into an internal format before execution.
+Evaluating perl code (e.g. via "eval" or "do 'file'") causes
+the code to be compiled into an internal format and then,
+provided there was no error in the compilation, executed.
+Code evaluated in a compartment compiles subject to the
+compartment's operator mask. Attempting to evaluate code in a
+compartment which contains a masked operator will cause the
+compilation to fail with an error. The code will not be executed.
+.Sp
+The default operator mask for a newly created compartment is
+the ':default' optag.
+.Sp
+It is important that you read the Opcode module documentation
+for more information, especially for detailed definitions of opnames,
+optags and opsets.
+.Sp
+Since it is only at the compilation stage that the operator mask
+applies, controlled access to potentially unsafe operations can
+be achieved by having a handle to a wrapper subroutine (written
+outside the compartment) placed into the compartment. For example,
+.Sp
+.Vb 5
+\& $cpt = new Safe;
+\& sub wrapper {
+\& # vet arguments and perform potentially unsafe operations
+\& }
+\& $cpt\->share(\*(Aq&wrapper\*(Aq);
+.Ve
+.SH WARNING
+.IX Header "WARNING"
+The Safe module does not implement an effective sandbox for
+evaluating untrusted code with the perl interpreter.
+.PP
+Bugs in the perl interpreter that could be abused to bypass
+Safe restrictions are not treated as vulnerabilities. See
+perlsecpolicy for additional information.
+.PP
+The authors make \fBno warranty\fR, implied or otherwise, about the
+suitability of this software for safety or security purposes.
+.PP
+The authors shall not in any case be liable for special, incidental,
+consequential, indirect or other similar damages arising from the use
+of this software.
+.PP
+Your mileage will vary. If in any doubt \fBdo not use it\fR.
+.SH METHODS
+.IX Header "METHODS"
+To create a new compartment, use
+.PP
+.Vb 1
+\& $cpt = new Safe;
+.Ve
+.PP
+Optional argument is (NAMESPACE), where NAMESPACE is the root namespace
+to use for the compartment (defaults to "Safe::Root0", incremented for
+each new compartment).
+.PP
+Note that version 1.00 of the Safe module supported a second optional
+parameter, MASK. That functionality has been withdrawn pending deeper
+consideration. Use the permit and deny methods described below.
+.PP
+The following methods can then be used on the compartment
+object returned by the above constructor. The object argument
+is implicit in each case.
+.SS "permit (OP, ...)"
+.IX Subsection "permit (OP, ...)"
+Permit the listed operators to be used when compiling code in the
+compartment (in \fIaddition\fR to any operators already permitted).
+.PP
+You can list opcodes by names, or use a tag name; see
+"Predefined Opcode Tags" in Opcode.
+.SS "permit_only (OP, ...)"
+.IX Subsection "permit_only (OP, ...)"
+Permit \fIonly\fR the listed operators to be used when compiling code in
+the compartment (\fIno\fR other operators are permitted).
+.SS "deny (OP, ...)"
+.IX Subsection "deny (OP, ...)"
+Deny the listed operators from being used when compiling code in the
+compartment (other operators may still be permitted).
+.SS "deny_only (OP, ...)"
+.IX Subsection "deny_only (OP, ...)"
+Deny \fIonly\fR the listed operators from being used when compiling code
+in the compartment (\fIall\fR other operators will be permitted, so you probably
+don't want to use this method).
+.SS "trap (OP, ...), untrap (OP, ...)"
+.IX Subsection "trap (OP, ...), untrap (OP, ...)"
+The trap and untrap methods are synonyms for deny and permit
+respectfully.
+.SS "share (NAME, ...)"
+.IX Subsection "share (NAME, ...)"
+This shares the variable(s) in the argument list with the compartment.
+This is almost identical to exporting variables using the Exporter
+module.
+.PP
+Each NAME must be the \fBname\fR of a non-lexical variable, typically
+with the leading type identifier included. A bareword is treated as a
+function name.
+.PP
+Examples of legal names are '$foo' for a scalar, '@foo' for an
+array, '%foo' for a hash, '&foo' or 'foo' for a subroutine and '*foo'
+for a glob (i.e. all symbol table entries associated with "foo",
+including scalar, array, hash, sub and filehandle).
+.PP
+Each NAME is assumed to be in the calling package. See share_from
+for an alternative method (which \f(CW\*(C`share\*(C'\fR uses).
+.SS "share_from (PACKAGE, ARRAYREF)"
+.IX Subsection "share_from (PACKAGE, ARRAYREF)"
+This method is similar to \fBshare()\fR but allows you to explicitly name the
+package that symbols should be shared from. The symbol names (including
+type characters) are supplied as an array reference.
+.PP
+.Vb 1
+\& $safe\->share_from(\*(Aqmain\*(Aq, [ \*(Aq$foo\*(Aq, \*(Aq%bar\*(Aq, \*(Aqfunc\*(Aq ]);
+.Ve
+.PP
+Names can include package names, which are relative to the specified PACKAGE.
+So these two calls have the same effect:
+.PP
+.Vb 2
+\& $safe\->share_from(\*(AqScalar::Util\*(Aq, [ \*(Aqreftype\*(Aq ]);
+\& $safe\->share_from(\*(Aqmain\*(Aq, [ \*(AqScalar::Util::reftype\*(Aq ]);
+.Ve
+.SS "varglob (VARNAME)"
+.IX Subsection "varglob (VARNAME)"
+This returns a glob reference for the symbol table entry of VARNAME in
+the package of the compartment. VARNAME must be the \fBname\fR of a
+variable without any leading type marker. For example:
+.PP
+.Vb 1
+\& ${$cpt\->varglob(\*(Aqfoo\*(Aq)} = "Hello world";
+.Ve
+.PP
+has the same effect as:
+.PP
+.Vb 2
+\& $cpt = new Safe \*(AqRoot\*(Aq;
+\& $Root::foo = "Hello world";
+.Ve
+.PP
+but avoids the need to know \f(CW$cpt\fR's package name.
+.SS "reval (STRING, STRICT)"
+.IX Subsection "reval (STRING, STRICT)"
+This evaluates STRING as perl code inside the compartment.
+.PP
+The code can only see the compartment's namespace (as returned by the
+\&\fBroot\fR method). The compartment's root package appears to be the
+\&\f(CW\*(C`main::\*(C'\fR package to the code inside the compartment.
+.PP
+Any attempt by the code in STRING to use an operator which is not permitted
+by the compartment will cause an error (at run-time of the main program
+but at compile-time for the code in STRING). The error is of the form
+"'%s' trapped by operation mask...".
+.PP
+If an operation is trapped in this way, then the code in STRING will
+not be executed. If such a trapped operation occurs or any other
+compile-time or return error, then $@ is set to the error message, just
+as with an \fBeval()\fR.
+.PP
+If there is no error, then the method returns the value of the last
+expression evaluated, or a return statement may be used, just as with
+subroutines and \fBeval()\fR. The context (list or scalar) is determined
+by the caller as usual.
+.PP
+If the return value of \fBreval()\fR is (or contains) any code reference,
+those code references are wrapped to be themselves executed always
+in the compartment. See "wrap_code_refs_within".
+.PP
+The formerly undocumented STRICT argument sets strictness: if true
+\&'use strict;' is used, otherwise it uses 'no strict;'. \fBNote\fR: if
+STRICT is omitted 'no strict;' is the default.
+.PP
+Some points to note:
+.PP
+If the entereval op is permitted then the code can use eval "..." to
+\&'hide' code which might use denied ops. This is not a major problem
+since when the code tries to execute the eval it will fail because the
+opmask is still in effect. However this technique would allow clever,
+and possibly harmful, code to 'probe' the boundaries of what is
+possible.
+.PP
+Any string eval which is executed by code executing in a compartment,
+or by code called from code executing in a compartment, will be eval'd
+in the namespace of the compartment. This is potentially a serious
+problem.
+.PP
+Consider a function \fBfoo()\fR in package pkg compiled outside a compartment
+but shared with it. Assume the compartment has a root package called
+\&'Root'. If \fBfoo()\fR contains an eval statement like eval '$foo = 1' then,
+normally, \f(CW$pkg::foo\fR will be set to 1. If \fBfoo()\fR is called from the
+compartment (by whatever means) then instead of setting \f(CW$pkg::foo\fR, the
+eval will actually set \f(CW$Root::pkg::foo\fR.
+.PP
+This can easily be demonstrated by using a module, such as the Socket
+module, which uses eval "..." as part of an AUTOLOAD function. You can
+\&'use' the module outside the compartment and share an (autoloaded)
+function with the compartment. If an autoload is triggered by code in
+the compartment, or by any code anywhere that is called by any means
+from the compartment, then the eval in the Socket module's AUTOLOAD
+function happens in the namespace of the compartment. Any variables
+created or used by the eval'd code are now under the control of
+the code in the compartment.
+.PP
+A similar effect applies to \fIall\fR runtime symbol lookups in code
+called from a compartment but not compiled within it.
+.SS "rdo (FILENAME)"
+.IX Subsection "rdo (FILENAME)"
+This evaluates the contents of file FILENAME inside the compartment.
+It uses the same rules as perl's built-in \f(CW\*(C`do\*(C'\fR to locate the file,
+poossibly using \f(CW@INC\fR.
+.PP
+See above documentation on the \fBreval\fR method for further details.
+.SS "root (NAMESPACE)"
+.IX Subsection "root (NAMESPACE)"
+This method returns the name of the package that is the root of the
+compartment's namespace.
+.PP
+Note that this behaviour differs from version 1.00 of the Safe module
+where the root module could be used to change the namespace. That
+functionality has been withdrawn pending deeper consideration.
+.SS "mask (MASK)"
+.IX Subsection "mask (MASK)"
+This is a get-or-set method for the compartment's operator mask.
+.PP
+With no MASK argument present, it returns the current operator mask of
+the compartment.
+.PP
+With the MASK argument present, it sets the operator mask for the
+compartment (equivalent to calling the deny_only method).
+.SS "wrap_code_ref (CODEREF)"
+.IX Subsection "wrap_code_ref (CODEREF)"
+Returns a reference to an anonymous subroutine that, when executed, will call
+CODEREF with the Safe compartment 'in effect'. In other words, with the
+package namespace adjusted and the opmask enabled.
+.PP
+Note that the opmask doesn't affect the already compiled code, it only affects
+any \fIfurther\fR compilation that the already compiled code may try to perform.
+.PP
+This is particularly useful when applied to code references returned from \fBreval()\fR.
+.PP
+(It also provides a kind of workaround for RT#60374: "Safe.pm sort {} bug with
+\&\-Dusethreads". See <https://rt.perl.org/rt3//Public/Bug/Display.html?id=60374>
+for \fImuch\fR more detail.)
+.SS "wrap_code_refs_within (...)"
+.IX Subsection "wrap_code_refs_within (...)"
+Wraps any CODE references found within the arguments by replacing each with the
+result of calling "wrap_code_ref" on the CODE reference. Any ARRAY or HASH
+references in the arguments are inspected recursively.
+.PP
+Returns nothing.
+.SH RISKS
+.IX Header "RISKS"
+This section is just an outline of some of the things code in a compartment
+might do (intentionally or unintentionally) which can have an effect outside
+the compartment.
+.IP Memory 8
+.IX Item "Memory"
+Consuming all (or nearly all) available memory.
+.IP CPU 8
+.IX Item "CPU"
+Causing infinite loops etc.
+.IP Snooping 8
+.IX Item "Snooping"
+Copying private information out of your system. Even something as
+simple as your user name is of value to others. Much useful information
+could be gleaned from your environment variables for example.
+.IP Signals 8
+.IX Item "Signals"
+Causing signals (especially SIGFPE and SIGALARM) to affect your process.
+.Sp
+Setting up a signal handler will need to be carefully considered
+and controlled. What mask is in effect when a signal handler
+gets called? If a user can get an imported function to get an
+exception and call the user's signal handler, does that user's
+restricted mask get re-instated before the handler is called?
+Does an imported handler get called with its original mask or
+the user's one?
+.IP "State Changes" 8
+.IX Item "State Changes"
+Ops such as chdir obviously effect the process as a whole and not just
+the code in the compartment. Ops such as rand and srand have a similar
+but more subtle effect.
+.SH AUTHOR
+.IX Header "AUTHOR"
+Originally designed and implemented by Malcolm Beattie.
+.PP
+Reworked to use the Opcode module and other changes added by Tim Bunce.
+.PP
+Currently maintained by the Perl 5 Porters, <perl5\-porters@perl.org>.