db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Song Guo Qiang (JIRA)" <j...@apache.org>
Subject [jira] Issue Comment Edited: (DERBY-3363) AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.net.www.protocol.c)
Date Tue, 05 Feb 2008 09:17:07 GMT

    [ https://issues.apache.org/jira/browse/DERBY-3363?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12565667#action_12565667
] 

superq edited comment on DERBY-3363 at 2/5/08 1:15 AM:
---------------------------------------------------------------

This test case (see attachment) helps to reveal the problems when Derby does not assign proper
security domain to generated classes.

This folder contains a Eclipse project so you can open it and run the test case in the current
folder.

Then you should see the following exception stack trace (using JDK 1.5.0_11): 

java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.net.www.protocol.c)
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
	at java.security.AccessController.checkPermission(AccessController.java:427)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
	at ElxSecurityManager.checkPermission(ElxSecurityManager.java:18)
	at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1512)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
	at java.net.URL.getURLStreamHandler(URL.java:1141)
	at java.net.URL.<init>(URL.java:572)
	at java.net.URL.<init>(URL.java:464)
	at java.net.URL.<init>(URL.java:413)
	at org.apache.derby.impl.store.raw.RawStore.backup(Unknown Source)
	at org.apache.derby.impl.store.access.RAMAccessManager.backup(Unknown Source)
	at org.apache.derby.impl.db.BasicDatabase.backup(Unknown Source)
	at org.apache.derby.catalog.SystemProcedures.SYSCS_BACKUP_DATABASE(Unknown Source)
	at org.apache.derby.exe.ac601a400fx0117xe8b9x0cb5x0000001875c80.g0(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at org.apache.derby.impl.services.reflect.ReflectMethod.invoke(Unknown Source)
	at org.apache.derby.impl.sql.execute.CallStatementResultSet.open(Unknown Source)
	at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedStatement.executeUpdate(Unknown Source)
	at BackupTest.main(BackupTest.java:34)

==

What happended was:

1/ I tried to backup the database into folder 'C:/the_project_location/db/backup'.

2/ In derby's method (RawStore.backup()), the code does the following:

       String backupDirURL = null;
       try {
           URL url = new URL(backupDir);
           backupDirURL = url.getFile();
       } catch (MalformedURLException ex) {}

       if (backupDirURL != null)
           backupDir = backupDirURL;

Basically it treats the given file path as URL. So the java.net.URL class was called.

3/ The URL class checked the input, and assume "C" is a protocol name, so it tried to look
for protocol handler for it and it tried to load the handler as "sun.net.www.protocol.c.Handler"
from system class loader (sun.misc.Launcher$AppClassLoader)

4/ The system class loader checked if the caller has permission to access package "sun.net.www.protocol.c"
and found that the Derby-generated class (org.apache.derby.exe.ac3a7f0048x0117xc98bxe062x0000001202800)
did not have any security domain, so it threw AccessControlException.

5/ The ElxSecurityManager class noticed the exception and logged it. (That's what we saw on
console.)

6/ The java.net.URL.getURLStreamHandler method captures the exception and *ignored* it. Then
it tired some other ways to determine the protocol handler. At last, the method could not
find any handler for "C", so it threw MalformedURLException.

7/ The RawStore.backup method captured this MalformedURLException, knowing it's not a URL,
and treated the input as a file path.

8/ At last, the database was backuped successfully.

==

So in conclusion:

1/ The exception we saw on the console was a warning, but there was no real problem.

2/ This test shows you some potential problem if Derby does not assign proper security domain
to the generated classes.

Personally, I think the generated classes should have the same security domain as classes
loaded from Derby.jar. Then you (as Derby developer) can avoid calling doPrivileged and save
a lot of time for debuging issues like this.


      was (Author: superq):
    This test case helps to reveal the problems when Derby does not assign proper security
domain to generated classes.

This folder contains a Eclipse project so you can open it and run the test case in the current
folder.

Then you should see the following exception stack trace (using JDK 1.5.0_11): 

java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.net.www.protocol.c)
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
	at java.security.AccessController.checkPermission(AccessController.java:427)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
	at ElxSecurityManager.checkPermission(ElxSecurityManager.java:18)
	at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1512)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
	at java.net.URL.getURLStreamHandler(URL.java:1141)
	at java.net.URL.<init>(URL.java:572)
	at java.net.URL.<init>(URL.java:464)
	at java.net.URL.<init>(URL.java:413)
	at org.apache.derby.impl.store.raw.RawStore.backup(Unknown Source)
	at org.apache.derby.impl.store.access.RAMAccessManager.backup(Unknown Source)
	at org.apache.derby.impl.db.BasicDatabase.backup(Unknown Source)
	at org.apache.derby.catalog.SystemProcedures.SYSCS_BACKUP_DATABASE(Unknown Source)
	at org.apache.derby.exe.ac601a400fx0117xe8b9x0cb5x0000001875c80.g0(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at org.apache.derby.impl.services.reflect.ReflectMethod.invoke(Unknown Source)
	at org.apache.derby.impl.sql.execute.CallStatementResultSet.open(Unknown Source)
	at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedStatement.executeUpdate(Unknown Source)
	at BackupTest.main(BackupTest.java:34)

==

What happended was:

1/ I tried to backup the database into folder 'C:/the_project_location/db/backup'.

2/ In derby's method (RawStore.backup()), the code does the following:

       String backupDirURL = null;
       try {
           URL url = new URL(backupDir);
           backupDirURL = url.getFile();
       } catch (MalformedURLException ex) {}

       if (backupDirURL != null)
           backupDir = backupDirURL;

Basically it treats the given file path as URL. So the java.net.URL class was called.

3/ The URL class checked the input, and assume "C" is a protocol name, so it tried to look
for protocol handler for it and it tried to load the handler as "sun.net.www.protocol.c.Handler"
from system class loader (sun.misc.Launcher$AppClassLoader)

4/ The system class loader checked if the caller has permission to access package "sun.net.www.protocol.c"
and found that the Derby-generated class (org.apache.derby.exe.ac3a7f0048x0117xc98bxe062x0000001202800)
did not have any security domain, so it threw AccessControlException.

5/ The ElxSecurityManager class noticed the exception and logged it. (That's what we saw on
console.)

6/ The java.net.URL.getURLStreamHandler method captures the exception and *ignored* it. Then
it tired some other ways to determine the protocol handler. At last, the method could not
find any handler for "C", so it threw MalformedURLException.

7/ The RawStore.backup method captured this MalformedURLException, knowing it's not a URL,
and treated the input as a file path.

8/ At last, the database was backuped successfully.

==

So in conclusion:

1/ The exception we saw on the console was a warning, but there was no real problem.

2/ This test shows you some potential problem if Derby does not assign proper security domain
to the generated classes.

Personally, I think the generated classes should have the same security domain as classes
loaded from Derby.jar. Then you (as Derby developer) can avoid calling doPrivileged and save
a lot of time for debuging issues like this.

  
> AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.net.www.protocol.c)
> ---------------------------------------------------------------------------------------------------------------
>
>                 Key: DERBY-3363
>                 URL: https://issues.apache.org/jira/browse/DERBY-3363
>             Project: Derby
>          Issue Type: Bug
>          Components: Security
>    Affects Versions: 10.3.2.1
>         Environment: ------------------ Java Information ------------------
> Java Version:    1.5.0_11
> Java Vendor:     Sun Microsystems Inc.
> Java home:       C:\Program Files\Java\jre1.5.0_11
> Java classpath:  derby.jar
> OS name:         Windows XP
> OS architecture: x86
> OS version:      5.1
> Java user name:  Guo Qiang
> Java user home:  C:\Documents and Settings\Guo Qiang
> Java user dir:   C:\Repertoire-Server-20080118\RepertoireServer\lib
> java.specification.name: Java Platform API Specification
> java.specification.version: 1.5
> --------- Derby Information --------
> JRE - JDBC: J2SE 5.0 - JDBC 3.0
> [C:\Repertoire-Server-20080118\RepertoireServer\lib\derby.jar] 10.3.2.1 - (59911
> 0)
>            Reporter: Song Guo Qiang
>         Attachments: DerbyBackupTest.zip
>
>   Original Estimate: 48h
>  Remaining Estimate: 48h
>
> I got one AccessControlException when I tried to backup my derby database using code
like:
> Statement statement;
> String dbPath;
> ...
> statement.executeUpdate("CALL SYSCS_UTIL.SYSCS_BACKUP_DATABASE('" + dbPath + "')");
> ==
> I run my code with the default security manager installed. The exception stack trace
is:
> java.security.AccessControlException: access denied (java.lang.RuntimePermission
>  accessClassInPackage.sun.net.www.protocol.c)
>         at java.security.AccessControlContext.checkPermission(AccessControlConte
> xt.java:264)
>         at java.security.AccessController.checkPermission(AccessController.java:
> 427)
>         at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
>         at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:151
> 2)
>         at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
>         at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
>         at java.net.URL.getURLStreamHandler(URL.java:1141)
>         at java.net.URL.<init>(URL.java:572)
>         at java.net.URL.<init>(URL.java:464)
>         at java.net.URL.<init>(URL.java:413)
>         at org.apache.derby.impl.store.raw.RawStore.backup(Unknown Source)
>         at org.apache.derby.impl.store.access.RAMAccessManager.backup(Unknown So
> urce)
>         at org.apache.derby.impl.db.BasicDatabase.backup(Unknown Source)
>         at org.apache.derby.catalog.SystemProcedures.SYSCS_BACKUP_DATABASE(Unkno
> wn Source)
>         at org.apache.derby.exe.ac3a7f0048x0117xc98bxe062x0000001202800.g0(Unkno
> wn Source)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
> java:39)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
> sorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:585)
>         at org.apache.derby.impl.services.reflect.ReflectMethod.invoke(Unknown S
> ource)
>         at org.apache.derby.impl.sql.execute.CallStatementResultSet.open(Unknown
>  Source)
>         at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown So
> urce)
>         at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown So
> urce)
>         at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
>         at org.apache.derby.impl.jdbc.EmbedStatement.executeUpdate(Unknown Sourc
> e)
>         at com.elixirtech.ers2.db.DBSystem.systemUpdate(Unknown Source)
> ==
> I did some quick debug. I guess the problem happens because Derby generates some classes
on the fly but forgets to assign proper security domains when loading the generated classes
(such as 'org.apache.derby.exe.ac3a7f0048x0117xc98bxe062x0000001202800'). When the generated
code tried to access some sun.* packages, the security check failed.
> Ideally, Derby code should call 
> ClassLoader.defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain)

> instead of 
> ClassLoader.defineClass(String name, byte[] b, int off, int len)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message