NAME

Opcode - Disable named opcodes when compiling perl code

SYNOPSIS

use Opcode;

DESCRIPTION

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 evaulated in a compartment compiles subject to the compartment's operator mask. Attempting to evaulate code in a compartment which contains a masked operator will cause the compilation to fail with an error. The code will not be executed.

By default, the operator mask for a newly created compartment masks out all operations which give "access to the system" in some sense. This includes masking off operators such as system, open, chown, and shmget but does not mask off operators such as print, sysread and <HANDL>. Those file operators are allowed since for the code in the compartment to have access to a filehandle, the code outside the compartment must have explicitly placed the filehandle variable inside the compartment.

(Note: the definition of the default ops is not yet finalised.)

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,

$cpt = new Opcode;
sub wrapper {
    # vet arguments and perform potentially unsafe operations
}
$cpt->share('&wrapper');

Confusingly the term 'operator mask' is used to refer to the 'masking out' of operators during compilation and also to a value defining a set of operators. The term 'opset' is being more widely used to refer to the latter but you may still come across mask being used instead.

Operator Names and Operator Lists

XXX

The canonical list of operator names is the contents of the array op_name defined and initialised in file opcode.h of the Perl source distribution (and installed into the perl library).

Each operator has both a terse name and a more verbose or recognisable descriptive name. The opdesc function can be used to return a list of descriptions for a list of operators.

Many of the functions and methods listed below take a lists of operators as parameters. Operator lists can be made up of several types of elements. Each element can be one of

an operator name (opname)

XXX

an operator tag name (optag)

Operator tags can be used to refer to groups (or sets) of operators. Tag names always being with a colon. The Opcode module defines several optags and the user can define others using the define_optag function.

a negated opname or optag

XXX

an operator set (opset)

An opset as an opaque binary string of approximately 43 bytes which holds a set or zero or more operators.

The ops_to_opset and opset_to_ops functions can be used to convert from a list of operators to an opset (and vice versa).

Wherever a list of operators can be given you can use one or more opsets.

Subroutines in package Opcode

The Opcode package contains subroutines for manipulating operator names tags and sets. All are available for export by the package.

ops_to_opset (OP, ...)

This takes a list of operators and returns an opset representing precisely those operators.

opset_to_ops (OPSET)

This takes an opset and returns a list of operator names corresponding to those operators in the set.

full_opset

This just returns opset which includes all operators.

empty_opset

This just returns an opset which contains no operators.

This is useful if you want a compartment to make use of the namespace protection features but do not want the default restrictive mask.

define_optag (OPTAG, OPSET)

Define OPTAG as a symbolic name for OPSET. Optag names always start with a colon :. The optag name used must not be defined already (define_optag will croak if it is already defined). Optag names are global to the perl process and optag definitions cannot be altered or deleted once defined.

It is strongly recommended that applications using Opcode should use a leading capital letter on their tag names since lowercase names are reserved for use by the Opcode module. If using Opcode within a module you should prefix your tags names with the name of your module to ensure uniqueness.

opdesc (OP, ...)

This takes a list of operator names and returns the corresponding list of operator descriptions.

opcodes

In a scalar context opcodes returns the number of opcodes in this version of perl.

In a list context it returns a list of all the operator names.

Some Safety Issues

This section is currently 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.

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.

Predefined Opcode Tags

:base_core
null stub scalar pushmark wantarray const defined undef

rv2sv sassign

rv2av aassign aelem aelemfast aslice

rv2hv helem hslice each values keys exists -- no delete here

preinc i_preinc predec i_predec postinc i_postinc postdec i_postdec
int hex oct abs pow multiply i_multiply divide i_divide modulo
i_modulo add i_add subtract i_subtract

left_shift right_shift bit_and bit_xor bit_or negate i_negate
not complement

lt i_lt gt i_gt le i_le ge i_ge eq i_eq ne i_ne ncmp i_ncmp
slt sgt sle sge seq sne scmp

substr vec stringify study pos length index rindex ord chr

ucfirst lcfirst uc lc quotemeta trans chop schop chomp schomp

splice push pop shift unshift reverse

cond_expr flip flop andassign orassign and or xor

warn die lineseq nextstate unstack scope enter leave

entersub leavesub return method -- XXX loops via recursion?

leaveeval -- needed for Safe to operate, is safe without entereval
:base_mem

These memory related ops are not included in :base_core because they can easily be used to implement a resource attack (e.g., consume all available memory).

concat repeat join

anonlist anonhash

Note that despite the existance of this optag a memory resource attack may still be possible using only :base_core ops.

Disabling these ops is a very heavy handed way to attempt to prevent a memory resource attack. It's probable that a specific memory limit mechanism will be added to perl in the near future.

:base_loop

These loop ops are not included in :base_core because they can easily be used to implement a resource attack (e.g., consume all available CPU time).

grepstart grepwhile
mapstart mapwhile
enteriter iter
enterloop leaveloop
last next redo
:base_orig

These are a hotchpotch of opcodes still waiting to be considered

gvsv gv gelem

padsv padav padhv padany

pushre

rv2gv av2arylen rv2cv anoncode prototype refgen
srefgen ref bless

glob readline rcatline

regcmaybe regcomp match subst substcont

sprintf formline

crypt

delete -- hash elem

split list lslice

range

reset

caller dbstate goto

tie untie

dbmopen dbmclose sselect select getc read enterwrite leavewrite
prtf print sysread syswrite send recv eof tell seek truncate fcntl
sockpair bind connect listen accept shutdown gsockopt
getsockname

ftrwrite ftsvtx

open_dir readdir closedir telldir seekdir rewinddir

getppid getpgrp setpgrp getpriority setpriority localtime gmtime

entertry leavetry

ghbyname ghbyaddr ghostent gnbyname gnbyaddr gnetent gpbyname
gpbynumber gprotoent gsbyname gsbyport gservent shostent snetent
sprotoent sservent ehostent enetent eprotoent eservent

gpwnam gpwuid gpwent spwent epwent ggrnam ggrgid ggrent sgrent
egrent
:base_math

These ops are not included in :base_core because of the risk of them being used to generate floating point exceptions (which would have to be caught using a $SIG{FPE} handler).

atan2 sin cos exp log sqrt

These ops are not included in :base_core because they have an effect beyond the scope of the compartment.

rand srand
:default

The default set of ops allowed in a compartment. (The current ops allowed are unstable while development continues. It will change.)

:base_core :base_mem :base_loop :base_orig
:subprocess
backtick system

fork

wait waitpid
:ownprocess
exec exit dump syscall kill

time tms -- could be used for timing attacks (paranoid?)
:filesys_open
sysopen open close umask
:filesys_read
stat lstat readlink

ftatime ftblk ftchr ftctime ftdir fteexec fteowned fteread
ftewrite ftfile ftis ftlink ftmtime ftpipe ftrexec ftrowned
ftrread ftsgid ftsize ftsock ftsuid fttty ftzero

fttext ftbinary

fileno
:filesys_write
link unlink rename symlink

mkdir rmdir

utime chmod chown
:others

This tag holds groups of assorted specialist opcodes that don't warrant having optags defined for them.

SystemV Interprocess Communications:

msgctl msgget msgrcv msgsnd

semctl semget semop

shmctl shmget shmread shmwrite
:still_to_be_decided
chdir
chroot
require dofile 
binmode
flock ioctl
getlogin
pipe_op socket getpeername ssockopt 
sleep alarm
sort
tied
pack unpack
entereval -- can be used to hide code
:foo

Just an example to show and test negation

:default !spwent !sgrent

AUTHOR

Originally designed and implemented by Malcolm Beattie, mbeattie@sable.ox.ac.uk as part of Safe version 1.

Split out from Safe module version 1, Optags and other changes added by Tim Bunce <Tim.Bunce@ig.co.uk>.

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 83:

'=item' outside of any '=over'

Around line 124:

You forgot a '=back' before '=head2'