Skip to content

Commit 957e0d0

Browse files
committed
Implicit unpermitted operations should be sandboxed #791
1 parent 439a0d8 commit 957e0d0

File tree

5 files changed

+43
-29
lines changed

5 files changed

+43
-29
lines changed

utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt

+5-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.utbot.engine
22

33
import org.utbot.common.invokeCatching
4-
import org.utbot.common.withAccessibility
54
import org.utbot.framework.plugin.api.ClassId
65
import org.utbot.framework.plugin.api.ConstructorId
76
import org.utbot.framework.plugin.api.EnvironmentModels
@@ -41,6 +40,7 @@ import org.utbot.framework.plugin.api.util.jClass
4140
import org.utbot.framework.plugin.api.util.method
4241
import org.utbot.framework.plugin.api.util.utContext
4342
import org.utbot.framework.util.anyInstance
43+
import org.utbot.instrumentation.process.runSandbox
4444
import java.lang.reflect.Field
4545
import java.lang.reflect.Modifier
4646
import kotlin.reflect.KClass
@@ -405,17 +405,13 @@ class ValueConstructor {
405405
private fun value(model: UtModel) = construct(model, null).value
406406

407407
private fun MethodId.call(args: List<Any?>, instance: Any?): Any? =
408-
method.run {
409-
withAccessibility {
410-
invokeCatching(obj = instance, args = args).getOrThrow()
411-
}
408+
method.runSandbox {
409+
invokeCatching(obj = instance, args = args).getOrThrow()
412410
}
413411

414412
private fun ConstructorId.call(args: List<Any?>): Any? =
415-
constructor.run {
416-
withAccessibility {
417-
newInstance(*args.toTypedArray())
418-
}
413+
constructor.runSandbox {
414+
newInstance(*args.toTypedArray())
419415
}
420416

421417
/**

utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt

+5-9
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import kotlin.reflect.KClass
4444
import org.mockito.Mockito
4545
import org.mockito.stubbing.Answer
4646
import org.objectweb.asm.Type
47-
import org.utbot.common.withAccessibility
47+
import org.utbot.instrumentation.process.runSandbox
4848

4949
/**
5050
* Constructs values (including mocks) from models.
@@ -441,17 +441,13 @@ class MockValueConstructor(
441441
}
442442

443443
private fun MethodId.call(args: List<Any?>, instance: Any?): Any? =
444-
method.run {
445-
withAccessibility {
446-
invokeCatching(obj = instance, args = args).getOrThrow()
447-
}
444+
method.runSandbox {
445+
invokeCatching(obj = instance, args = args).getOrThrow()
448446
}
449447

450448
private fun ConstructorId.call(args: List<Any?>): Any? =
451-
constructor.run {
452-
withAccessibility {
453-
newInstance(*args.toTypedArray())
454-
}
449+
constructor.runSandbox {
450+
newInstance(*args.toTypedArray())
455451
}
456452

457453
/**

utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtExecutionInstrumentation.kt

+13-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import java.security.AccessControlException
4343
import java.security.ProtectionDomain
4444
import java.util.IdentityHashMap
4545
import org.objectweb.asm.Type
46+
import org.utbot.framework.plugin.api.MissingState
4647
import kotlin.reflect.jvm.javaMethod
4748

4849
/**
@@ -144,7 +145,18 @@ object UtExecutionInstrumentation : Instrumentation<UtConcreteExecutionResult> {
144145
traceHandler.resetTrace()
145146

146147
return MockValueConstructor(instrumentationContext).use { constructor ->
147-
val params = constructor.constructMethodParameters(parametersModels)
148+
val params = try {
149+
constructor.constructMethodParameters(parametersModels)
150+
} catch (e: Throwable) {
151+
if (e.cause is AccessControlException) {
152+
return@use UtConcreteExecutionResult(
153+
MissingState,
154+
UtSandboxFailure(e.cause!!),
155+
Coverage()
156+
)
157+
}
158+
throw e
159+
}
148160
val staticFields = constructor
149161
.constructStatics(
150162
stateBefore

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/instrumentation/InvokeInstrumentation.kt

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package org.utbot.instrumentation.instrumentation
22

3-
import org.utbot.common.withAccessibility
43
import org.utbot.framework.plugin.api.util.signature
5-
import org.utbot.instrumentation.process.sandbox
4+
import org.utbot.instrumentation.process.runSandbox
65
import java.lang.reflect.Constructor
76
import java.lang.reflect.InvocationTargetException
87
import java.lang.reflect.Method
@@ -53,18 +52,18 @@ class InvokeInstrumentation : Instrumentation<Result<*>> {
5352
methodOrConstructor.run {
5453
val result = when (this) {
5554
is Method ->
56-
withAccessibility {
55+
runSandbox {
5756
runCatching {
58-
sandbox { invoke(thisObject, *realArgs.toTypedArray()) }.let {
57+
invoke(thisObject, *realArgs.toTypedArray()).let {
5958
if (returnType != Void.TYPE) it else Unit
6059
} // invocation on method returning void will return null, so we replace it with Unit
6160
}
6261
}
6362

6463
is Constructor<*> ->
65-
withAccessibility {
64+
runSandbox {
6665
runCatching {
67-
sandbox { newInstance(*realArgs.toTypedArray()) }
66+
newInstance(*realArgs.toTypedArray())
6867
}
6968
}
7069

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/process/Security.kt

+15-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
package org.utbot.instrumentation.process
44

5+
import org.utbot.common.withAccessibility
56
import sun.security.provider.PolicyFile
7+
import java.lang.reflect.AccessibleObject
68
import java.net.URI
79
import java.nio.file.Files
810
import java.nio.file.Paths
@@ -28,6 +30,15 @@ internal fun permissions(block: SimplePolicy.() -> Unit) {
2830
}
2931
}
3032

33+
/**
34+
* Make this [AccessibleObject] accessible and run a block inside sandbox.
35+
*/
36+
fun <O: AccessibleObject, R> O.runSandbox(block: O.() -> R): R {
37+
return withAccessibility {
38+
sandbox { block() }
39+
}
40+
}
41+
3142
/**
3243
* Run [block] in sandbox mode.
3344
*
@@ -45,12 +56,12 @@ internal fun permissions(block: SimplePolicy.() -> Unit) {
4556
* ```
4657
* Read more [about policy file and syntax](https://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html#Examples)
4758
*/
48-
internal fun <T> sandbox(block: () -> T): T {
59+
fun <T> sandbox(block: () -> T): T {
4960
val policyPath = Paths.get(System.getProperty("user.home"), ".utbot", "sandbox.policy")
5061
return sandbox(policyPath.toUri()) { block() }
5162
}
5263

53-
internal fun <T> sandbox(file: URI, block: () -> T): T {
64+
fun <T> sandbox(file: URI, block: () -> T): T {
5465
val path = Paths.get(file)
5566
val perms = mutableListOf<Permission>(
5667
RuntimePermission("accessDeclaredMembers")
@@ -64,12 +75,12 @@ internal fun <T> sandbox(file: URI, block: () -> T): T {
6475
return sandbox(perms, allCodeSource) { block() }
6576
}
6677

67-
internal fun <T> sandbox(permission: List<Permission>, cs: CodeSource, block: () -> T): T {
78+
fun <T> sandbox(permission: List<Permission>, cs: CodeSource, block: () -> T): T {
6879
val perms = permission.fold(Permissions()) { acc, p -> acc.add(p); acc }
6980
return sandbox(perms, cs) { block() }
7081
}
7182

72-
internal fun <T> sandbox(perms: PermissionCollection, cs: CodeSource, block: () -> T): T {
83+
fun <T> sandbox(perms: PermissionCollection, cs: CodeSource, block: () -> T): T {
7384
val acc = AccessControlContext(arrayOf(ProtectionDomain(cs, perms)))
7485
return try {
7586
AccessController.doPrivileged(PrivilegedAction { block() }, acc)

0 commit comments

Comments
 (0)