Re: Securing Parrot ASM
I see two different situations when permissions/capabilities are concerned: the first is when one tries to run untrusted code, modules or parts of code and needs some kind of sanboxing mechanism. Safe has been built with this situation in mind, mostly. The second is when one builds a perl system which is inteded to run potentialy untrustworty code from multiple users, such as in collaborative environments, muds, mushes and other kinds of online games. Restricted access to funcitions, variables and methods is needed, and an implementation of object ownership and user permissions, not just restrictions on code functionality. Perl5 has been completely usless in this field since it does not provide workable access restrictions and the Safe semantics (and bugs in its implementation) prevent and object-oriented interfaces between unrestricted and restricted code, or between two different restricted compartments. Any attemtps of mud writing in perl failed or provided muds with no ability for users to add code to the system. (Examples: http://kitenet.net/programs/perlmoo/, http://www.boutell.com/perlmud/) All these problems have been encountered and solved in the classic C-like scripting language of LP-muds, LPC. LPC is an object-oriented C derivative with heavy string manipulation extensions and solid support for multiuser security, running under the Muddriver (LPC virtual machine and low-level server fucntionality, written in C). LP muds are interesting because much of the game engine is written in LPC, including some interesting features, such as www interfaces, mail/news interfaces etc.: LPC is a complete, if tiny, language. I think developping a LPC compiler for Parrot would be a good exercice, it would provide a very useful little language and insure that the core contains any functionality that might be neede for multiuser systems coded in Perl6. (I am only sad that my bad coding skills do not permit me to do anything more substantial in this direction.) But I am completely convinced that the permission/ownership support as required by LPC is the minimal implementation needed in Parrot and Perl, if Perl6 is ever to be used in multiuser collaborative environments. More on LPC: http://www.lysator.liu.se/mud/lpc.html More on LP muds: http://www.alchar.org/~aedil/Prehistoric/lpmud.html An example of running LP mud with intellingent coders online: telnet://remud.org:4000/ __ Do You Yahoo!? Everything you'll ever need on one web page from News and Sport to Email and Music Charts http://uk.my.yahoo.com
Re: Securing Parrot ASM
On Wed, Jan 29, 2003 at 09:20:33AM +, 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. MBM -- Matthew Byng-Maddick [EMAIL PROTECTED] http://colondot.net/
Re: Securing Parrot ASM
On Tue, Jan 28, 2003 at 11:41:14AM +, 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/
Re: Securing Parrot ASM
On Tue, Jan 28, 2003 at 11:41:14AM +, 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 [EMAIL PROTECTED] http://colondot.net/
Re: Securing Parrot ASM
On Tue, Jan 28, 2003 at 02:11:39PM +, Matthew Byng-Maddick wrote: On Tue, Jan 28, 2003 at 11:41:14AM +, 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?). -- Twisted | Christopher Armstrong: International Man of Twistery Radix | Release Manager, Twisted Project -+ http://twistedmatrix.com/users/radix.twistd/
Re: Securing Parrot ASM
On Tue, Jan 28, 2003 at 11:04:43AM -0500, Christopher Armstrong wrote: On Tue, Jan 28, 2003 at 02:11:39PM +, 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). MBM -- Matthew Byng-Maddick [EMAIL PROTECTED] http://colondot.net/
Re: Securing Parrot ASM
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
Re: Securing Parrot ASM
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=jailapropos=0sektion=0manpath=FreeBSD+5.0-currentformat=html http://www.freebsd.org/cgi/man.cgi?query=jailapropos=0sektion=2manpath=FreeBSD+5.0-currentformat=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/
Re: Securing Parrot ASM
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 -- Matthew Byng-Maddick [EMAIL PROTECTED] http://colondot.net/
RE: Securing Parrot ASM
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 [EMAIL PROTECTED] @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
RE: Securing Parrot ASM
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. --Brent Dax [EMAIL PROTECTED] @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
Re: Securing Parrot ASM
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. -- Twisted | Christopher Armstrong: International Man of Twistery Radix | Release Manager, Twisted Project -+ http://twistedmatrix.com/users/radix.twistd/
Re: Securing Parrot ASM
On Tue, Jan 28, 2003 at 04:15:41PM +, Matthew Byng-Maddick wrote: On Tue, Jan 28, 2003 at 11:04:43AM -0500, Christopher Armstrong wrote: 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). 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/
Re: Securing Parrot ASM
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
Re: Securing Parrot ASM
Matthew == Matthew Byng-Maddick [EMAIL PROTECTED] 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. msg26694/pgp0.pgp Description: PGP signature
Re: Securing Parrot ASM
Brent == Brent Dax [EMAIL PROTECTED] 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/ msg26695/pgp0.pgp Description: PGP signature
Re: Securing Parrot ASM
At 11:41 AM + 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 [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk