From: Samuele P. <pe...@in...> - 2000-12-31 02:34:05
|
Hi. [sorry for the length of this] [me] > I will study the patch. > I see some potential problems but maybe I'm interpreting wrong the java2 > security doc. The patch idea is quite nice (I had not thought about such a possibility) but unfortunately there are some problems. First a general remark: Our java2 security support should be robust in every situation (codesources/protection domains setup), even if probably it will be mostly used for applets running within the plug-in, or at least we should have a short formulation of what people should not do. The actual codebase meets such a requirement: one can allow (compiled) jython code to use exec at the cost of granting createClassLoader permission, this implies that both the code and the exec-ed jython fragments must be fully trusted. In Sun doc it is stated that the use of doPrivileged should be very limited and also the amount of code executed inside such a privileged context should be limited too. The patch does something very different using doPrivileged for every "jython function call" and having the privileged region encompass the whole "call". a) A bad news about the patch is the perfomance cost of it: On my machine with the patch in place the pystones number (using 50000 iters ) goes down from ~4950 to ~2900. I do know very little about how to read pystone results: but this seems to me a "big" performance cost that is paid globally. [In any case I continue to list the "problems" of the patch, maybe there is a solution that I do not see, and I think some remarks are of more general interest] b) Sun says nothing about using doPrivileged in the context of recursive calls: I have no idea if there are problems with that too? c) A final version of the patch should clearly avoid that code external to jython runtime could exploit the created classloaders, e.g. a method like BytecodeLoader.makeClass should then become package protected etc. d) With the patch as it is the (dynamically created) classes- loaded through the BytecodeLoaders - are still put in the protection domain of jython runtime: once the access to BytecodeLoader functionality is sealed from outside they will/can be just the adapters and proxies classes and PyCode-derived classes. I don't see a way to exploit the fact that these will be in jython runtime prot-dom. But I'm not sure that such a possibilty does not exist. e) Given that our support should work in a general setup: - The patch solves the problem of reducing the permissions back to the ones of the context of the code that used exec. So if the created code is called from a context with more permissions it cannot exploit any of these. That was the issue showed by my example. - On the other hand if the exec-created code is called from a context with less permissions, given doPrivileged definition, it will anyway run with the permissions of its creation context. In general java2 security design avoids this kind of situation (but gives through doPrivileged a way to obtain this) because then the user during coding should explicitly think about the possible security holes that this behaviour opens. I think that what we need to achieve is the following: that exec-created (and the other dynamically created code) should run under the intersection of the permissions of the creation and execution contexts. One then can use doPrivileged explicitly to modify this. But reading java2 security doc it seems that: - There is no way to take 2 AccessControlContext and build a third that correspond to the intersection of them. - There is no explicit/elegant way to extract the permissions in place given a/the current AccessControlContext. Now I will try to explain an alternative design for a patch. I do not like it very much, because it is not very elegant. I hope that we can save one the of other approaches or find a derivation of this or combination that do the job in a reasonable way. This is just a sketch. Jython runtime should keep a global list PermCands of permissions (e.g. thro ugh an HashSet). There will be an api to add permissions to the list. The init-functions (for proxies, etc.) that now take a classloader should then take the proxy/... class too and jython should automatically put all the permissions of the prot-dom of that class in the list. [Cheating at this level will bring no gain] The actual functionality of BytecodeLoader makeLoader, constructor and makeClass/Code methods should be completily isolated inside jython runtime: an idea for this is to have * a SingletonSealedLoader class with just a package protected constructor and a method to retrieve the unique class that is directly loaded through it: the constructor will take the makeClass arguments and an AccessControlContext acc. * a static package protected function that calls AccessController.getContext and then invoke through doPrivileged SingletonSealedLoader ctr with the obtained current protection context. The constructor logic will do the following: - if there is no security manager in place just define the class. - if there is a security manager in place: define the class inside a protection domain, the permissions to grant will be computed this way: Only the permissions from the global set PermsCands for which acc.checkPermission do not throw an exception will be granted. Clearly all this checks have a performance cost, especially when the negative result exc is thrown. The code can test wheter already AllPermission is ok to gain some speed in this case. The assumption is that the set will not be that big and in any case the cost is local to the dynamic creation of code. And zero if there is no security manager in place. So the permissions granted are all actually in place for the code that issued the creation request. Review of all this is welcome regards, Samuele Pedroni. PS: * Clearly these tentatives of enabling exec for untrusted code will work only if jython is installed locally and will receive enough permissions. * A definitive support for java2 security should probably also do the following: both for loading of percompiled ($py.class) jython code and java classes from sys.path loading the jython runtime should assign a correct protection domain to the loaded classes through the SecureClassLoader.defineClass(...,CodeSource csrc) api. |