This is an automated email from the ASF dual-hosted git repository. shaojunwang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-java-tee-sdk.git
commit a8bbf02670971e1484379d88a172abe15c878380 Author: jeffery.wsj <[email protected]> AuthorDate: Fri Apr 15 10:38:37 2022 +0800 [sdk] Synchronize host and enclave exception handling mechanism Summary: Adjust host's exception handling mechanism according to enclave exception information wrapper Test Plan: all tests pass Reviewers: lei.yul, cengfeng.lzy, sanhong.lsh Issue: https://aone.alibaba-inc.com/task/40820016 CR: https://code.aone.alibaba-inc.com/java-tee/JavaEnclave/codereview/8401257 --- .../exception/ConfidentialComputingException.java | 3 +- .../enclave/framework/ServiceMethodInvoker.java | 2 +- .../framework/ServiceMethodInvokerTest.java | 9 ++- .../host/AbstractEnclave.java | 3 +- .../host/ProxyEnclaveInvocationHandler.java | 11 ++-- .../exception/ConfidentialComputingException.java | 77 ---------------------- .../host/exception/EnclaveCreatingException.java | 2 + .../host/exception/EnclaveDestroyingException.java | 2 + .../exception/EnclaveMethodInvokingException.java | 2 + .../exception/EnclaveNativeInvokingException.java | 47 +++++++++++++ .../host/exception/RemoteAttestationException.java | 2 + .../host/exception/ServicesLoadingException.java | 2 + .../host/exception/ServicesUnloadingException.java | 2 + .../host/MockTestEnclave.java | 3 +- .../host/TestAbstractEnclave.java | 4 +- 15 files changed, 79 insertions(+), 92 deletions(-) diff --git a/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/exception/ConfidentialComputingException.java b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/exception/ConfidentialComputingException.java index 0887a33..43c3b25 100644 --- a/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/exception/ConfidentialComputingException.java +++ b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/exception/ConfidentialComputingException.java @@ -2,8 +2,7 @@ package com.alibaba.confidentialcomputing.common.exception; /** * ConfidentialComputingException {@link ConfidentialComputingException} is base exception in - * JavaEnclave's enclave. All exceptions thrown in JavaEnclave enclave will inherit this - * base exception. + * JavaEnclave. All exceptions thrown in JavaEnclave will inherit this base exception. * Programmers need to handle ConfidentialComputingException seriously. */ public class ConfidentialComputingException extends Exception { diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvoker.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvoker.java index 899ec5a..5ee639f 100644 --- a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvoker.java +++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvoker.java @@ -59,7 +59,7 @@ public final class ServiceMethodInvoker implements EnclaveMethodInvoker<EnclaveI returnedValue = method.invoke(receiverInstance, inputData.getArguments()); } catch (InvocationTargetException e) { // The exception happens in the vocation is the user's exception, it will be returned to the user. - throwable = e.getCause(); + throwable = e; } catch (Throwable t) { return new EnclaveInvocationResult(null, new ConfidentialComputingException(t)); } diff --git a/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvokerTest.java b/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvokerTest.java index 8b4bbe4..7a7dc11 100644 --- a/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvokerTest.java +++ b/sdk/enclave/src/test/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvokerTest.java @@ -19,6 +19,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.lang.reflect.InvocationTargetException; + public class ServiceMethodInvokerTest { private static ServiceMethodInvoker serviceMethodInvoker = new ServiceMethodInvoker(); @@ -63,7 +65,8 @@ public class ServiceMethodInvokerTest { assertNull(wrappedResult, "Expect to have non-null result from invoking service method call."); Throwable e = result.getException(); assertNotNull(e); - assertTrue(e instanceof ArithmeticException); + assertTrue(e instanceof InvocationTargetException); + assertTrue(((InvocationTargetException) e).getCause() instanceof ArithmeticException); } /** @@ -125,7 +128,7 @@ public class ServiceMethodInvokerTest { } @Test - public void testDefaultMethod(){ + public void testDefaultMethod() { EnclaveInvocationResult result = callServiceImplMethod(services[0], "getConstant", EMPTY_STRING_ARRAY, @@ -138,7 +141,7 @@ public class ServiceMethodInvokerTest { } @Test - public void testGrandChildMethod(){ + public void testGrandChildMethod() { EnclaveInvocationResult result = callNumericAdd(services[2], 1, 2); assertNotNull(result); Object wrappedResult = result.getResult(); diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AbstractEnclave.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AbstractEnclave.java index 50a92f6..c290e6f 100644 --- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AbstractEnclave.java +++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AbstractEnclave.java @@ -153,13 +153,12 @@ abstract class AbstractEnclave implements Enclave { throw new EnclaveMethodInvokingException("EnclaveInvokeResultWrapper deserialization failed.", e); } Throwable exception = resultWrapper.getException(); - Object result = resultWrapper.getResult(); if (exception != null) { EnclaveMethodInvokingException e = new EnclaveMethodInvokingException("method invoke exception happened in enclave."); e.initCause(exception); throw e; } - return result; + return resultWrapper.getResult(); } finally { getEnclaveContext().getEnclaveToken().restoreToken(); } diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ProxyEnclaveInvocationHandler.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ProxyEnclaveInvocationHandler.java index 65eb630..db1a6be 100644 --- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ProxyEnclaveInvocationHandler.java +++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ProxyEnclaveInvocationHandler.java @@ -2,6 +2,7 @@ package com.alibaba.confidentialcomputing.host; import com.alibaba.confidentialcomputing.common.EnclaveInvocationContext; import com.alibaba.confidentialcomputing.common.ServiceHandler; +import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException; import com.alibaba.confidentialcomputing.host.exception.EnclaveMethodInvokingException; import java.lang.reflect.InvocationTargetException; @@ -49,9 +50,10 @@ class ProxyEnclaveInvocationHandler implements InvocationHandler, Runnable { result = enclave.InvokeEnclaveMethod(methodInvokeMetaWrapper); } catch (EnclaveMethodInvokingException e) { // Get cause exception if it has one. - Throwable cause = e.getCause(); + ConfidentialComputingException enclaveException = (ConfidentialComputingException) e.getCause(); + Throwable enclaveCauseException = enclaveException.getCause(); Class<?>[] exceptionTypes = method.getExceptionTypes(); - if (cause != null && cause instanceof InvocationTargetException) { + if (enclaveCauseException instanceof InvocationTargetException) { // Check whether cause exception matches one of the method's exception declaration. // If it's true, it illustrates that an exception happened in enclave when the service // method was invoked in enclave, we should throw this exception directly and user will @@ -59,9 +61,10 @@ class ProxyEnclaveInvocationHandler implements InvocationHandler, Runnable { // If it's false, it illustrates that an exception happened in host side or enclave side, // but the exception is not belong to the method's declaration. In the case we should throw // EnclaveMethodInvokingException again. + Throwable rootCause = enclaveCauseException.getCause(); for (Class<?> exception : exceptionTypes) { - if (exception == cause.getCause().getClass()) { - throw cause.getCause(); + if (exception == rootCause.getClass()) { + throw rootCause; } } } diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ConfidentialComputingException.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ConfidentialComputingException.java deleted file mode 100644 index 85ab3fe..0000000 --- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ConfidentialComputingException.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.alibaba.confidentialcomputing.host.exception; - -/** - * ConfidentialComputingException {@link ConfidentialComputingException} is base exception in - * JavaEnclave's host. All exceptions thrown in JavaEnclave host will inherit this - * base exception. - * Programmers need to handle ConfidentialComputingException seriously. - */ -public class ConfidentialComputingException extends Exception { - /** - * @param info exception information. - */ - public ConfidentialComputingException(String info) { - super(info); - } - - /** - * @param e exception. - */ - public ConfidentialComputingException(Throwable e) { - super(e); - } - - /** - * @param info exception message. - * @param e exception. - */ - public ConfidentialComputingException(String info, Throwable e) { - super(info, e); - } - - /** - * EnclaveNativeInvokingException defines all kinds of possible exceptions towards an - * enclave's native operation. Basically there are two kinds error about enclave operation, - * one kind is native calling return an unexpected value, the other kind is an exception - * happen in enclave and transform into host side. If a native invoking into enclave returns - * an error value, enum of EnclaveNativeInvokingException will add extra error message details - * for debugging; If an exception happened in enclave and transformed to host side, it will be - * thrown again in host side to user. - * Programmers need to handle EnclaveNativeInvokingException seriously. - */ - enum EnclaveNativeInvokingException { - // Enclave creating failed. - ENCLAVE_CREATING_ERROR("A0001", "creating enclave failed."), - // Enclave destroying failed. - ENCLAVE_DESTROYING_ERROR("A0002", "destroying enclave failed"), - // Services loading failed. - SERVICES_LOADING_ERROR("A0003", "services loading failed in enclave"), - // Services unloading failed. - SERVICES_UNLOADING_ERROR("A0004", "service unloading failed in enclave"), - // Service method invoking failed. - SERVICE_METHOD_INVOKING_ERROR("A0005", "service method invoking failed"), - // Enclave remote attestation exception. - ENCLAVE_REMOTE_ATTESTATION_ERROR("A0006", "tee remote attestation failed"); - - private final String errorCode; - private final String errorMessage; - - EnclaveNativeInvokingException(String errorCode, String errorMessage) { - this.errorCode = errorCode; - this.errorMessage = errorMessage; - } - - String buildExceptionMessage(String details) { - if (details != null) { - return this.toString() + " DetailErrorMessage: " + details; - } else { - return this.toString(); - } - } - - @Override - public String toString() { - return "ErrorCode: " + this.errorCode + " , " + " ErrorMessage: " + this.errorMessage; - } - } -} \ No newline at end of file diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException.java index cfbdd99..53307bd 100644 --- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException.java +++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException.java @@ -1,5 +1,7 @@ package com.alibaba.confidentialcomputing.host.exception; +import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException; + /** * EnclaveCreatingException {@link EnclaveCreatingException} is thrown when exception happen * during an enclave was creating. diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveDestroyingException.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveDestroyingException.java index c46b1d5..6800ba9 100644 --- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveDestroyingException.java +++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveDestroyingException.java @@ -1,5 +1,7 @@ package com.alibaba.confidentialcomputing.host.exception; +import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException; + /** * EnclaveDestroyingException {@link EnclaveDestroyingException} is thrown when exception happen * during an enclave was destroying. diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveMethodInvokingException.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveMethodInvokingException.java index fcb534b..1b57481 100644 --- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveMethodInvokingException.java +++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveMethodInvokingException.java @@ -1,5 +1,7 @@ package com.alibaba.confidentialcomputing.host.exception; +import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException; + /** * EnclaveMethodInvokingException {@link EnclaveMethodInvokingException} is thrown when exception happen * during an enclave's method was invoking. diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveNativeInvokingException.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveNativeInvokingException.java new file mode 100644 index 0000000..052234f --- /dev/null +++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveNativeInvokingException.java @@ -0,0 +1,47 @@ +package com.alibaba.confidentialcomputing.host.exception; + +/** + * EnclaveNativeInvokingException defines all kinds of possible exceptions towards an + * enclave's native operation. Basically there are two kinds error about enclave operation, + * one kind is native calling return an unexpected value, the other kind is an exception + * happen in enclave and transform into host side. If a native invoking into enclave returns + * an error value, enum of EnclaveNativeInvokingException will add extra error message details + * for debugging; If an exception happened in enclave and transformed to host side, it will be + * thrown again in host side to user. + * Programmers need to handle EnclaveNativeInvokingException seriously. + */ +enum EnclaveNativeInvokingException { + // Enclave creating failed. + ENCLAVE_CREATING_ERROR("A0001", "creating enclave failed."), + // Enclave destroying failed. + ENCLAVE_DESTROYING_ERROR("A0002", "destroying enclave failed"), + // Services loading failed. + SERVICES_LOADING_ERROR("A0003", "services loading failed in enclave"), + // Services unloading failed. + SERVICES_UNLOADING_ERROR("A0004", "service unloading failed in enclave"), + // Service method invoking failed. + SERVICE_METHOD_INVOKING_ERROR("A0005", "service method invoking failed"), + // Enclave remote attestation exception. + ENCLAVE_REMOTE_ATTESTATION_ERROR("A0006", "tee remote attestation failed"); + + private final String errorCode; + private final String errorMessage; + + EnclaveNativeInvokingException(String errorCode, String errorMessage) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + } + + String buildExceptionMessage(String details) { + if (details != null) { + return this.toString() + " DetailErrorMessage: " + details; + } else { + return this.toString(); + } + } + + @Override + public String toString() { + return "ErrorCode: " + this.errorCode + " , " + " ErrorMessage: " + this.errorMessage; + } +} \ No newline at end of file diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/RemoteAttestationException.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/RemoteAttestationException.java index d5faaab..b2582f4 100644 --- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/RemoteAttestationException.java +++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/RemoteAttestationException.java @@ -1,5 +1,7 @@ package com.alibaba.confidentialcomputing.host.exception; +import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException; + /** * RemoteAttestationException {@link RemoteAttestationException} is thrown when an enclave generates remote * attestation report and returns an error value. diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ServicesLoadingException.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ServicesLoadingException.java index 7fda291..f791ffb 100644 --- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ServicesLoadingException.java +++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ServicesLoadingException.java @@ -1,5 +1,7 @@ package com.alibaba.confidentialcomputing.host.exception; +import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException; + /** * ServicesLoadingException {@link ServicesLoadingException} is thrown when exception happen * during an enclave's service was loading. diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ServicesUnloadingException.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ServicesUnloadingException.java index 4c0de9d..349ba5a 100644 --- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ServicesUnloadingException.java +++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/ServicesUnloadingException.java @@ -1,5 +1,7 @@ package com.alibaba.confidentialcomputing.host.exception; +import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException; + /** * ServicesUnloadingException {@link ServicesUnloadingException} is thrown when exception happen * during an enclave's service was unloading. diff --git a/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/MockTestEnclave.java b/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/MockTestEnclave.java index 04faf7b..e1b8a3c 100644 --- a/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/MockTestEnclave.java +++ b/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/MockTestEnclave.java @@ -1,6 +1,7 @@ package com.alibaba.confidentialcomputing.host; import com.alibaba.confidentialcomputing.common.*; +import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException; import com.alibaba.confidentialcomputing.host.exception.EnclaveCreatingException; import com.alibaba.confidentialcomputing.host.exception.RemoteAttestationException; @@ -145,7 +146,7 @@ class MockTestEnclave extends AbstractEnclave { method.setAccessible(true); invokeRet = method.invoke(instance, args); } catch (Throwable e) { - exception = e; + exception = new ConfidentialComputingException(e); } finally { result = new EnclaveInvocationResult(invokeRet, exception); } diff --git a/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/TestAbstractEnclave.java b/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/TestAbstractEnclave.java index a66aca7..785b6c6 100644 --- a/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/TestAbstractEnclave.java +++ b/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/TestAbstractEnclave.java @@ -35,12 +35,12 @@ class TestAbstractEnclave { assertEquals(1, queue.size()); ((MockTestEnclave) enclave).unloadService((ServiceHandler) queue.poll()); assertEquals(0, ((MockTestEnclave) enclave).getServicesNum()); - enclave.destroy(); - assertThrows(ServicesLoadingException.class, () -> enclave.load(Service.class)); try { service.doNothing(); } catch (UndeclaredThrowableException e) { assertEquals(e.getCause().getClass(), EnclaveMethodInvokingException.class); } + enclave.destroy(); + assertThrows(ServicesLoadingException.class, () -> enclave.load(Service.class)); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
