You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-dev@db.apache.org by Craig L Russell <Cr...@Sun.COM> on 2008/07/20 02:40:51 UTC

Security issue with generated classes

We have an issue with the JDO security model and generated classes.

The standard Java SecurityManager does not provide for dynamic  
addition of class loaders to the protection domains. So generated  
classes cannot participate in the security model.

This implies to me that we cannot use the standard JDO security model  
and must so something else for generated classes.

I'm open to ideas. My focus will be on the replaceSecurityManager  
permission. I'd like to hear ideas from others.

Craig

Craig L Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Re: Security issue with generated classes

Posted by Andy Jefferson <an...@datanucleus.org>.
Hi Craig,

> Here's a patch for JDOPersistenceManagerFactory that works for me; the
> call might better be put somewhere else...

> And the RDO security patch needed just a little more help. The
> implementation of QueryUtils.getPublicPutMethodForResultClass fails in
> security environments. So I reimplemented it with doPrivileged and
> it's ok.

These were added to DataNucleus SVN the other day. Thx!


-- 
Andy  (DataNucleus - http://www.datanucleus.org)

Re: Security issue with generated classes

Posted by Craig L Russell <Cr...@Sun.COM>.
On Jul 28, 2008, at 1:18 PM, Craig L Russell wrote:

> Hi Andy,
>
> On Jul 27, 2008, at 11:17 PM, Andy Jefferson wrote:
>
>> Hi Craig,
>>
>>> I looked at the datanucleus implementation and found that I'm  
>>> totally
>>> not qualified to propose a patch. I found the code that needs to be
>>> changed in org/datanucleus/enhancer/bcel/method/
>>> JdoReplaceStateManager.java and org/datanucleus/enhancer/asm/method/
>>> JdoReplaceStateManager.java but that's as far as I could get without
>>> knowing asm, bcel, and byte-codes.
>>
>> The ASM-based enhancer is now updated to match the current spec.
>
> I'll take a look and let you know what I find.

The modified enhanced jdoSetStateManager now works great!

One "last thing". In order to avoid the security manager check in the  
enhanced code, sometime during initialization of the  
PersistenceManagerFactory you need to register the StateManager class.

Here's a patch for JDOPersistenceManagerFactory that works for me; the  
call might better be put somewhere else...

I also had to add another couple of permissions to the security policy  
(after getting through the StateManager security issue). These are now  
checked in.

And the RDO security patch needed just a little more help. The  
implementation of QueryUtils.getPublicPutMethodForResultClass fails in  
security environments. So I reimplemented it with doPrivileged and  
it's ok.

Now the entire TCK runs with security enabled (modulo the existing http://issues.apache.org/jira/browse/JDO-573 
  that still fails...)

Craig


Re: Security issue with generated classes

Posted by Craig L Russell <Cr...@Sun.COM>.
Hi Andy,

On Jul 27, 2008, at 11:17 PM, Andy Jefferson wrote:

> Hi Craig,
>
>> I looked at the datanucleus implementation and found that I'm totally
>> not qualified to propose a patch. I found the code that needs to be
>> changed in org/datanucleus/enhancer/bcel/method/
>> JdoReplaceStateManager.java and org/datanucleus/enhancer/asm/method/
>> JdoReplaceStateManager.java but that's as far as I could get without
>> knowing asm, bcel, and byte-codes.
>
> The ASM-based enhancer is now updated to match the current spec.

I'll take a look and let you know what I find.

>
>
> The BCEL-based enhancer is not updated since strategic direction is  
> using ASM
> (and the TCK uses ASM). There's a DataNucleus JIRA and a TODO for
> implementing using BCEL if anyone has the time/motivation.
>
> The original code for that method was written for JDO 1.0.0 and  
> never changed
> since seemingly.

When I encountered this issue it sounded familiar. Apparently, we  
figured out back in 1.0.1 days that calling the SecurityManager  
directly from enhanced classes would be problematic. We were right. ;-)

Craig
>
>
>
> -- 
> Andy  (DataNucleus - http://www.datanucleus.org)

Craig L Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Re: Security issue with generated classes

Posted by Andy Jefferson <an...@datanucleus.org>.
Hi Craig,

> I looked at the datanucleus implementation and found that I'm totally
> not qualified to propose a patch. I found the code that needs to be
> changed in org/datanucleus/enhancer/bcel/method/
> JdoReplaceStateManager.java and org/datanucleus/enhancer/asm/method/
> JdoReplaceStateManager.java but that's as far as I could get without
> knowing asm, bcel, and byte-codes.

The ASM-based enhancer is now updated to match the current spec.

The BCEL-based enhancer is not updated since strategic direction is using ASM  
(and the TCK uses ASM). There's a DataNucleus JIRA and a TODO for  
implementing using BCEL if anyone has the time/motivation.

The original code for that method was written for JDO 1.0.0 and never changed  
since seemingly.


-- 
Andy  (DataNucleus - http://www.datanucleus.org)

Re: Security issue with generated classes

Posted by Craig L Russell <Cr...@Sun.COM>.
I looked at the datanucleus implementation and found that I'm totally  
not qualified to propose a patch. I found the code that needs to be  
changed in org/datanucleus/enhancer/bcel/method/ 
JdoReplaceStateManager.java and org/datanucleus/enhancer/asm/method/ 
JdoReplaceStateManager.java but that's as far as I could get without  
knowing asm, bcel, and byte-codes.

I think the spec is clear on what the generated code should do.
<spec>C. If the current jdoStateManager field is null, then a security  
check is performed] by
calling JDOImplHelper.checkAuthorizedStateManager [with the StateManager
parameter sm passed as the parameter to the check.] Thus, only  
StateManager instances
in code bases authorized for JDOPermission(“setStateManager”) are  
allowed to
set the StateManager. [If the security check succeeds, the  
jdoStateManager field is
set to the value of the parameter sm, and the jdoFlags field is set to  
LOAD_REQUIRED
to indicate that mediation is required.]
</spec>

Craig

On Jul 27, 2008, at 3:09 PM, Craig L Russell wrote:

> I looked at this issue in some more detail and found that the root  
> cause was fixed some time ago (before 1.0.1).
>
> The persistence-capable classes should not call SecurityManager  
> directly, but instead call the static method  
> JDOImplHelper.checkAuthorizedStateManager with the StateManager as  
> the parameter. This first checks to see if the StateManager class  
> has been authorized (by the implementation earlier calling  
> registerAuthorizedStateManagerClass in a doPrivileged block). Using  
> this technique, the persistence-capable classes themselves do not  
> have to be mentioned in the security.permissions file.
>
> In the stack trace below I don't see the call to  
> JDOImplHelper.checkAuthorizedStateManager.
>
> Craig
>
>    [java] There was 1 error:
>    [java] 1)  
> test 
> (org 
> .apache.jdo.tck.mapping.CompletenessTest)javax.jdo.JDOUserException:  
> One or more instances could not be made persistent
>    [java] 	at  
> org 
> .datanucleus 
> .jdo 
> .JDOPersistenceManager.makePersistentAll(JDOPersistenceManager.java: 
> 734)
>    [java] 	at  
> org 
> .apache 
> .jdo.tck.mapping.CompletenessTest.localSetUp(CompletenessTest.java:70)
>    [java] 	at org.apache.jdo.tck.JDO_Test.setUp(JDO_Test.java:242)
>    [java] 	at org.apache.jdo.tck.JDO_Test.runBare(JDO_Test.java:258)
>    [java] 	at  
> org.apache.jdo.tck.util.BatchTestRunner.doRun(BatchTestRunner.java: 
> 108)
>    [java] 	at  
> org.apache.jdo.tck.util.BatchTestRunner.start(BatchTestRunner.java: 
> 148)
>    [java] 	at  
> org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:123)
>    [java] NestedThrowablesStackTrace:
>    [java] javax.jdo.JDOFatalUserException: Insufficent access  
> granted to org.datanucleus.*
>    [java] 	at  
> org 
> .datanucleus 
> .state 
> .JDOStateManagerImpl.replaceStateManager(JDOStateManagerImpl.java:961)
>    [java] 	at  
> org 
> .datanucleus 
> .state 
> .JDOStateManagerImpl 
> .initialiseForPersistentNew(JDOStateManagerImpl.java:396)
>    [java] 	at  
> org 
> .datanucleus 
> .state 
> .StateManagerFactory 
> .newStateManagerForPersistentNew(StateManagerFactory.java:153)
>    [java] 	at  
> org 
> .datanucleus 
> .ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1245)
>    [java] 	at  
> org 
> .datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java: 
> 1091)
>    [java] 	at  
> org 
> .datanucleus 
> .jdo 
> .JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java: 
> 666)
>    [java] 	at  
> org 
> .datanucleus 
> .jdo 
> .JDOPersistenceManager.makePersistentAll(JDOPersistenceManager.java: 
> 720)
>    [java] 	at  
> org 
> .apache 
> .jdo.tck.mapping.CompletenessTest.localSetUp(CompletenessTest.java:70)
>    [java] 	at org.apache.jdo.tck.JDO_Test.setUp(JDO_Test.java:242)
>    [java] 	at org.apache.jdo.tck.JDO_Test.runBare(JDO_Test.java:258)
>    [java] 	at  
> org.apache.jdo.tck.util.BatchTestRunner.doRun(BatchTestRunner.java: 
> 108)
>    [java] 	at  
> org.apache.jdo.tck.util.BatchTestRunner.start(BatchTestRunner.java: 
> 148)
>    [java] 	at  
> org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:123)
>    [java] NestedThrowablesStackTrace:
>    [java] java.security.AccessControlException: access denied  
> (javax.jdo.spi.JDOPermission setStateManager)
>    [java] 	at  
> java 
> .security 
> .AccessControlContext.checkPermission(AccessControlContext.java:264)
>    [java] 	at  
> java.security.AccessController.checkPermission(AccessController.java: 
> 427)
>    [java] 	at  
> java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
>    [java] 	at  
> org 
> .apache 
> .jdo 
> .tck 
> .pc 
> .companyAnnotatedPI.PIDSCompanyImpl.jdoReplaceStateManager(Unknown  
> Source)
>    [java] 	at org.datanucleus.state.JDOStateManagerImpl 
> $1.run(JDOStateManagerImpl.java:954)
>    [java] 	at java.security.AccessController.doPrivileged(Native  
> Method)
>    [java] 	at  
> org 
> .datanucleus 
> .state 
> .JDOStateManagerImpl.replaceStateManager(JDOStateManagerImpl.java:950)
>    [java] 	at  
> org 
> .datanucleus 
> .state 
> .JDOStateManagerImpl 
> .initialiseForPersistentNew(JDOStateManagerImpl.java:396)
>    [java] 	at  
> org 
> .datanucleus 
> .state 
> .StateManagerFactory 
> .newStateManagerForPersistentNew(StateManagerFactory.java:153)
>    [java] 	at  
> org 
> .datanucleus 
> .ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1245)
>    [java] 	at  
> org 
> .datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java: 
> 1091)
>    [java] 	at  
> org 
> .datanucleus 
> .jdo 
> .JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java: 
> 666)
>    [java] 	at  
> org 
> .datanucleus 
> .jdo 
> .JDOPersistenceManager.makePersistentAll(JDOPersistenceManager.java: 
> 720)
>    [java] 	at  
> org 
> .apache 
> .jdo.tck.mapping.CompletenessTest.localSetUp(CompletenessTest.java:70)
>    [java] 	at org.apache.jdo.tck.JDO_Test.setUp(JDO_Test.java:242)
>    [java] 	at org.apache.jdo.tck.JDO_Test.runBare(JDO_Test.java:258)
>    [java] 	at  
> org.apache.jdo.tck.util.BatchTestRunner.doRun(BatchTestRunner.java: 
> 108)
>    [java] 	at  
> org.apache.jdo.tck.util.BatchTestRunner.start(BatchTestRunner.java: 
> 148)
>    [java] 	at  
> org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:123)
>    [java] FAILURES!!!
>
>
>
> On Jul 19, 2008, at 5:40 PM, Craig L Russell wrote:
>
>> We have an issue with the JDO security model and generated classes.
>>
>> The standard Java SecurityManager does not provide for dynamic  
>> addition of class loaders to the protection domains. So generated  
>> classes cannot participate in the security model.
>>
>> This implies to me that we cannot use the standard JDO security  
>> model and must so something else for generated classes.
>>
>> I'm open to ideas. My focus will be on the replaceSecurityManager  
>> permission. I'd like to hear ideas from others.
>>
>> Craig
>>
>> Craig L Russell
>> Architect, Sun Java Enterprise System http://java.sun.com/products/ 
>> jdo
>> 408 276-5638 mailto:Craig.Russell@sun.com
>> P.S. A good JDO? O, Gasp!
>>
>
> Craig L Russell
> Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
> 408 276-5638 mailto:Craig.Russell@sun.com
> P.S. A good JDO? O, Gasp!
>

Craig L Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Re: Security issue with generated classes

Posted by Craig L Russell <Cr...@Sun.COM>.
I looked at this issue in some more detail and found that the root  
cause was fixed some time ago (before 1.0.1).

The persistence-capable classes should not call SecurityManager  
directly, but instead call the static method  
JDOImplHelper.checkAuthorizedStateManager with the StateManager as the  
parameter. This first checks to see if the StateManager class has been  
authorized (by the implementation earlier calling  
registerAuthorizedStateManagerClass in a doPrivileged block). Using  
this technique, the persistence-capable classes themselves do not have  
to be mentioned in the security.permissions file.

In the stack trace below I don't see the call to  
JDOImplHelper.checkAuthorizedStateManager.

Craig

     [java] There was 1 error:
     [java] 1)  
test 
(org 
.apache.jdo.tck.mapping.CompletenessTest)javax.jdo.JDOUserException:  
One or more instances could not be made persistent
     [java] 	at  
org 
.datanucleus 
.jdo 
.JDOPersistenceManager.makePersistentAll(JDOPersistenceManager.java:734)
     [java] 	at  
org 
.apache 
.jdo.tck.mapping.CompletenessTest.localSetUp(CompletenessTest.java:70)
     [java] 	at org.apache.jdo.tck.JDO_Test.setUp(JDO_Test.java:242)
     [java] 	at org.apache.jdo.tck.JDO_Test.runBare(JDO_Test.java:258)
     [java] 	at  
org.apache.jdo.tck.util.BatchTestRunner.doRun(BatchTestRunner.java:108)
     [java] 	at  
org.apache.jdo.tck.util.BatchTestRunner.start(BatchTestRunner.java:148)
     [java] 	at  
org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:123)
     [java] NestedThrowablesStackTrace:
     [java] javax.jdo.JDOFatalUserException: Insufficent access  
granted to org.datanucleus.*
     [java] 	at  
org 
.datanucleus 
.state 
.JDOStateManagerImpl.replaceStateManager(JDOStateManagerImpl.java:961)
     [java] 	at  
org 
.datanucleus 
.state 
.JDOStateManagerImpl 
.initialiseForPersistentNew(JDOStateManagerImpl.java:396)
     [java] 	at  
org 
.datanucleus 
.state 
.StateManagerFactory 
.newStateManagerForPersistentNew(StateManagerFactory.java:153)
     [java] 	at  
org 
.datanucleus 
.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1245)
     [java] 	at  
org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java: 
1091)
     [java] 	at  
org 
.datanucleus 
.jdo 
.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:666)
     [java] 	at  
org 
.datanucleus 
.jdo 
.JDOPersistenceManager.makePersistentAll(JDOPersistenceManager.java:720)
     [java] 	at  
org 
.apache 
.jdo.tck.mapping.CompletenessTest.localSetUp(CompletenessTest.java:70)
     [java] 	at org.apache.jdo.tck.JDO_Test.setUp(JDO_Test.java:242)
     [java] 	at org.apache.jdo.tck.JDO_Test.runBare(JDO_Test.java:258)
     [java] 	at  
org.apache.jdo.tck.util.BatchTestRunner.doRun(BatchTestRunner.java:108)
     [java] 	at  
org.apache.jdo.tck.util.BatchTestRunner.start(BatchTestRunner.java:148)
     [java] 	at  
org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:123)
     [java] NestedThrowablesStackTrace:
     [java] java.security.AccessControlException: access denied  
(javax.jdo.spi.JDOPermission setStateManager)
     [java] 	at  
java 
.security 
.AccessControlContext.checkPermission(AccessControlContext.java:264)
     [java] 	at  
java.security.AccessController.checkPermission(AccessController.java: 
427)
     [java] 	at  
java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
     [java] 	at  
org 
.apache 
.jdo 
.tck 
.pc.companyAnnotatedPI.PIDSCompanyImpl.jdoReplaceStateManager(Unknown  
Source)
     [java] 	at org.datanucleus.state.JDOStateManagerImpl 
$1.run(JDOStateManagerImpl.java:954)
     [java] 	at java.security.AccessController.doPrivileged(Native  
Method)
     [java] 	at  
org 
.datanucleus 
.state 
.JDOStateManagerImpl.replaceStateManager(JDOStateManagerImpl.java:950)
     [java] 	at  
org 
.datanucleus 
.state 
.JDOStateManagerImpl 
.initialiseForPersistentNew(JDOStateManagerImpl.java:396)
     [java] 	at  
org 
.datanucleus 
.state 
.StateManagerFactory 
.newStateManagerForPersistentNew(StateManagerFactory.java:153)
     [java] 	at  
org 
.datanucleus 
.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1245)
     [java] 	at  
org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java: 
1091)
     [java] 	at  
org 
.datanucleus 
.jdo 
.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:666)
     [java] 	at  
org 
.datanucleus 
.jdo 
.JDOPersistenceManager.makePersistentAll(JDOPersistenceManager.java:720)
     [java] 	at  
org 
.apache 
.jdo.tck.mapping.CompletenessTest.localSetUp(CompletenessTest.java:70)
     [java] 	at org.apache.jdo.tck.JDO_Test.setUp(JDO_Test.java:242)
     [java] 	at org.apache.jdo.tck.JDO_Test.runBare(JDO_Test.java:258)
     [java] 	at  
org.apache.jdo.tck.util.BatchTestRunner.doRun(BatchTestRunner.java:108)
     [java] 	at  
org.apache.jdo.tck.util.BatchTestRunner.start(BatchTestRunner.java:148)
     [java] 	at  
org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:123)
     [java] FAILURES!!!



On Jul 19, 2008, at 5:40 PM, Craig L Russell wrote:

> We have an issue with the JDO security model and generated classes.
>
> The standard Java SecurityManager does not provide for dynamic  
> addition of class loaders to the protection domains. So generated  
> classes cannot participate in the security model.
>
> This implies to me that we cannot use the standard JDO security  
> model and must so something else for generated classes.
>
> I'm open to ideas. My focus will be on the replaceSecurityManager  
> permission. I'd like to hear ideas from others.
>
> Craig
>
> Craig L Russell
> Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
> 408 276-5638 mailto:Craig.Russell@sun.com
> P.S. A good JDO? O, Gasp!
>

Craig L Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!