Discussion:
Security issue with generated classes
(too old to reply)
Craig L Russell
2008-07-20 00:40:51 UTC
Permalink
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:***@sun.com
P.S. A good JDO? O, Gasp!
Craig L Russell
2008-07-27 22:09:48 UTC
Permalink
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!!!
Post by Craig L Russell
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
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:***@sun.com
P.S. A good JDO? O, Gasp!
Craig L Russell
2008-07-27 22:34:44 UTC
Permalink
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
Post by Craig L Russell
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] 1)
test
(org
One or more instances could not be made persistent
[java] at
org
.datanucleus
.jdo
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
108)
[java] at
148)
[java] at
org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:123)
[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
1091)
[java] at
org
.datanucleus
.jdo
666)
[java] at
org
.datanucleus
.jdo
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
108)
[java] at
148)
[java] at
org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:123)
[java] java.security.AccessControlException: access denied
(javax.jdo.spi.JDOPermission setStateManager)
[java] at
java
.security
.AccessControlContext.checkPermission(AccessControlContext.java:264)
[java] at
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
1091)
[java] at
org
.datanucleus
.jdo
666)
[java] at
org
.datanucleus
.jdo
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
108)
[java] at
148)
[java] at
org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:123)
[java] FAILURES!!!
Post by Craig L Russell
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
P.S. A good JDO? O, Gasp!
Craig L Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
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:***@sun.com
P.S. A good JDO? O, Gasp!
Andy Jefferson
2008-07-28 06:17:50 UTC
Permalink
Hi Craig,
Post by Craig L Russell
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)
Craig L Russell
2008-07-28 20:18:49 UTC
Permalink
Hi Andy,
Post by Andy Jefferson
Hi Craig,
Post by Craig L Russell
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.
Post by Andy Jefferson
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
Post by Andy Jefferson
--
Andy (DataNucleus - http://www.datanucleus.org)
Craig L Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:***@sun.com
P.S. A good JDO? O, Gasp!
Craig L Russell
2008-07-28 22:48:12 UTC
Permalink
Post by Craig L Russell
Hi Andy,
Post by Andy Jefferson
Hi Craig,
Post by Craig L Russell
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
Andy Jefferson
2008-07-31 17:05:21 UTC
Permalink
Hi Craig,
Post by Craig L Russell
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)
Continue reading on narkive:
Loading...