Hi all.
Here's a generic problem for people that like puzzles that I can't seem to work out: I want to add "Domains" to Squeak, so that system resources can be managed. Here's how it would work, in theory: * A domain would typically be a group of objects related to a particular application. * Every object belongs to a domain. And then: - A domain's memory usage can be capped. Object>>new would be implemented so that it would wait for free memory or throw an Exception if the memory cap has been breached. - A domain can only start up a limited number of Processes. This would control fork bombs etc. Process>>new or some other entry point would check for this and wait or throw an Exception if the process limit has been breached. - Ditto for other system resources, such as disk usage, network bandwidth, access to devices etc. - I'm implementing a distributed system, so remote objects that come in will already belong to a particular domain. A local DomainManager or some other mechanism would determine if objects from that domain are allowed to use local system resources, and at which priorities. For example, I could have two domains: "AlicesEmail" an "BobsEmail". AlicesEmail is capped at 10Mb of memory and 6 processes. BobsEmail is capped at 20Mb of memory and 15 processes. Assuming that the Squeak image is a remote mail server; now neither Alice nor Bob can make the image explode by doing funny things with their email. Both domains use the same classes. Now, here's the problem: How would I implement Object>>new and Process>>new (or other equally good locations) so that the domain for that object is found and a DomainManager queried about that domain's privileges? The possibilities that I've thought of so far are: 1. Adding an instance variable called 'domain' to Object is a bad idea - consider SmallIntegers and parts of the VM that assume certain instance variables are in certain places. 2. Creating dictionaries of which objects are in which domains would work, but is going to be extremely inefficient. _Every_ object in the image would have an entry in these dictionaries. 3. Creating a subclass of Object with an instance variable "domain" could work, and then all other objects that are used by domain-using code are subclasses. I'm still thinking through the implications. 4. Assigning domains to processes rather than objects is a possibility, but this would allow resource theft when invocations are done on objects out of the current domain. If this was done, the current domain would just be <<thisContext domain>>. 5. Another option is to make radical changes to the VM, so that a domain of objects are all kept in the same range of memory. This would be a rather major change and would introduce bugs. 6. I could do fancy tricks with the garbage collector like ImageSegment does and trace references back to an object which identifies the current domain. This is slow and yuck. So far alternatives 3 or 4 seem possible. Thinking aloud; option 4 could be implemented by implementing Domain>>doPrivileged: taking a block as an argument. Object>>new and Process>>new can then search down the stack until Domain>>doPrivileged: is found and ask the global DomainManager what that domain is allowed to do. Calls out of the current domain can be stripped of privileges by doing something like noPrivilegesDomain>>doPrivileged: [otherObject doSomething]. otherObject would then need to call doPrivileged: again with its own domain to regain the ability to fork and make new objects. Umm... this would need some way of preventing user processes from peeking down the stack and stealing another domain (i.e. using capability-based security). Option 3 has the advantage of making less work for the poor application developer, but incurs an extra pointer for every single object. Java does something similar, but it does it based on classes or jar files (afaik). This is not particularly good - you can't have two domains with different privileges which share the same implementation. For example, you can't have an "AlicesEmail" and "BobsEmail" domains with different privileges if they both use the same classes. Thoughts? Does anything like this already exist? Mikevdg. |
Michael van der Gulik wrote:
> Hi all. > > Here's a generic problem for people that like puzzles that I can't seem > to work out: I want to add "Domains" to Squeak, so that system resources > can be managed. > > Here's how it would work, in theory: > > * A domain would typically be a group of objects related to a particular > application. > * Every object belongs to a domain. > > And then: > > - A domain's memory usage can be capped. Object>>new would be > implemented so that it would wait for free memory or throw an Exception > if the memory cap has been breached. Finding total memory usage for a Domain seems to be pretty difficult. There's a PointerFinder class which would work if every object in a domain had a reference to that domain, but that looks expensive. If I did domains by assigning a domain to each Process, then memory usage per domain would be impossible to calculate. Back to the drawing board... VM hacking might be needed :-(. Michael. |
In reply to this post by Michael van der Gulik
Hi Michael,
If changing the base object is not possible (like adding an ivar to Object) then solve the problem with a back pointer. Object subclass: DomainConnector Ivars: 'domain subject' Object subclass: Domain Ivars: 'name' Obviously you need a way to figure out what domain a user is on Object subclass: User Ivars: '.... domain' Now for every object created that needs to be attached to a domain you do DomainConnector addObject: anObject toDomain: aDomain "Create a domain connector object which links anObject to aDomain ^self new subject: anObject; domain: aDomain; yourself. Depending on whether or not you are using a database you could manage objects. As you said not every object needs a domain so you could implement a #needsDomain method on the objects that need it. Consider root objects and places where creating a dependent object doesn't make sense to your class model (I would never have classB without an instance of ClassA) and then implement needs domain on that root class. The update of domain objects could be done at the time of commit for a database, commitObjectsForUser: aUser domainObjects := self objectsToCommit select: [:a | a needsDomain]. domainObjects do: [:a | DomainConnector addObject: a toDomain: aUser domain]. Or you could change new to do newForUser on root objects. There are lots of possibilities, the main point is that once the connecter is created you can find out if an object is in a domain by querying the back pointer. If you are in a database the query is simple Object >> isInDomain: aDomain self needsDomain ifFalse: [NotInDomainError signal: 'Not a Domain Object']. aConnector := DomainConnector where: [:a | a subject = self]. ^aConnector domain = aDomain If you are not in a database then updating a dictionary that lives on a class variable that separates by class, object oids or something will speed lookup of domain objects. aConnector := (DomainConnecter someOrginazationDictionaryFind: self ). ^aConnector domain = aDomain. Hope that helps! Happy coding! Ron Teitelbaum President / Principal Software Engineer US Medical Record Specialists [hidden email] > -----Original Message----- > From: [hidden email] [mailto:squeak-dev- > [hidden email]] On Behalf Of Michael van der Gulik > Sent: Saturday, August 05, 2006 5:20 AM > To: [hidden email] > Subject: Puzzle: Adding domain-based security to Squeak. > > Hi all. > > Here's a generic problem for people that like puzzles that I can't seem > to work out: I want to add "Domains" to Squeak, so that system resources > can be managed. > > Here's how it would work, in theory: > > * A domain would typically be a group of objects related to a particular > application. > * Every object belongs to a domain. > > And then: > > - A domain's memory usage can be capped. Object>>new would be > implemented so that it would wait for free memory or throw an Exception > if the memory cap has been breached. > > - A domain can only start up a limited number of Processes. This would > control fork bombs etc. Process>>new or some other entry point would > check for this and wait or throw an Exception if the process limit has > been breached. > > - Ditto for other system resources, such as disk usage, network > bandwidth, access to devices etc. > > - I'm implementing a distributed system, so remote objects that come in > will already belong to a particular domain. A local DomainManager or > some other mechanism would determine if objects from that domain are > allowed to use local system resources, and at which priorities. > > For example, I could have two domains: "AlicesEmail" an "BobsEmail". > AlicesEmail is capped at 10Mb of memory and 6 processes. BobsEmail is > capped at 20Mb of memory and 15 processes. Assuming that the Squeak > image is a remote mail server; now neither Alice nor Bob can make the > image explode by doing funny things with their email. Both domains use > the same classes. > > Now, here's the problem: > > How would I implement Object>>new and Process>>new (or other equally > good locations) so that the domain for that object is found and a > DomainManager queried about that domain's privileges? > > The possibilities that I've thought of so far are: > > 1. Adding an instance variable called 'domain' to Object is a bad idea - > consider SmallIntegers and parts of the VM that assume certain instance > variables are in certain places. > > 2. Creating dictionaries of which objects are in which domains would > work, but is going to be extremely inefficient. _Every_ object in the > image would have an entry in these dictionaries. > > 3. Creating a subclass of Object with an instance variable "domain" > could work, and then all other objects that are used by domain-using > code are subclasses. I'm still thinking through the implications. > > 4. Assigning domains to processes rather than objects is a possibility, > but this would allow resource theft when invocations are done on objects > out of the current domain. If this was done, the current domain would > just be <<thisContext domain>>. > > 5. Another option is to make radical changes to the VM, so that a domain > of objects are all kept in the same range of memory. This would be a > rather major change and would introduce bugs. > > 6. I could do fancy tricks with the garbage collector like ImageSegment > does and trace references back to an object which identifies the current > domain. This is slow and yuck. > > So far alternatives 3 or 4 seem possible. > > Thinking aloud; option 4 could be implemented by implementing > Domain>>doPrivileged: taking a block as an argument. Object>>new and > Process>>new can then search down the stack until Domain>>doPrivileged: > is found and ask the global DomainManager what that domain is allowed to > do. Calls out of the current domain can be stripped of privileges by > doing something like noPrivilegesDomain>>doPrivileged: [otherObject > doSomething]. otherObject would then need to call doPrivileged: again > with its own domain to regain the ability to fork and make new objects. > > Umm... this would need some way of preventing user processes from > peeking down the stack and stealing another domain (i.e. using > capability-based security). > > Option 3 has the advantage of making less work for the poor application > developer, but incurs an extra pointer for every single object. > > Java does something similar, but it does it based on classes or jar > files (afaik). This is not particularly good - you can't have two > domains with different privileges which share the same implementation. > For example, you can't have an "AlicesEmail" and "BobsEmail" domains > with different privileges if they both use the same classes. > > Thoughts? Does anything like this already exist? > > Mikevdg. > |
In reply to this post by Michael van der Gulik
Seaside has a tool, WAMemoryUse, that uses ImageSegments. I'm not
sure if it does exactly what you want but you might like to check it out. The key part seems to be this: segment := ImageSegment new copyFromRoots: (Array with: root) sizeHint: 100000. results := segment doSpaceAnalysis. Cheers, Mike |
In reply to this post by Michael van der Gulik
Hi Michael,
since I cannot see what memory usage (or resource usage, for that matter) has to do with security, I suggest to refer to "planning for contingencies", like in - http://en.wikipedia.org/wiki/Defensive_design - http://www.google.com/search?q=%22planning+for+contingencies%22 A while back I had a discussion with Alexandre Bergel on "coloring" object memory (as part of the Goya project) and your description looks like an application of that idea. What we concluded by that time (pure theory ;-) was that the metaclass is sufficient for coloring memory resources (i.e. usage of memory, as in your case). Your "domain" members can be a (sub)set of instances of Metaclass, your "domain" can be a clone of Metaclass. Think that today's Metaclass belongs to the builtin *system* domain and that every domain user (or application instance, as you mentioned in your posting) gets a clone of Metaclass (and consequently the respective instances of Metaclass), on demand. So finding the total memory usage for one of your domains is pretty easy and the pointer which does it is the *class* pointer (no change to the VM), like (roughly) in domain "clone of Metaclass" allInstances inject: 0 into: [:accum :aDomainClass | aDomainClass allInstances ... + accum] Since I planned for a short response, I stop here (many more implications can be discussed, of course). I'm sure that coloring of object memory is something which is easy to implement and to maintain. /Klaus On Sat, 05 Aug 2006 13:10:33 +0200, Michael van der Gulik wrote: > Michael van der Gulik wrote: >> Hi all. >> Here's a generic problem for people that like puzzles that I can't >> seem to work out: I want to add "Domains" to Squeak, so that system >> resources can be managed. >> Here's how it would work, in theory: >> * A domain would typically be a group of objects related to a >> particular application. >> * Every object belongs to a domain. >> And then: >> - A domain's memory usage can be capped. Object>>new would be >> implemented so that it would wait for free memory or throw an Exception >> if the memory cap has been breached. > > Finding total memory usage for a Domain seems to be pretty difficult. > > There's a PointerFinder class which would work if every object in a > domain had a reference to that domain, but that looks expensive. > > If I did domains by assigning a domain to each Process, then memory > usage per domain would be impossible to calculate. > > Back to the drawing board... VM hacking might be needed :-(. > > Michael. > > > |
In reply to this post by Michael van der Gulik
Michael,
In my opinion, you're solving the wrong problem. Fun, perhaps, but not likely to help you win big. (FWIW, IMHO, YMMV, etc...) It seems to me that any attempt to put arbitrary, coarse-grained restrictions on computer resources -- as opposed to problem-domain or user-domain behaviors, is just doing a lot of work to shift the problem, without actually solving it. How will the programmer set these limits? How will the poor user or "administrator" manage them? I imagine that there must be a lot written in or about the Java community that gives examples of this. But in short, since users and administrators don't know whether or how much to limit non-behavior-oriented computer resources, they are forced to either trust an application completely, or to restrict it pretty-much completely, which makes it fairly useless. There is a better way. Now, there are two issues: 1. "But my customer wants to do it the broken way!" Fair enough. You might consider, though, whether or not this approach fits with the real advantages (to the customer, not to you) of using Squeak. If you turn the application into something that works just like Java except that it's in Squeak, you can bet the contract that in the end, the customer will decide to re-implement it in Java (for social reasons, such as covering their butts in deploying, hiring people to work on it, etc.) Doing a broken, Java-like thing "better than Java" is just a special case. 2. "OK, How SHOULD I do it?" Here you have to look at the actual problems you're trying to avoid. For example, suppose you want to keep mobile programs from writing files on a user's computer. The answer is to arrange to only present a 'file open' interface that prompts the user for the location. This is better than draconianly prohibiting all 'file open' requests, because it still allows arbitrary programs to do useful work as long as the user is made clearly aware of what the program is doing. (In an imperfect-world nod to resource management, that user dialog might specify the max size of the file.) Now suppose you want to have the system manage (e.g., remember) the fact that such-and-such an object has requested a file-open, and that the user has granted it for given name/size. The capabilities community (see e-rights) has a lot of literature on how to do this securely. But as I see it, the capabilities stuff is just an implementation detail for the higher-level issue of choosing what (or where) to manage problem-specific behaviors. (See end-to-end argument.) -Howard Michael van der Gulik wrote: > Hi all. > > Here's a generic problem for people that like puzzles that I can't > seem to work out: I want to add "Domains" to Squeak, so that system > resources can be managed. > > Here's how it would work, in theory: > > * A domain would typically be a group of objects related to a > particular application. > * Every object belongs to a domain. > > And then: > > - A domain's memory usage can be capped. Object>>new would be > implemented so that it would wait for free memory or throw an > Exception if the memory cap has been breached. > > - A domain can only start up a limited number of Processes. This would > control fork bombs etc. Process>>new or some other entry point would > check for this and wait or throw an Exception if the process limit has > been breached. > > - Ditto for other system resources, such as disk usage, network > bandwidth, access to devices etc. > > - I'm implementing a distributed system, so remote objects that come > in will already belong to a particular domain. A local DomainManager > or some other mechanism would determine if objects from that domain > are allowed to use local system resources, and at which priorities. > > For example, I could have two domains: "AlicesEmail" an "BobsEmail". > AlicesEmail is capped at 10Mb of memory and 6 processes. BobsEmail is > capped at 20Mb of memory and 15 processes. Assuming that the Squeak > image is a remote mail server; now neither Alice nor Bob can make the > image explode by doing funny things with their email. Both domains use > the same classes. > > Now, here's the problem: > > How would I implement Object>>new and Process>>new (or other equally > good locations) so that the domain for that object is found and a > DomainManager queried about that domain's privileges? > > The possibilities that I've thought of so far are: > > 1. Adding an instance variable called 'domain' to Object is a bad idea > - consider SmallIntegers and parts of the VM that assume certain > instance variables are in certain places. > > 2. Creating dictionaries of which objects are in which domains would > work, but is going to be extremely inefficient. _Every_ object in the > image would have an entry in these dictionaries. > > 3. Creating a subclass of Object with an instance variable "domain" > could work, and then all other objects that are used by domain-using > code are subclasses. I'm still thinking through the implications. > > 4. Assigning domains to processes rather than objects is a > possibility, but this would allow resource theft when invocations are > done on objects out of the current domain. If this was done, the > current domain would just be <<thisContext domain>>. > > 5. Another option is to make radical changes to the VM, so that a > domain of objects are all kept in the same range of memory. This would > be a rather major change and would introduce bugs. > > 6. I could do fancy tricks with the garbage collector like > ImageSegment does and trace references back to an object which > identifies the current domain. This is slow and yuck. > > So far alternatives 3 or 4 seem possible. > > Thinking aloud; option 4 could be implemented by implementing > Domain>>doPrivileged: taking a block as an argument. Object>>new and > Process>>new can then search down the stack until > Domain>>doPrivileged: is found and ask the global DomainManager what > that domain is allowed to do. Calls out of the current domain can be > stripped of privileges by doing something like > noPrivilegesDomain>>doPrivileged: [otherObject doSomething]. > otherObject would then need to call doPrivileged: again with its own > domain to regain the ability to fork and make new objects. > > Umm... this would need some way of preventing user processes from > peeking down the stack and stealing another domain (i.e. using > capability-based security). > > Option 3 has the advantage of making less work for the poor > application developer, but incurs an extra pointer for every single > object. > > Java does something similar, but it does it based on classes or jar > files (afaik). This is not particularly good - you can't have two > domains with different privileges which share the same implementation. > For example, you can't have an "AlicesEmail" and "BobsEmail" domains > with different privileges if they both use the same classes. > > Thoughts? Does anything like this already exist? > > Mikevdg. > > -- Howard Stearns University of Wisconsin - Madison Division of Information Technology mailto:[hidden email] jabber:[hidden email] voice:+1-608-262-3724 |
On Aug 7, 2006, at 4:29 PM, Howard Stearns wrote: > Michael, > > In my opinion, you're solving the wrong problem. Fun, perhaps, but > not likely to help you win big. (FWIW, IMHO, YMMV, etc...) > > It seems to me that any attempt to put arbitrary, coarse-grained > restrictions on computer resources -- as opposed to problem-domain > or user-domain behaviors, is just doing a lot of work to shift the > problem, without actually solving it. How will the programmer set > these limits? How will the poor user or "administrator" manage them? > > I imagine that there must be a lot written in or about the Java > community that gives examples of this. But in short, since users > and administrators don't know whether or how much to limit non- > behavior-oriented computer resources, they are forced to either > trust an application completely, or to restrict it pretty-much > completely, which makes it fairly useless. There is a better way. > > Now, there are two issues: > > 1. "But my customer wants to do it the broken way!" Fair enough. > You might consider, though, whether or not this approach fits with > the real advantages (to the customer, not to you) of using Squeak. > If you turn the application into something that works just like > Java except that it's in Squeak, you can bet the contract that in > the end, the customer will decide to re-implement it in Java (for > social reasons, such as covering their butts in deploying, hiring > people to work on it, etc.) Doing a broken, Java-like thing > "better than Java" is just a special case. > > 2. "OK, How SHOULD I do it?" Here you have to look at the actual > problems you're trying to avoid. For example, suppose you want to > keep mobile programs from writing files on a user's computer. The > answer is to arrange to only present a 'file open' interface that > prompts the user for the location. This is better than draconianly > prohibiting all 'file open' requests, because it still allows > arbitrary programs to do useful work as long as the user is made > clearly aware of what the program is doing. (In an imperfect-world > nod to resource management, that user dialog might specify the max > size of the file.) I very much agree. Some ways back I have written an authorisation system for a car leasing company along exactly these lines. They liked it. The nice part was that it was even administrable by end-users: Select a widget, give the functionality (either readable or clickable) of that widget a name, link name to a role, link the roles to persons, and voila.... Sure, you better don't forget any UI parts, but I do think that the end-to-end argument from Reeds and Co. applies to many aspects in software development -like security - also. http://web.mit.edu/Saltzer/www/publications/endtoend/endtoend.pdf At least in theory ;-) something should be locked, if all the outer ports of the castle surrounding it are locked. Cheers, Markus > Now suppose you want to have the system manage (e.g., remember) the > fact that such-and-such an object has requested a file-open, and > that the user has granted it for given name/size. The capabilities > community (see e-rights) has a lot of literature on how to do this > securely. But as I see it, the capabilities stuff is just an > implementation detail for the higher-level issue of choosing what > (or where) to manage problem-specific behaviors. (See end-to-end > argument.) > > -Howard > > Michael van der Gulik wrote: >> Hi all. >> >> Here's a generic problem for people that like puzzles that I can't >> seem to work out: I want to add "Domains" to Squeak, so that >> system resources can be managed. >> >> Here's how it would work, in theory: >> >> * A domain would typically be a group of objects related to a >> particular application. >> * Every object belongs to a domain. >> >> And then: >> >> - A domain's memory usage can be capped. Object>>new would be >> implemented so that it would wait for free memory or throw an >> Exception if the memory cap has been breached. >> >> - A domain can only start up a limited number of Processes. This >> would control fork bombs etc. Process>>new or some other entry >> point would check for this and wait or throw an Exception if the >> process limit has been breached. >> >> - Ditto for other system resources, such as disk usage, network >> bandwidth, access to devices etc. >> >> - I'm implementing a distributed system, so remote objects that >> come in will already belong to a particular domain. A local >> DomainManager or some other mechanism would determine if objects >> from that domain are allowed to use local system resources, and at >> which priorities. >> >> For example, I could have two domains: "AlicesEmail" an >> "BobsEmail". AlicesEmail is capped at 10Mb of memory and 6 >> processes. BobsEmail is capped at 20Mb of memory and 15 processes. >> Assuming that the Squeak image is a remote mail server; now >> neither Alice nor Bob can make the image explode by doing funny >> things with their email. Both domains use the same classes. >> >> Now, here's the problem: >> >> How would I implement Object>>new and Process>>new (or other >> equally good locations) so that the domain for that object is >> found and a DomainManager queried about that domain's privileges? >> >> The possibilities that I've thought of so far are: >> >> 1. Adding an instance variable called 'domain' to Object is a bad >> idea - consider SmallIntegers and parts of the VM that assume >> certain instance variables are in certain places. >> >> 2. Creating dictionaries of which objects are in which domains >> would work, but is going to be extremely inefficient. _Every_ >> object in the image would have an entry in these dictionaries. >> >> 3. Creating a subclass of Object with an instance variable >> "domain" could work, and then all other objects that are used by >> domain-using code are subclasses. I'm still thinking through the >> implications. >> >> 4. Assigning domains to processes rather than objects is a >> possibility, but this would allow resource theft when invocations >> are done on objects out of the current domain. If this was done, >> the current domain would just be <<thisContext domain>>. >> >> 5. Another option is to make radical changes to the VM, so that a >> domain of objects are all kept in the same range of memory. This >> would be a rather major change and would introduce bugs. >> >> 6. I could do fancy tricks with the garbage collector like >> ImageSegment does and trace references back to an object which >> identifies the current domain. This is slow and yuck. >> >> So far alternatives 3 or 4 seem possible. >> >> Thinking aloud; option 4 could be implemented by implementing >> Domain>>doPrivileged: taking a block as an argument. Object>>new >> and Process>>new can then search down the stack until >> Domain>>doPrivileged: is found and ask the global DomainManager >> what that domain is allowed to do. Calls out of the current domain >> can be stripped of privileges by doing something like >> noPrivilegesDomain>>doPrivileged: [otherObject doSomething]. >> otherObject would then need to call doPrivileged: again with its >> own domain to regain the ability to fork and make new objects. >> >> Umm... this would need some way of preventing user processes from >> peeking down the stack and stealing another domain (i.e. using >> capability-based security). >> >> Option 3 has the advantage of making less work for the poor >> application developer, but incurs an extra pointer for every >> single object. >> >> Java does something similar, but it does it based on classes or >> jar files (afaik). This is not particularly good - you can't have >> two domains with different privileges which share the same >> implementation. For example, you can't have an "AlicesEmail" and >> "BobsEmail" domains with different privileges if they both use the >> same classes. >> >> Thoughts? Does anything like this already exist? >> >> Mikevdg. >> >> > > -- > Howard Stearns > University of Wisconsin - Madison > Division of Information Technology > mailto:[hidden email] > jabber:[hidden email] > voice:+1-608-262-3724 > > |
In reply to this post by Howard Stearns
Hi Howard.
I forgot to mention that the reason I'm doing this is to allow untrusted foreign code to run in the same image as trusted code. Untrusted code must be carefully managed - it must not be able to consume large amounts of memory, CPU or disk space to which it is not entitled. Untrusted code / objects must not prevent trusted code from operating well. Oh, and Squeak is full of security holes, but there will be ways to patch them I'm sure. Howard Stearns wrote: > It seems to me that any attempt to put arbitrary, coarse-grained > restrictions on computer resources -- as opposed to problem-domain or > user-domain behaviors, is just doing a lot of work to shift the problem, > without actually solving it. How will the programmer set these limits? > How will the poor user or "administrator" manage them? The programmer, user or administrator will manage them "manually"; coarse-grained restrictions are course-grained, meaning that there aren't many of them. Example: You find a foreign set of objects and classes in a domain called "SqueakSeti@home" and decide to grant that domain access to you local computer: it is granted low-priority CPU only, memory is bound to 64MB, this domain may use 100MB of disk space and no more than 100MB of network bandwidth per day. Meanwhile, another domain called "ImportantBusinessStuff" can use high-priority CPU, no more than 256MB memory (i.e. the size of physical memory), etc. This all makes a lot more sense when working with a public distributed system where code and objects float from computer to computer. In this case, a group of distributed objects are all bound to a "Domain", and individual computers decide how much privilege that Domain has on each computer. > Now, there are two issues: > > 1. "But my customer wants to do it the broken way!" Fair enough. You > might consider, though, whether or not this approach fits with the real > advantages (to the customer, not to you) of using Squeak. If you turn > the application into something that works just like Java except that > it's in Squeak, you can bet the contract that in the end, the customer > will decide to re-implement it in Java (for social reasons, such as > covering their butts in deploying, hiring people to work on it, etc.) > Doing a broken, Java-like thing "better than Java" is just a special case. Umm... I don't get your point. This is for my own project. No customers, no Java. > 2. "OK, How SHOULD I do it?" Here you have to look at the actual > problems you're trying to avoid. For example, suppose you want to keep > mobile programs from writing files on a user's computer. The answer is > to arrange to only present a 'file open' interface that prompts the user > for the location. ...like a capability. > This is better than draconianly prohibiting all 'file > open' requests, because it still allows arbitrary programs to do useful > work as long as the user is made clearly aware of what the program is > doing. (In an imperfect-world nod to resource management, that user > dialog might specify the max size of the file.) Now suppose you want to > have the system manage (e.g., remember) the fact that such-and-such an > object has requested a file-open, and that the user has granted it for > given name/size. The capabilities community (see e-rights) has a lot of > literature on how to do this securely. But as I see it, the capabilities > stuff is just an implementation detail for the higher-level issue of > choosing what (or where) to manage problem-specific behaviors. (See > end-to-end argument.) That's what I intend to use domains for... they're a higher-level "management object" to manage problem-specific behaviours. A reference to a File object would be a capability. The "Domain" aggregates objects together so that permissions can be granted in bulk. Objects that need access to that File object (which is a capability) would ask their Domain instance for it. If the Domain instance does not have it, access is obviously not possible. Of course the implementation details might end up different, but the idea is that the local system grants Domains the rights to use system resources. Michael. |
In reply to this post by Michael Roberts-2
Michael Roberts wrote:
> Seaside has a tool, WAMemoryUse, that uses ImageSegments. I'm not sure > if it does exactly what you want but you might like to check it out. > > The key part seems to be this: > > segment := ImageSegment new copyFromRoots: (Array with: root) sizeHint: > 100000. > results := segment doSpaceAnalysis. Thanks. I'll try to work out if it is useful. Michael. |
In reply to this post by Klaus D. Witzel
Klaus D. Witzel wrote:
> Hi Michael, > > since I cannot see what memory usage (or resource usage, for that > matter) has to do with security, I suggest to refer to "planning for > contingencies", like in > > - http://en.wikipedia.org/wiki/Defensive_design > - http://www.google.com/search?q=%22planning+for+contingencies%22 In this case, the domaining *is* my defensive design :-). I'm trying to write a system where untrusted foreign code can run locally in a sandboxed environment within the image. > A while back I had a discussion with Alexandre Bergel on "coloring" > object memory (as part of the Goya project) and your description looks > like an application of that idea. What we concluded by that time (pure > theory ;-) was that the metaclass is sufficient for coloring memory > resources (i.e. usage of memory, as in your case). > > Your "domain" members can be a (sub)set of instances of Metaclass, your > "domain" can be a clone of Metaclass. Think that today's Metaclass > belongs to the builtin *system* domain and that every domain user (or > application instance, as you mentioned in your posting) gets a clone of > Metaclass (and consequently the respective instances of Metaclass), on > demand. > > So finding the total memory usage for one of your domains is pretty > easy and the pointer which does it is the *class* pointer (no change to > the VM), like (roughly) in > > domain "clone of Metaclass" allInstances inject: 0 into: [:accum > :aDomainClass | > aDomainClass allInstances ... + accum] > > Since I planned for a short response, I stop here (many more > implications can be discussed, of course). > > I'm sure that coloring of object memory is something which is easy to > implement and to maintain. Doesn't this implementation limit you to having all objects of one class bound to the same domain? How would you have two domains sharing the same implementation? For example, an "alicesEmail" domain and a "bobsEmail" domain would both share the classes implementing email stuff. Michael. |
In reply to this post by Ron Teitelbaum
Thanks, Ron.
This would assume that domains use some other form of aggregation - such as using the ImageSegment tricks that Michael Roberts suggested. I'm trying to work out if this presents another possibility for implementing what I'm trying. Thanks for the tip. Michael. Ron Teitelbaum wrote: > Hi Michael, > > If changing the base object is not possible (like adding an ivar to Object) > then solve the problem with a back pointer. > > Object subclass: DomainConnector > Ivars: 'domain subject' > > Object subclass: Domain > Ivars: 'name' > > Obviously you need a way to figure out what domain a user is on > > Object subclass: User > Ivars: '.... domain' > > Now for every object created that needs to be attached to a domain you do > > DomainConnector addObject: anObject toDomain: aDomain > "Create a domain connector object which links anObject to aDomain > > ^self new > subject: anObject; > domain: aDomain; > yourself. > > Depending on whether or not you are using a database you could manage > objects. > As you said not every object needs a domain so you could implement a > #needsDomain method on the objects that need it. Consider root objects and > places where creating a dependent object doesn't make sense to your class > model (I would never have classB without an instance of ClassA) and then > implement needs domain on that root class. > The update of domain objects could be done at the time of commit for > a database, > commitObjectsForUser: aUser > domainObjects := self objectsToCommit select: [:a | a > needsDomain]. > domainObjects do: [:a | DomainConnector addObject: a > toDomain: aUser domain]. > > Or you could change new to do newForUser on root objects. > > There are lots of possibilities, the main point is that once the connecter > is created you can find out if an object is in a domain by querying the back > pointer. > If you are in a database the query is simple > Object >> isInDomain: aDomain > self needsDomain ifFalse: [NotInDomainError signal: 'Not a > Domain Object']. > aConnector := DomainConnector where: [:a | a subject = > self]. > ^aConnector domain = aDomain > If you are not in a database then updating a dictionary that lives > on a class variable that separates by class, object oids or something will > speed lookup of domain objects. > aConnector := (DomainConnecter someOrginazationDictionaryFind: self > ). > ^aConnector domain = aDomain. > > Hope that helps! |
In reply to this post by Michael van der Gulik
"Michael van der Gulik" <[hidden email]> wrote:
> Hi Howard. > > I forgot to mention that the reason I'm doing this is to allow untrusted > foreign code to run in the same image as trusted code. Untrusted code > must be carefully managed - it must not be able to consume large amounts > of memory, CPU or disk space to which it is not entitled. Untrusted code > / objects must not prevent trusted code from operating well. Have you looked at the (Tweak) Islands [1] work? Lex Spoon also did work with the same name [2], IIRC. And there's the Squeak-E [3] stuff too. [1] http://tweak.impara.de/TECHNOLOGY/Whitepapers/Islands/ [2] http://minnow.cc.gatech.edu/squeak/2074 [3] http://www.erights.org/history/squeak-e.html frank |
None of the cited references will solve the original problem(s). They
are related but they won't solve it. Managing memory limits alone would require *major* modifications of the VM. Cheers, - Andreas Frank Shearar wrote: > "Michael van der Gulik" <[hidden email]> wrote: > >> Hi Howard. >> >> I forgot to mention that the reason I'm doing this is to allow untrusted >> foreign code to run in the same image as trusted code. Untrusted code >> must be carefully managed - it must not be able to consume large amounts >> of memory, CPU or disk space to which it is not entitled. Untrusted code >> / objects must not prevent trusted code from operating well. > > Have you looked at the (Tweak) Islands [1] work? Lex Spoon also did work > with the same name [2], IIRC. And there's the Squeak-E [3] stuff too. > > [1] http://tweak.impara.de/TECHNOLOGY/Whitepapers/Islands/ > [2] http://minnow.cc.gatech.edu/squeak/2074 > [3] http://www.erights.org/history/squeak-e.html > > frank > > > |
In reply to this post by Michael van der Gulik
Hi Michael,
on Tue, 08 Aug 2006 11:19:37 +0200, you wrote: > Klaus D. Witzel wrote: >> Hi Michael, >> since I cannot see what memory usage (or resource usage, for that >> matter) has to do with security, I suggest to refer to "planning for >> contingencies", like in >> - http://en.wikipedia.org/wiki/Defensive_design >> - http://www.google.com/search?q=%22planning+for+contingencies%22 > > In this case, the domaining *is* my defensive design :-). I'm trying to > write a system where untrusted foreign code can run locally in a > sandboxed environment within the image. O.K. when untrusted code (and/or the untrusted user) is in the scope I agree that your defensive design has something to do with security :) >> A while back I had a discussion with Alexandre Bergel on "coloring" >> object memory (as part of the Goya project) and your description looks >> like an application of that idea. What we concluded by that time (pure >> theory ;-) was that the metaclass is sufficient for coloring memory >> resources (i.e. usage of memory, as in your case). >> Your "domain" members can be a (sub)set of instances of Metaclass, >> your "domain" can be a clone of Metaclass. Think that today's >> Metaclass belongs to the builtin *system* domain and that every domain >> user (or application instance, as you mentioned in your posting) gets >> a clone of Metaclass (and consequently the respective instances of >> Metaclass), on demand. >> So finding the total memory usage for one of your domains is pretty >> easy and the pointer which does it is the *class* pointer (no change >> to the VM), like (roughly) in >> domain "clone of Metaclass" allInstances inject: 0 into: [:accum >> :aDomainClass | >> aDomainClass allInstances ... + accum] >> Since I planned for a short response, I stop here (many more >> implications can be discussed, of course). >> I'm sure that coloring of object memory is something which is easy to >> implement and to maintain. > > Doesn't this implementation limit you to having all objects of one class > bound to the same domain? Hhm, no: domain membership is an implication of organization (IMO). Depends on how (besides: where) you implement "make instances of *this*class* belong to domain X under condition Y". Today's system runs with X := #system, Y := true, the default. In a kiss approach, classes "know" whether their instances are shared a) by everybody in the system (today's default), b) per application (for services and the like), c) per application *instance* (for clients and the like), d) per process (regardless of other organizational aspects), e) per user (regardless of other organizational aspects), and so on. Of course, kiss implies that all instances of the same class belong to the same domain but, I hope it can be seen that it's a matter of what is decided by X and Y in the scheme above. > How would you have two domains sharing the same implementation? That's the easy part: clones of classes share their method dictionary (in form of a pointer, not as a copy). Only the class pointer of per domain created instances is changed, nothing more and nothing else. A very good ROI, that is :) > For example, an "alicesEmail" domain and a "bobsEmail" domain would both > share the classes implementing email stuff. Sure. /Klaus > Michael. > > > |
In reply to this post by Andreas.Raab
But they will help with the "untrusted foreign code" bit, not so?
frank "Andreas Raab" <[hidden email]> wrote: > None of the cited references will solve the original problem(s). They > are related but they won't solve it. Managing memory limits alone would > require *major* modifications of the VM. > > Cheers, > - Andreas > > Frank Shearar wrote: > > "Michael van der Gulik" <[hidden email]> wrote: > > > >> Hi Howard. > >> > >> I forgot to mention that the reason I'm doing this is to allow > >> foreign code to run in the same image as trusted code. Untrusted code > >> must be carefully managed - it must not be able to consume large amounts > >> of memory, CPU or disk space to which it is not entitled. Untrusted code > >> / objects must not prevent trusted code from operating well. > > > > Have you looked at the (Tweak) Islands [1] work? Lex Spoon also did work > > with the same name [2], IIRC. And there's the Squeak-E [3] stuff too. > > > > [1] http://tweak.impara.de/TECHNOLOGY/Whitepapers/Islands/ > > [2] http://minnow.cc.gatech.edu/squeak/2074 > > [3] http://www.erights.org/history/squeak-e.html > > > > frank > > > > > > > > > |
In reply to this post by Michael van der Gulik
Imagine that a magic fairy comes and creates a system that works exactly
as you prescribe. Now, how will you or your users guess that 64MB RAM / 100MB disk / 100MB traffic/day is appropriate for one application, while others use different figures? It's like Windows asking me whether I want to use extended memory or a fat file system during installation. How the hell should I know? And why wouldn't some domains want to restrict KB traffic/second instead? Or the number of open connections? Or how much second-level cache is devoted to Processor 1 vs Processor 2? Or....etc. Alright, now imagine that the same magic fairy (let's call it a "Wizard") comes and gives you a dialog box that's going to make it easy to configure these possibilities, or better yet, picks a magic right answer for each. What problem have you solved? Have you now made your computer safe against viruses, malware, or poorly designed software? Have you made the applications in these domains now easy to operate, fast, and robust. (Answer: no.) Now consider two applications in two different domains communicating with each other.... My point is that I believe that sandboxing applications into resource-starved ghettos may be technically fun to program and you may learn a lot of neat stuff. But when you look at the whole end-to-end problem, it isn't going to produce the result of "allowing untrusted foreign code to run in the same image as trusted code." Java has already demonstrated this to be the case. Here's some hand-wavy heuristics: - Don't ask the user to configure stuff that they don't know about. (Assume administrators don't know about pretty much the universal set.) - Don't try to make low-level infrastructure do something that it can't do completely or correctly without application knowledge, such that the application ends up having to do it itself anyway. - If you want to aggregate stuff (e.g., for ease of administration), then create a basic mechanism that handles the fine grain (e.g., capabilities) and which can be fractally applied at different scales. Creating a the aggregated thing first (e.g., access control lists) tends to break down when you run into the real-world special cases, and then you end up with two half-broken mechanisms. - Don't spend a lot of effort implementing a feature that doesn't actually deliver a result that the user can see. (E.g., Putting a stoplight up on Bagdad's airport road may make it a little safer with respect to traffic accidents, but that's not actually the major safety problem.) Michael van der Gulik wrote: > Hi Howard. > > I forgot to mention that the reason I'm doing this is to allow > untrusted foreign code to run in the same image as trusted code. > Untrusted code must be carefully managed - it must not be able to > consume large amounts of memory, CPU or disk space to which it is not > entitled. Untrusted code / objects must not prevent trusted code from > operating well. > > Oh, and Squeak is full of security holes, but there will be ways to > patch them I'm sure. > > Howard Stearns wrote: >> It seems to me that any attempt to put arbitrary, coarse-grained >> restrictions on computer resources -- as opposed to problem-domain or >> user-domain behaviors, is just doing a lot of work to shift the >> problem, without actually solving it. How will the programmer set >> these limits? How will the poor user or "administrator" manage them? > > The programmer, user or administrator will manage them "manually"; > coarse-grained restrictions are course-grained, meaning that there > aren't many of them. > > Example: You find a foreign set of objects and classes in a domain > called "SqueakSeti@home" and decide to grant that domain access to you > local computer: it is granted low-priority CPU only, memory is bound > to 64MB, this domain may use 100MB of disk space and no more than > 100MB of network bandwidth per day. > > Meanwhile, another domain called "ImportantBusinessStuff" can use > high-priority CPU, no more than 256MB memory (i.e. the size of > physical memory), etc. > > This all makes a lot more sense when working with a public distributed > system where code and objects float from computer to computer. In this > case, a group of distributed objects are all bound to a "Domain", and > individual computers decide how much privilege that Domain has on each > computer. > >> Now, there are two issues: >> >> 1. "But my customer wants to do it the broken way!" Fair enough. You >> might consider, though, whether or not this approach fits with the >> real advantages (to the customer, not to you) of using Squeak. If you >> turn the application into something that works just like Java except >> that it's in Squeak, you can bet the contract that in the end, the >> customer will decide to re-implement it in Java (for social reasons, >> such as covering their butts in deploying, hiring people to work on >> it, etc.) Doing a broken, Java-like thing "better than Java" is just >> a special case. > > Umm... I don't get your point. This is for my own project. No > customers, no Java. > >> 2. "OK, How SHOULD I do it?" Here you have to look at the actual >> problems you're trying to avoid. For example, suppose you want to >> keep mobile programs from writing files on a user's computer. The >> answer is to arrange to only present a 'file open' interface that >> prompts the user for the location. > > ...like a capability. > >> This is better than draconianly prohibiting all 'file open' requests, >> because it still allows arbitrary programs to do useful work as long >> as the user is made clearly aware of what the program is doing. (In >> an imperfect-world nod to resource management, that user dialog might >> specify the max size of the file.) Now suppose you want to have the >> system manage (e.g., remember) the fact that such-and-such an object >> has requested a file-open, and that the user has granted it for given >> name/size. The capabilities community (see e-rights) has a lot of >> literature on how to do this securely. But as I see it, the >> capabilities stuff is just an implementation detail for the >> higher-level issue of choosing what (or where) to manage >> problem-specific behaviors. (See end-to-end argument.) > > That's what I intend to use domains for... they're a higher-level > "management object" to manage problem-specific behaviours. > > A reference to a File object would be a capability. The "Domain" > aggregates objects together so that permissions can be granted in > bulk. Objects that need access to that File object (which is a > capability) would ask their Domain instance for it. If the Domain > instance does not have it, access is obviously not possible. > > Of course the implementation details might end up different, but the > idea is that the local system grants Domains the rights to use system > resources. > > Michael. > > -- Howard Stearns University of Wisconsin - Madison Division of Information Technology mailto:[hidden email] jabber:[hidden email] voice:+1-608-262-3724 |
On Tue, 08 Aug 2006 16:53:46 +0200, Howard Stearns wrote:
> Imagine that a magic fairy comes and creates a system that works exactly > as you prescribe. > Now, how will you or your users guess that 64MB RAM / 100MB disk / > 100MB traffic/day is appropriate for one application, while others use > different figures? Would you say that the above is any different from a single computer system with exactly the capacity limits you gave? If so, mind to explain? BTW: in ancient (computer age) times we had to implement contingency systems (sometimes mistakenly called accounting systems) because there was only one computer for 1,000's of users, like for example here: - http://www.unibw.de/ on a B7800/B7900, the successor of the B5000. /Klaus |
Klaus D. Witzel wrote:
> On Tue, 08 Aug 2006 16:53:46 +0200, Howard Stearns wrote: > >> Imagine that a magic fairy comes and creates a system that works >> exactly as you prescribe. >> Now, how will you or your users guess that 64MB RAM / 100MB disk >> / 100MB traffic/day is appropriate for one application, while others >> use different figures? > > Would you say that the above is any different from a single computer > system with exactly the capacity limits you gave? If so, mind to explain? I agree that they're the same. And I would never order a computer saying that it must not have more than 64MB, 100MB disk, nor allow more than 100MB traffic/day. Nor would I attempt to implement "safety" that way on a single or partitioned computer. > > BTW: in ancient (computer age) times we had to implement contingency > systems (sometimes mistakenly called accounting systems) because there > was only one computer for 1,000's of users, like for example here: Indeed, and there is good reason that computers are no longer implemented that way. While I certainly don't feel that "no body does it that way" is a valid argument that something should not be done, I do feel it is instructive to note that, while there are many projects to build distributed systems that allow resources to be shared among computers, the opposite does not appear to be true (e.g., hardware systems that segregate or cap resources). It's rather suspect that the original project spec of how to limit resource use on a single processor should come out of a problem in distributed computing, which by definition is an attempt to gain overall system power and access by sharing resources between computers. There's a good heuristic: Don't create a feature requirement that contravenes the overriding project goal! > > - http://www.unibw.de/ > > on a B7800/B7900, the successor of the B5000. > > /Klaus > Thanks for making my point! -- Howard Stearns University of Wisconsin - Madison Division of Information Technology mailto:[hidden email] jabber:[hidden email] voice:+1-608-262-3724 |
Howard Stearns wrote:
> Klaus D. Witzel wrote: >> On Tue, 08 Aug 2006 16:53:46 +0200, Howard Stearns wrote: >> >>> Imagine that a magic fairy comes and creates a system that works >>> exactly as you prescribe. >>> Now, how will you or your users guess that 64MB RAM / 100MB >>> disk / 100MB traffic/day is appropriate for one application, while >>> others use different figures? >> >> Would you say that the above is any different from a single computer >> system with exactly the capacity limits you gave? If so, mind to >> explain? > > I agree that they're the same. And I would never order a computer > saying that it must not have more than 64MB, 100MB disk, nor allow > more than 100MB traffic/day. Nor would I attempt to implement "safety" > that way on a single or partitioned computer. > I believe) resource, you would like to be sure that customers will not draw resources from each other, and you will be able to comply to your Service Level Agreement with them and you would like to gain additional profit from differentiating of services. Is not this a common business practice? regards, Danil |
In reply to this post by Frank Shearar
Frank Shearar wrote:
> But they will help with the "untrusted foreign code" bit, not so? They will help in understanding the problem, yes. They are not working solutions - all of them would require some major work before one could claim that. Cheers, - Andreas > > frank > > "Andreas Raab" <[hidden email]> wrote: > >> None of the cited references will solve the original problem(s). They >> are related but they won't solve it. Managing memory limits alone would >> require *major* modifications of the VM. >> >> Cheers, >> - Andreas >> >> Frank Shearar wrote: >>> "Michael van der Gulik" <[hidden email]> wrote: >>> >>>> Hi Howard. >>>> >>>> I forgot to mention that the reason I'm doing this is to allow > untrusted >>>> foreign code to run in the same image as trusted code. Untrusted code >>>> must be carefully managed - it must not be able to consume large > amounts >>>> of memory, CPU or disk space to which it is not entitled. Untrusted > code >>>> / objects must not prevent trusted code from operating well. >>> Have you looked at the (Tweak) Islands [1] work? Lex Spoon also did work >>> with the same name [2], IIRC. And there's the Squeak-E [3] stuff too. >>> >>> [1] http://tweak.impara.de/TECHNOLOGY/Whitepapers/Islands/ >>> [2] http://minnow.cc.gatech.edu/squeak/2074 >>> [3] http://www.erights.org/history/squeak-e.html >>> >>> frank >>> >>> >>> >> >> > > > |
Free forum by Nabble | Edit this page |