北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

RuntimePermission "exitVM"

ポリシーファイルにexitVM権限を付加しなくても、アプリはSystem.exit()可能だそうです。ここを流し読みした感じ、sun.misc.Launcher.AppClassLoader経由ではexitVM権限が付加されるみたい。確かに、デフォルトのjava.policyにはexitVM権限は書かれていないのに、セキュリティマネージャを有効にしてもexit()は可能ですねえ。

ならば、URLClassLoader経由でロードさせればSystem.exit()できなくなるんでしょうか? Runnableを継承したOuterClassを作って、CLASSPATHの通ってないディレクトリに置いて試してみます。OuterClass.run()からSystem.exit()を呼んでます。

Runnable outerClass = null;
try{
    ClassLoader cl = new URLClassLoader(
        new URL[] {new File("CLASSPATHの通ってないディレクトリ").toURL()}
    );
    Class cls = cl.loadClass("OuterClass");
    outerClass = (Runnable) cls.newInstance();
}catch(Exception e){
    throw new RuntimeException(e);
}
outerClass.run();

【結果】
Exception in thread "main" java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM)
	at java.security.AccessControlContext.checkPermission(Unknown Source)
	at java.security.AccessController.checkPermission(Unknown Source)
	at java.lang.SecurityManager.checkPermission(Unknown Source)
	at java.lang.SecurityManager.checkExit(Unknown Source)
	at java.lang.Runtime.exit(Unknown Source)
	at java.lang.System.exit(Unknown Source)
	at OuterClass.run(OuterClass.java:12)
	at PolicyTest.main(PolicyTest.java:41)

出ました! おめでとう。

にしても、ClassLoaderを含めたjavaのセキュリティの話は難しいですね。書籍を買って勉強したほうがいいかなあ。たとえば↓とか。

Javaセキュリティ
スコット オークス Scott Oaks 島田 秋雄
4873110645


ちなみに、この実験をするのにいくらか準備が必要です。まず、SecurityManagerを有効にするために、javaを-Djava.security.manager付きで起動する必要があります。

でもって、SecurityManagerが有効になるとClassLoaderの作成ができなくなったりする可能性があるので、自作のpolicyファイルを作ってjavaに与えます。-Djava.security.policy=ポリシファイルPATH、とオプションで指定するといいです。

grant { 
	permission java.lang.RuntimePermission "createClassLoader";
	//permission java.lang.RuntimePermission "exitVM";
};

他、実行する条件によっては java.util.PropertyPermission "user.dir", "read" とか java.io.FilePermission "hogedir${/}-", "read" とか必要になってくるかも。