Add permission to access sun.reflect.MethodAccessorImpl from Groovy scripts

Groovy uses reflection to invoke closures. These reflective calls are optimized by the JVM after "sun.reflect.inflationThreshold" number of invocations.
After inflation, access to sun.reflect.MethodAccessorImpl is required from the security manager.

Closes #16536
This commit is contained in:
Yannick Welsch 2016-02-09 16:39:42 +01:00
parent 77a1649905
commit 380393a5b7
4 changed files with 7 additions and 0 deletions

View File

@ -49,6 +49,7 @@ grant {
permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation"; permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation";
permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.vmplugin.v7.IndyInterface"; permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.vmplugin.v7.IndyInterface";
permission org.elasticsearch.script.ClassPermission "sun.reflect.ConstructorAccessorImpl"; permission org.elasticsearch.script.ClassPermission "sun.reflect.ConstructorAccessorImpl";
permission org.elasticsearch.script.ClassPermission "sun.reflect.MethodAccessorImpl";
permission org.elasticsearch.script.ClassPermission "groovy.lang.Closure"; permission org.elasticsearch.script.ClassPermission "groovy.lang.Closure";
permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.GeneratedClosure"; permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.GeneratedClosure";

View File

@ -90,6 +90,10 @@ public class GroovySecurityTests extends ESTestCase {
// Groovy closures // Groovy closures
assertSuccess("[1, 2, 3, 4].findAll { it % 2 == 0 }"); assertSuccess("[1, 2, 3, 4].findAll { it % 2 == 0 }");
assertSuccess("def buckets=[ [2, 4, 6, 8], [10, 12, 16, 14], [18, 22, 20, 24] ]; buckets[-3..-1].every { it.every { i -> i % 2 == 0 } }"); assertSuccess("def buckets=[ [2, 4, 6, 8], [10, 12, 16, 14], [18, 22, 20, 24] ]; buckets[-3..-1].every { it.every { i -> i % 2 == 0 } }");
// Groovy uses reflection to invoke closures. These reflective calls are optimized by the JVM after "sun.reflect.inflationThreshold"
// invocations. After the inflation step, access to sun.reflect.MethodAccessorImpl is required from the security manager. This test,
// assuming a inflation threshold below 100 (15 is current value on Oracle JVMs), checks that the relevant permission is available.
assertSuccess("(1..100).collect{ it + 1 }");
// Fail cases: // Fail cases:
assertFailure("pr = Runtime.getRuntime().exec(\"touch /tmp/gotcha\"); pr.waitFor()", MissingPropertyException.class); assertFailure("pr = Runtime.getRuntime().exec(\"touch /tmp/gotcha\"); pr.waitFor()", MissingPropertyException.class);

View File

@ -84,6 +84,7 @@ public class JavaScriptSecurityTests extends ESTestCase {
public void testOK() { public void testOK() {
assertSuccess("1 + 2"); assertSuccess("1 + 2");
assertSuccess("Math.cos(Math.PI)"); assertSuccess("Math.cos(Math.PI)");
assertSuccess("Array.apply(null, Array(100)).map(function (_, i) {return i;}).map(function (i) {return i+1;})");
} }
/** Test some javascripts that should hit security exception */ /** Test some javascripts that should hit security exception */

View File

@ -82,6 +82,7 @@ public class PythonSecurityTests extends ESTestCase {
public void testOK() { public void testOK() {
assertSuccess("1 + 2"); assertSuccess("1 + 2");
assertSuccess("from java.lang import Math\nMath.cos(0)"); assertSuccess("from java.lang import Math\nMath.cos(0)");
assertSuccess("map(lambda x: x + 1, range(100))");
} }
/** Test some py scripts that should hit security exception */ /** Test some py scripts that should hit security exception */