=head1 NAME

docs/pdds/pdd18_security.pod - Parrot's security infrastructure

=head1 ABSTRACT

This PDD describes the safety, security, and quota infrastructure of
Parrot.

=head1 DESCRIPTION

There are three basic subsystems in Parrot's security system. They
are:

=over 4

=item Quotas

To ensure that an interpreter doesn't use more CPU time, memory, or
system resources than is allowed.

=item Privilege checks

To restrict access to what an interpreter can do.

=item Parameter checks

To double-check bytecode parameters for basic sanity.

=back

Each of these can be enabled or disabled separately, and each has a
particular purpose. Often two or more systems will be engaged at
once, but this isn't required.

=head2 Quotas

The purpose of a quota system is to ensure that an interpreter
doesn't use up too many resources -- usually memory and CPU, but
there may be other scarce resources, such as files, that need
managing. In a shared environment it prevents an interpreter from
hogging too many resources, either explicitly (as in a DOS attack) or
implicitly (through poor programming or poorly scheduled runs), and
preventing other interpreters from running.

=head2 Privilege checks

A privilege system is used to restrict code from performing certain
actions. When privilege checking is in force you may need a
particular privilege to load a library, or open a file.

Each interpreter has three sets of privileges. The first set is
the I<current> privilege set, which is the set of privileges 
currently in force. The second set is the set of I<authorized> 
privileges. These are the privileges that the interpreter is 
allowed to put into its current set. The third set are the I<sub>
privileges. These are the privileges that a sub has intrinsic to
itself, regardless of what the interpreter privileges currently
are. (Subs with privileges attached to them are called I<privileged
subs>, oddly enough).

An interpreter may drop any privilege it likes from the current
set. It may also at any time enable a privilege which is in the
authorized set but not in the current set. It is possible for a sub
to have a privilege in its current set which isn't in its authorized
set. Those privileges are, once dropped, gone.

Subroutines may also have a set of I<required privileges> attached to
them. The current interpreter B<must> have those privileges in its
current or sub set to call a subroutine so tagged. If the interpreter
doesn't have the privileges then a privilege violation exception is
thrown.

=head2 Parameter checking

In normal operation the interpreter assumes that the bytecode that it
executes is valid -- that is, any parameters to opcodes are sane,
data structures are intact, and the world, generally, is a good
place. When parameter checking is enabled, however, we assume that
bytecode is not necessarily valid. The interpreter then, at runtime,
makes sure that all specified register numbers are within valid
range, and string and PMC structures used are valid.

=head2 Feature usage

Each of the three features has a separate use. Parameter checking is
most useful when executing code which may come from an unsafe source,
for example from the network. Quotas are most useful when running
code in a managed environment such as a web, database, or game server where
no one interpreter is allowed to consume too many resources and
impact the system too badly. Privileges are used when running
untrusted code in a trusted environment, again such as a database or
game server, where Parrot can't disable certain features, but must
limit their use to trusted code.

It's unlikely that any one of these features will be enabled
individually, though there are certainly reasons to do so. Each
feature is separately implemented, however, and as such can be taken
singly and discussed.

=head1 IMPLEMENTATION

=head2 Quotas

Quota management is split into two separate parts, CPU time and
everything else.

=head3 CPU time

CPU time is managed by the runloop. There's a certain unavoidable
overhead, but there's no way around this, at least not reliably. (We may
be able to play interesting games with timer events and system event
handlers. We'll see).

=head3 Everything else

The rest of the quotas are enforced by code scattered across the
interpreter. The memory system handles memory quotas, the IO system
handles file open and pending IO count quotas, and so on. There's not
a whole lot for this, though we should abstract out all the
high-level operations that do things which may have quotas applied so
we can wrap these functions, so as not to pay the price when quotas
aren't in force.

For example, rather than having checks in the memory subsystem to see
if quotas are enabled (a check that would have to be done on each
memory allocation) we should instead access the memory allocation via
a function pointer stored off the interpreter somewhere. This way
when quotas are enabled we can swap in an alternate function pointer,
one that points to a function which checks quotas before calling into
the memory subsystem.

This should be relatively painless as most, if not all, of the
functions which should have quotas applied to them are also functions
which embedders may wish to override, and thus already need to be
accessed indirectly.

=head2 Privileges



=head2 Parameter Checking

Parameter checking is done with an alternate runloop, one where the
opcodes first check their parameters before executing. This is fairly
expensive, which is why it isn't the default mode for operations.
(The JIT may, at its choice, check parameters at JIT time). Checking
at load time is also somewhat problematic, as it is also somewhat
expensive, means the checker needs to know the signatures for ops
which may not have been loaded yet, and precludes code doing overly
clever things. (Which itself probably ought be forbidden, but that's
a separate problem).

The checking op variants are automatically generated by the op file
preprocessor, the same way that it generates all the other oploop
variants.

=head1 ATTACHMENTS


=head1 FOOTNOTES


=head1 REFERENCES



=head1 VERSION

=head2 CURRENT

    Maintainer: Dan Sugalski
    Class: Internal
    PDD Number: 18
    Version: 1.0
    Status: Developing
    Last Modified: 29 Aug 2004
    PDD Format: 1
    Language: English

=head2 HISTORY

=over 4

=item version 1

None. First version

=back

=head1 CHANGES

=over 4

=item Version 1.0

None. First version

=back

