Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Securing Parrot ASM

8 views
Skip to first unread message

Thomas Whateley

unread,
Jan 28, 2003, 6:41:14 AM1/28/03
to perl6-i...@perl.org
Hi,

I've been thinking about how to run un-trusted code,
without having to audit every line, or use some sort of sandbox,
and was wondering if Parrot could provide a Mandator Access
Control mechanism (ala SE Linux/Flask).

When assembling Parrot, the assembler could either look in a
file or a perl BEGIN type block containing a list of access
requests along the lines of:

syscall time
read-write directory /tmp
listen socket 80
connect socket 25
read-write file /etc/shadow


These commands should be easy/quick to audit, could be easily
generated by higher level language complier from similar
directives in whichever language it is compiling, and parrot
would guarentee that only these system priviledges were
provided.

As a sysadmin I'd certainly be gratefull to have a small
block to audit and be certain of what a module/program could
do to my system.

If people think something like this would be usefull, I'd be
more than happy to research this further and try to come up
with some code....


Cheers,
Tom

Christopher Armstrong

unread,
Jan 28, 2003, 8:25:21 AM1/28/03
to perl6-i...@perl.org, Thomas Whateley
On Tue, Jan 28, 2003 at 11:41:14AM +0000, Thomas Whateley wrote:
> Hi,
>
> I've been thinking about how to run un-trusted code,
> without having to audit every line, or use some sort of sandbox,
> and was wondering if Parrot could provide a Mandator Access
> Control mechanism (ala SE Linux/Flask).
>
> When assembling Parrot, the assembler could either look in a
> file or a perl BEGIN type block containing a list of access
> requests along the lines of:
>
> syscall time
> read-write directory /tmp
> listen socket 80
> connect socket 25
> read-write file /etc/shadow
>

> If people think something like this would be usefull, I'd be
> more than happy to research this further and try to come up
> with some code....


It would be immensely useful, especially for online, distributed
games, in addition to general sysadmin paranoia. I'm very interested
in this. It reminds me of the capability systems. I'm admittedly
pretty culeless when it comes to this stuff, but it's one of the
reasons I really want Parrot to succeed.

Of course, doing this on the parrot level brings up some interesting
issues; how exactly do we define what needs to be restricted in case
of untrusted code? I'm inclined to say "All classes", because a white
list is really the only sane way to do security, with defaults being
classes that are deemed harmless. Also, I think that this should be
made as dynamic as possible so different languages/applications can
plug in to the security system to overload certain things
(intentionally vague here).

One other thing to think about is resource limits. It'd be nice to not
require `ulimit' or whatever system-specific resource limitation
mechanism, but rather rely on the parrot interpreter to
baby-sit. Also, it'd make catching these resource-limit violations
much more convenient; an exception could be raised (or, e.g., the rate
at which bytecodes are executed could be throttled), rather than
simply rudely killing the process. For what I want to do, it's not
really required, and it's not really relevant to the type of security
we're discussing here, but it would still be very, very useful.

Some incoherent ramblings of mine about secure distributed code in
virtual worlds:

http://twistedmatrix.com/users/radix.twistd/Distributed_20Games

A really cool research-project language, "E", which is all about
capabilities:

http://erights.org/

CapDesk, a slightly irrelevant but very interesting design for
capability UIs:

http://www.combex.com/tech/index.html


--
Twisted | Christopher Armstrong: International Man of Twistery
Radix | Release Manager, Twisted Project
---------+ http://twistedmatrix.com/users/radix.twistd/

Matthew Byng-Maddick

unread,
Jan 28, 2003, 9:11:39 AM1/28/03
to perl6-i...@perl.org
On Tue, Jan 28, 2003 at 11:41:14AM +0000, Thomas Whateley wrote:
> I've been thinking about how to run un-trusted code,
> without having to audit every line, or use some sort of sandbox,
[snip]

> block to audit and be certain of what a module/program could
> do to my system.

As author of http://dev.perl.org/rfc/353.pod, I thought somewhat about
these issues, and eventually hit a rather hard brick wall.

What happens when you link in some module that's written natively?
Basically, my conclusion was that this was, unfortunately, still
necessary, but once you do it, then all bets about restriction and
security are off. If you can get around the necessity of that (and
only allow things which are parrot-native, then you can control it).

> If people think something like this would be usefull, I'd be
> more than happy to research this further and try to come up
> with some code....

I suspect you'll end up hitting the same problems as I did, but
if you want to do it in the situations where there is no linking
allowed, then it's probably sane.

MBM

--
Matthew Byng-Maddick <m...@colondot.net> http://colondot.net/

Matthew Byng-Maddick

unread,
Jan 28, 2003, 11:15:41 AM1/28/03
to perl6-i...@perl.org
On Tue, Jan 28, 2003 at 11:04:43AM -0500, Christopher Armstrong wrote:

> On Tue, Jan 28, 2003 at 02:11:39PM +0000, Matthew Byng-Maddick wrote:
> > What happens when you link in some module that's written natively?
> > Basically, my conclusion was that this was, unfortunately, still
> Hrm, maybe I just don't know what's going on, but I'm not sure why
> this is a problem. Couldn't "call out to native functions" or perhaps
> "call out to native functions in this library" or even "call out to
> *this* native function" be a capability? AFAIC (which means "for the
> applications I'm interested in"), any of the three are still Good
> Enough.

Oh, yes, it is still a reasonable capability, but at the point that you
allow that capability, you can forget any of the rest of them. (this is
of course, ignoring any possible buffer overruns/format string/double-free
or other types of vulnerability where you can change the executed code).

> I guess what I'm saying is, sure, you can't stop a native function
> (which was called from parrot code) from doing whatever it wants, but
> you can still prevent the parrot code from using that function in the
> first place (right?).

Yes, but looking at the current Perl core, a large number of the
day-to-day useful modules are written native (read: in C), so you end
up losing there. That's not to say that future ones will have to be,
but... In reality, however, the problem as I see it is that this is a
capability which, once acquired overrides all others (wheras the others
can be mutually orthogonal).

Joseph Guhlin

unread,
Jan 28, 2003, 11:39:33 AM1/28/03
to perl6-i...@perl.org
Pardon my ignorance on the whole issue but I'm just a lurker trying to
understand enough to help out. =)
I know security on parrot like this would be difficult, and this thread
is specifically about securing PASM, but what about something like
FreeBSD's 'jail' command built in? That way, even untrusted code could
possibly be set(somewhere in the parrot configuration, compile time,
command line, enviroment, etc...) to be jailed. The man pages are here:

http://www.freebsd.org/cgi/man.cgi?query=jail&apropos=0&sektion=0&manpath=FreeBSD+5.0-current&format=html
http://www.freebsd.org/cgi/man.cgi?query=jail&apropos=0&sektion=2&manpath=FreeBSD+5.0-current&format=html

I don't know if this will help or not, but this discussion brought to my
mind this. If anyone wants the source it should be available via the web
or I can forward it to any who ask.

Sorry for being so out of the loop. =/

--Joseph Guhlin
http://www.josephguhlin.com/

Christopher Armstrong

unread,
Jan 28, 2003, 11:04:43 AM1/28/03
to perl6-i...@perl.org, Matthew Byng-Maddick
On Tue, Jan 28, 2003 at 02:11:39PM +0000, Matthew Byng-Maddick wrote:
> On Tue, Jan 28, 2003 at 11:41:14AM +0000, Thomas Whateley wrote:
> > I've been thinking about how to run un-trusted code,
> > without having to audit every line, or use some sort of sandbox,
> [snip]
> > block to audit and be certain of what a module/program could
> > do to my system.
>
> As author of http://dev.perl.org/rfc/353.pod, I thought somewhat about
> these issues, and eventually hit a rather hard brick wall.
>
> What happens when you link in some module that's written natively?
> Basically, my conclusion was that this was, unfortunately, still
> necessary, but once you do it, then all bets about restriction and
> security are off. If you can get around the necessity of that (and
> only allow things which are parrot-native, then you can control it).

Hrm, maybe I just don't know what's going on, but I'm not sure why


this is a problem. Couldn't "call out to native functions" or perhaps
"call out to native functions in this library" or even "call out to
*this* native function" be a capability? AFAIC (which means "for the
applications I'm interested in"), any of the three are still Good
Enough.

I guess what I'm saying is, sure, you can't stop a native function


(which was called from parrot code) from doing whatever it wants, but
you can still prevent the parrot code from using that function in the
first place (right?).

--

Fred K Ollinger

unread,
Jan 28, 2003, 11:29:05 AM1/28/03
to Thomas Whateley, perl6-i...@perl.org
> I've been thinking about how to run un-trusted code,
> without having to audit every line, or use some sort of sandbox,
> and was wondering if Parrot could provide a Mandator Access
> Control mechanism (ala SE Linux/Flask).

I think that this is a great idea.

> When assembling Parrot, the assembler could either look in a
> file or a perl BEGIN type block containing a list of access
> requests along the lines of:
>
> syscall time
> read-write directory /tmp
> listen socket 80
> connect socket 25
> read-write file /etc/shadow

Wouldn't it also help to add a chroot layer?

In my mind, /etc/passwd should not even _exist_ to untrusted code. It
should be chrooted to its own dir.

Yes, I realize that one can concievable break out of a chroot, but this
should be made really hard.

Fred Ollinger


Christopher Armstrong

unread,
Jan 28, 2003, 12:43:15 PM1/28/03
to perl6-i...@perl.org, Matthew Byng-Maddick

I don't see why. Why, for example, would socket access (a
C-implemented feature, certainly) allow access to everything else?
Presumably, the built-in parrot[/perl/python/etc] functionality is
`trusted' such that it only does what it *says* it does (after
auditing and removing 100% of the bugs, of course ;), and you can give
out caps to them on a per-func/obj/whatever basis. But maybe I'm
totally misunderstanding what you're saying. Are you just assuming
there are bugs in all native built-in functions that are exploitable
to gain other capabilities? An example would help.

Anyway, even if you're right about access to native functions, the way
I'm thinking I'd use this would be to have a trusted program (i.e., my
imaginary virtual world engine) running various untrusted scripts from
around the world. With such a system, we'll just give the untrusted
code access to application-level APIs (which themselves will be
managed with capabilities, to facilitate differing trust levels) -- no
need to give them access to such things as file I/O and
whatnot. However, I guess socket access would be required, as I plan
on having them executed in a separate process (with ulimits) and talk
to the main system through an RPC (i.e., sockets) mechanism, with
probably a chroot/jail thrown in for good measure, but this is an easy
thing to audit and I can't see ever requiring more low-level access.

--
Twisted | Christopher Armstrong: International Man of Twistery
Radix | Release Manager, Twisted Project

--------+ http://twistedmatrix.com/users/radix.twistd/

Fred K Ollinger

unread,
Jan 28, 2003, 12:43:26 PM1/28/03
to Matthew Byng-Maddick, perl6-i...@perl.org
> On Tue, Jan 28, 2003 at 10:39:33AM -0600, Joseph Guhlin wrote:
> > Pardon my ignorance on the whole issue but I'm just a lurker trying to
> > understand enough to help out. =)
> > I know security on parrot like this would be difficult, and this thread
> > is specifically about securing PASM, but what about something like
> > FreeBSD's 'jail' command built in? That way, even untrusted code could
> > possibly be set(somewhere in the parrot configuration, compile time,
> > command line, enviroment, etc...) to be jailed. The man pages are here:
>
> The fun bit is getting information in and out of the jail. ie. you trust
> a module but not one of its derived classes.... Also, you might wish to
> note that both jail(2) and chroot(2) need to be called by the super-user.

If it's jail and something gets out then it's not a good jail.

To me jail means what you see is what you get. If you trust code in the
jail, then you should be ok.

> The reason you can't do a jail entirely within Parrot is that the moment
> you link to any native code, all bets are off, and you're reliant on
> what the kernel allows you to do. Parrot can no longer control it.

This is probably out of my league. I'm sure your right on this one.

> It seems to me that the linking with native code is going to end up
> being one that most people switch on, because it will be necessary
> and/or useful in getting anything done.

Well, that would mean two parrots, which I think is great. One w/ jail for
untested code, one w/o.

I see four levels of security:

1. chroot jail where / is the toplevel /parrot. If there needs to be a
/usr, then it's /parrot/usr.

2. catching all calls and keeping them in line. For example, there are
some opcodes that can't work in "sandbox" mode.

3. Manually checking over all libs that are linked to for safety. Only
"safe" (those that can't be used to pick your way out of jail) go into
/jail/lib.

4. Many things that I have not thought of, but are known to others.

This is probably overly general and simplistic, but I just want to make
sure that when we are talking about #2, people don't think that they mean
#3 or heaven forbid #4.

Fred Ollinger

Matthew Byng-Maddick

unread,
Jan 28, 2003, 12:06:38 PM1/28/03
to perl6-i...@perl.org
On Tue, Jan 28, 2003 at 10:39:33AM -0600, Joseph Guhlin wrote:
> Pardon my ignorance on the whole issue but I'm just a lurker trying to
> understand enough to help out. =)
> I know security on parrot like this would be difficult, and this thread
> is specifically about securing PASM, but what about something like
> FreeBSD's 'jail' command built in? That way, even untrusted code could
> possibly be set(somewhere in the parrot configuration, compile time,
> command line, enviroment, etc...) to be jailed. The man pages are here:

The fun bit is getting information in and out of the jail. ie. you trust


a module but not one of its derived classes.... Also, you might wish to
note that both jail(2) and chroot(2) need to be called by the super-user.

The reason you can't do a jail entirely within Parrot is that the moment


you link to any native code, all bets are off, and you're reliant on
what the kernel allows you to do. Parrot can no longer control it.

It seems to me that the linking with native code is going to end up


being one that most people switch on, because it will be necessary
and/or useful in getting anything done.

MBM

Christopher Armstrong

unread,
Jan 28, 2003, 12:19:49 PM1/28/03
to perl6-i...@perl.org, Brent Dax
On Tue, Jan 28, 2003 at 09:24:20AM -0800, Brent Dax wrote:
> Christopher Armstrong:
> # One other thing to think about is resource limits. It'd be nice to not
> # require `ulimit' or whatever system-specific resource limitation
> # mechanism, but rather rely on the parrot interpreter to
> # baby-sit. Also, it'd make catching these resource-limit violations
> # much more convenient; an exception could be raised (or, e.g., the rate
> # at which bytecodes are executed could be throttled), rather than
> # simply rudely killing the process. For what I want to do, it's not
> # really required, and it's not really relevant to the type of security
> # we're discussing here, but it would still be very, very useful.
>
> I don't see why Parrot couldn't do much of this. It can certainly audit
> allocations made through its own memory-allocation system, and with only
> a little help from the system it should be able to audit its processor
> usage as well (at least within Parrot bytecode). I'm not sure about
> disk space usage, but that's a pretty OS-level thing anyway.

Cool. I'm really only concerned about CPU and memory usage, as I'd
never allow plain file I/O to my untrusted code -- just
application-level APIs for doing specific things that might access the
disk.

Brent Dax

unread,
Jan 28, 2003, 12:24:20 PM1/28/03
to Christopher Armstrong, perl6-i...@perl.org, Thomas Whateley
Christopher Armstrong:
# One other thing to think about is resource limits. It'd be nice to not
# require `ulimit' or whatever system-specific resource limitation
# mechanism, but rather rely on the parrot interpreter to
# baby-sit. Also, it'd make catching these resource-limit violations
# much more convenient; an exception could be raised (or, e.g., the rate
# at which bytecodes are executed could be throttled), rather than
# simply rudely killing the process. For what I want to do, it's not
# really required, and it's not really relevant to the type of security
# we're discussing here, but it would still be very, very useful.

I don't see why Parrot couldn't do much of this. It can certainly audit
allocations made through its own memory-allocation system, and with only
a little help from the system it should be able to audit its processor
usage as well (at least within Parrot bytecode). I'm not sure about
disk space usage, but that's a pretty OS-level thing anyway.

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

>How do you "test" this 'God' to "prove" it is who it says it is?
"If you're God, you know exactly what it would take to convince me. Do
that."
--Marc Fleury on alt.atheism


Brent Dax

unread,
Jan 28, 2003, 12:28:24 PM1/28/03
to Matthew Byng-Maddick, perl6-i...@perl.org
Matthew Byng-Maddick:
# It seems to me that the linking with native code is going to
# end up being one that most people switch on, because it will
# be necessary and/or useful in getting anything done.

Then make sure that "link in native code" isn't a permission--"link in
native code library X" is. That way the sysadmin or whoever can make
sure that only harmless libraries get in. The control mechanism could
be in Parrot_dlopen, which would make (well-behaved) native libraries
subject to it too.

Allen Short

unread,
Jan 28, 2003, 1:07:07 PM1/28/03
to perl6-i...@perl.org
>>>>> "Matthew" == Matthew Byng-Maddick <pe...@lists.colondot.net> writes:

>> I guess what I'm saying is, sure, you can't stop a native
>> function (which was called from parrot code) from doing
>> whatever it wants, but you can still prevent the parrot code
>> from using that function in the first place (right?).

> Yes, but looking at the current Perl core, a large number of the
> day-to-day useful modules are written native (read: in C), so
> you end up losing there. That's not to say that future ones will
> have to be, but... In reality, however, the problem as I see it
> is that this is a capability which, once acquired overrides all
> others (wheras the others can be mutually orthogonal).

Obviously this is a problem; however, this is one of the easier things
to solve in a system like Parrot. By constructing proxies to the native
libraries that allow the insertion of checks and restrictions, untrusted
code can be written to use the usual APIs without allowing them to
assume the full power of the usual implementations. So, presumably,
in the restricted environment, File would be replaced with
RestrictedFile which only allows accessing files in a certain
subdirectory, or owned by a particular user, or such; Socket would be
replaced with RestrictedSocket which can only connect to certain
hosts, or must prompt for permission to connect; and so on. One could
even imagine something like a RestrictedCanvas in a GUI application,
that allows the untrusted code to draw only on a small portion of the
application's window.

All this is very close to achievable in existing language; the *hard*
part is preventing DoS attacks on CPU and memory. Parrot should make
that doable as well, with the ability to run multiple interpreters in
the same process.

Allen Short

unread,
Jan 28, 2003, 1:39:23 PM1/28/03
to perl6-i...@perl.org
>>>>> "Brent" == Brent Dax <bren...@cpan.org> writes:


> I don't see why Parrot couldn't do much of this. It can
> certainly audit allocations made through its own
> memory-allocation system, and with only a little help from the
> system it should be able to audit its processor usage as well
> (at least within Parrot bytecode). I'm not sure about disk
> space usage, but that's a pretty OS-level thing anyway.

Shouldn't this be doable by starting a separate 'restricted
interpreter' within the process that is given a limit on the number of
bytecodes it can run and amount of memory it can allocate? As far as I
can see, this would achieve the primary goals of restriction
(throttling CPU/memory use). Filesystem usage can be controlled
through a restricted file API, so that shouldn't be a very low-level
concern.

A system that might be worth examining is Darius Bacon's "idel", a
small VM designed for running untrusted code.

http://www.accesscom.com/~darius/software/idel/

Dan Sugalski

unread,
Jan 28, 2003, 2:26:14 PM1/28/03
to Thomas Whateley, perl6-i...@perl.org
At 11:41 AM +0000 1/28/03, Thomas Whateley wrote:
>Hi,
>
>I've been thinking about how to run un-trusted code,
>without having to audit every line, or use some sort of sandbox,
>and was wondering if Parrot could provide a Mandator Access
>Control mechanism (ala SE Linux/Flask).

Ah, I've been hoping to avoid this for a while for sheer, screaming
lack of tuits, but... Here's the deal for 'safe mode'. (For
background, as everyone in the Unix world seems to be happy
reinventing security wheels, surf over to the VMS doc site at
http://www.openvms.compaq.com/doc, and the VMS system security manual
specifically at either
http://www.openvms.compaq.com/doc/731FINAL/6346/6346PRO.HTM or
http://www.openvms.compaq.com/doc/731FINAL/DOCUMENTATION/PDF/OVMS_731_SYS_SEC.PDF)

Posits:
*) We may potentially put in resource quotas. This includes time,
memory, CPU usage, I/O requests, and I/O bytes
*) We may be running untrustworthy code which will try and subvert
the interpreter
*) We may potentially put in access controls which restrict what code can do
*) Embedders may want to intercept all file IO calls anyway

So, here's the facilities we're going to build.

*) There'll be an alternate set of opcodes that validate their
parameters, so no sneaky trying to access register 554, or branching
off the end of the world.

*) There'll be a set of 'privileges' of some sort (call 'em
capabilities or whatever) and to do various tasks will require that
you have an appropriate privilege

*) You will be able to load in external code (and I realize that
there is the general "Hit C and all bets are off" rule). External
modules will have the potential to have trust rights attached to them
so we can mark C things that are actually safe as loadable, or
loadable in certain circumstances

*) Code segments can be granted temporarily elevated privs,
presumably being done for code that's been audited and deemed safe

*) Data will be marked as tainted if it comes from an external source
for perl/ruby style taint checking
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Matthew Byng-Maddick

unread,
Jan 28, 2003, 5:36:25 PM1/28/03
to perl6-i...@perl.org
On Tue, Jan 28, 2003 at 02:26:14PM -0500, Dan Sugalski wrote:
> *) There'll be a set of 'privileges' of some sort (call 'em
> capabilities or whatever) and to do various tasks will require that
> you have an appropriate privilege

Please don't use "capabilities" for this. The term "capability" is quite
specific in this area, and refers to something like a reference to an
object method, but with access. (i.e. you can't get use the reference
without the capability). See also:
http://www.eros-os.org/essays/00Essays.html

Thomas Whateley

unread,
Jan 29, 2003, 4:20:33 AM1/29/03
to Dan Sugalski, perl6-i...@perl.org
* Dan Sugalski <d...@sidhe.org> [030128 19:30]:

> Ah, I've been hoping to avoid this for a while for sheer, screaming
> lack of tuits, but... Here's the deal for 'safe mode'. (For
> background, as everyone in the Unix world seems to be happy
> reinventing security wheels,

Hey! I wasn't trying to invent anything... I just wanted to
steal it from the wrong place ;)

[snip]

Thanks... I'll get reading...

one more quick question.. would it be possible to play linker games
to redirect syscalls (from compiled c) to wrapper functions that check
permissions? Would that allow us to secure dynamicly linked libs??


Cheers,
Tom

Matthew Byng-Maddick

unread,
Jan 29, 2003, 6:08:13 AM1/29/03
to perl6-i...@perl.org
On Wed, Jan 29, 2003 at 09:20:33AM +0000, Thomas Whateley wrote:
> one more quick question.. would it be possible to play linker games
> to redirect syscalls (from compiled c) to wrapper functions that check
> permissions? Would that allow us to secure dynamicly linked libs??

When I said "as soon as you go to native code, you lose", that was
precisely what I was referring to. You just write the syscall in an
asm{} block, and you can forget any library getting in the way.

0 new messages