在成功通过JNI打电话后,什么可能导致Segfaults?

发布于 2025-02-02 15:01:16 字数 13349 浏览 2 评论 0原文

上下文 我正在使用Intel SGX撰写主论文,以便在Java项目旁边使用Enclave代码。

该项目使用Gradle进行安装,我添加了一个.jar,其中包含一个包含本机呼叫的类和包含这些调用代码的.SO文件。

我目前只能打开飞地并计算DH密钥交换的EC曲线,但是,随着Java代码的移动,发生了Segfaults。但是,这些segfault在C代码内不出现,因为我能够从我的Java项目中的本机代码中检索正确且预期的结果。这些分割的故障通常发生在大量的I/O工作负载(至少这是我到目前为止推论的),通常是插座,这是我使用的,因为我的论文在分布式系统中。

c代码:

JNIEXPORT jint JNICALL Java_sgxUtils_SgxFunctions_jni_1initialize_1enclave
  (JNIEnv *env , jobject,jint enclaveId, jbyteArray file_path){

    if(file_path == NULL){
      printf("NULL FILEPATH. error.");
      return -1;
    }
    char token_path[MAX_PATH] = {'\0'};
    sgx_launch_token_t token = {0};
    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
    int updated = 0;
    //Get the id of a given Enclave:
    global_eid = (int)enclaveId;
    int length = snprintf(NULL , 0, "%d", enclaveId) + 1; //Gives the length of the Integer as a String.
    char* id_ptr = (char*)malloc(length); 
    snprintf(id_ptr,length,"%d",enclaveId); 


    /* Step 1: try to retrieve the launch token saved by last transaction 
     *         if there is no token, then create a new one.
     */
    /* try to get the token saved in $HOME */
    const char *home_dir = getpwuid(getuid())->pw_dir;
    
    if (home_dir != NULL && 
        (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) {
        /* compose the token path */
        strncpy(token_path, home_dir, strlen(home_dir));
        strncat(token_path, "/", strlen("/"));
        char* correctName = (char*) malloc(length + sizeof(TOKEN_FILENAME) + 1);
        memcpy(correctName,id_ptr,length);
        strncat(correctName,TOKEN_FILENAME,sizeof(TOKEN_FILENAME)+1);
        strncat(token_path,correctName,length + sizeof(TOKEN_FILENAME)+1);
        // strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1);
        // free(correctName);
    } else {
        /* if token path is too long or $HOME is NULL */
        strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
    }

    FILE *fp = fopen(token_path, "rb");
    if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
        printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
    }


    if (fp != NULL) {
        /* read the token from saved file */
        size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
        if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
            /* if token is invalid, clear the buffer */
            memset(&token, 0x0, sizeof(sgx_launch_token_t));
            printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
        }
    }
    printf("\n");
    /* Step 2: call sgx_create_enclave to initialize an enclave instance */
    /* Debug Support: set 2nd parameter to 1 */

    //Here we obtain the char* of the given Enclave file path:
    size_t filename_size = env->GetArrayLength(file_path);
    jbyte* jb_filePath = env->GetByteArrayElements(file_path,NULL);
   
    char* enclave_filePath = (char*) malloc(filename_size);
    memcpy(enclave_filePath,jb_filePath,filename_size);

    ret = sgx_create_enclave(enclave_filePath, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
    if (ret != SGX_SUCCESS) {
        if (fp != NULL) fclose(fp);
        return -1;
    }

    /* Step 3: save the launch token if it is updated */
    if (updated == FALSE || fp == NULL) {
        /* if the token is not updated, or file handler is invalid, do not perform saving */
        if (fp != NULL) fclose(fp);
        return 0;
    }

    /* reopen the file with write capablity */
    fp = freopen(token_path, "wb", fp);
    if (fp == NULL) return 0;
    size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
    if (write_num != sizeof(sgx_launch_token_t))
        printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
    fclose(fp);

    free(id_ptr);
    // env->ReleaseStringUTFChars(file_path,enclave_filePath);
    return 0;
  }

JNIEXPORT jbyteArray JNICALL Java_sgxUtils_SgxFunctions_jni_1sgx_1begin_1ec_1dh(JNIEnv *env, jobject){
    printf("Begin DH \n");

    if(init_happened == 1){ //Verify if the Random generators were seeded.
      sgx_status_t init_status;
      init_mbed(global_eid,&init_status);
      init_happened = 0;
      //printf("Init happened inside enclave.");
    }

    unsigned char* public_ec_key = (unsigned char*)malloc(EC_KEY_SIZE); //32 bytes allocated. (256)
    printf("Calculating EC_DH.\n");

    //Start the ECDH Ecall.
    sgx_status_t ecdh_status;
    create_ec_key_pair(global_eid,&ecdh_status,public_ec_key,EC_KEY_SIZE); //Send the buffer and its size.
    if(ecdh_status != SGX_SUCCESS){
      printf("Failed. ec_key_pair returned %d\n",ecdh_status);
    }

    //Copy the information to a Jbyte in order to return in a JbyteArray:
    jbyte* toCopy = (jbyte*)malloc(EC_KEY_SIZE * sizeof(jbyte));
    memcpy(toCopy,public_ec_key,EC_KEY_SIZE);

    //Return the Public Key:
    jbyteArray result = env->NewByteArray(EC_KEY_SIZE);
    env->SetByteArrayRegion(result,0,EC_KEY_SIZE,toCopy);
    //Free the pointers and return the arrray.
    free(public_ec_key);
    free(toCopy);

    printf("EC_DH Calculated.\n");

    return result;
  }

我将省略Valgrind的大量输出,这只是一个巨大的文件,其中“?”每一行,因为SGX都隐藏了堆栈跟踪,因此没有关于无效读取/写入的信息。

valgrind output

==38490== Warning: client switching stacks?  SP change: 0x6a937a0 --> 0x28789d48
==38490==          to suppress, use: --max-stackframe=567240104 or greater
==38490== Warning: client switching stacks?  SP change: 0x28789d48 --> 0x6a937a0
==38490==          to suppress, use: --max-stackframe=567240104 or greater
==38490== Warning: client switching stacks?  SP change: 0x6a97220 --> 0x28789d48
==38490==          to suppress, use: --max-stackframe=567225128 or greater
==38490==          further instances of this message will not be shown.
==38490== 
==38490== Process terminating with default action of signal 11 (SIGSEGV)
==38490==  Access not within mapped region at address 0x2
==38490==    at 0x27CD0B05: sig_handler_sim(int, siginfo_t*, void*) (in /opt/intel/sgxsdk/lib64/libsgx_urts_sim.so)
==38490==  If you believe this happened as a result of a stack
==38490==  overflow in your program's main thread (unlikely but
==38490==  possible), you can try to increase the size of the
==38490==  main thread stack using the --main-stacksize= flag.
==38490==  The main thread stack size used in this run was 8388608.
==38490== 
==38490== HEAP SUMMARY:
==38490==     in use at exit: 16,636,139 bytes in 39,334 blocks
==38490==   total heap usage: 55,264 allocs, 15,930 frees, 71,819,001 bytes allocated

java代码

    private void initEnclave() {
        this.logger.info("Starting InitEnclave");
        enclave = new SgxFunctions(this.enclaveId);
        try {
            File pemFile = new File(HOME_DIR + "/" + this.enclaveId + ".pem");
            if(!pemFile.exists()) {
                pemFile = SgxFunctions.createPem(this.enclaveId);
            }
            File enclaveFile = new File(HOME_DIR + "/" + this.enclaveId + "enclave_signed.so");
            if(!enclaveFile.exists()) {
                enclave.createSignedEnclave(HOME_DIR, pemFile.getAbsolutePath(), enclaveId);
                this.logger.info("Enclave signed");
            }
            else
                this.logger.info("Enclave file exists. Starting enclave.");
            
            logger.info("ABSOLUTE PATH: " + enclaveFile.getAbsolutePath());
            byte[] enclaveFilePath = enclaveFile.getAbsolutePath().substring(0).getBytes(StandardCharsets.UTF_8);
            byte[] correctPath = Arrays.copyOf(enclaveFilePath, enclaveFilePath.length+1);
            correctPath[correctPath.length-1] = '\0';
            int created = enclave.jni_initialize_enclave(enclaveId,correctPath);
            if(created == 0)
                this.logger.info("Enclave created.");
            else
                this.logger.info("Enclave failed to create.");
//
//          //Create DH parameters:
            this.dh_params = this.enclave.jni_sgx_begin_ec_dh(); //Begin the Enclave EC parameters for DH key exchange.
            this.logger.info("EC-DH Parameters created for Key exchange.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

如果我评论'begin_ec_dh()'调用,则该程序将不会被删除。但是,即使在运行此本机调用时,飞地也将返回可接受的结果,我能够在我的Java代码中使用该结果,但只有直到直到出于不可行的原因而直到其segfault为止。

我怀疑它显然是我的代码,但我不知道发生了什么。 感谢您的帮助,感谢您的帮助,并为漫长的帖子提供了很抱歉。

编辑:

我添加了一个printf(),以便通过文件名指针从JVM中检索崩溃文件。 我不明白的是,如果您查看我的C代码,我已经完全分配了来自Java的数组大小(并且我在我的Java代码中添加了Null终结器,这是以前是另一个segfault的来源),任何想法)是什么原因造成的?好像我正在删除无效的指针,但是为什么它是无效的?

JVM崩溃文件

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f9f51fd9627, pid=9910, tid=9911
#
# JRE version: OpenJDK Runtime Environment (17.0.3+7) (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1)
# Java VM: OpenJDK 64-Bit Server VM (17.0.3+7-Ubuntu-0ubuntu0.20.04.1, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# C  [libc.so.6+0x188627]
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E" (or dumping to /home/andrecruz/Tese/Con-BFT/build/install/library/core.9910)
#
# If you would like to submit a bug report, please visit:
#   Unknown
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

---------------  S U M M A R Y ------------

Command Line: -Djava.security.properties=./config/java.security -Djava.library.path=./lib/ -Dfile.encoding=UTF-8 -XX:ErrorFile=/home/andrecruz/Tese/Con-BFT/ -XX:+ShowCodeDetailsInExceptionMessages -Dlogback.configurationFile=./config/logback.xml bftsmart.demo.map.MapServer 0 10

Host: Intel(R) Core(TM) i5-6440HQ CPU @ 2.60GHz, 4 cores, 7G, Ubuntu 20.04.4 LTS
Time: Sun May 29 23:13:08 2022 WEST elapsed time: 2.134101 seconds (0d 0h 0m 2s)

---------------  T H R E A D  ---------------

Current thread (0x00007f9f4c012b40):  JavaThread "main" [_thread_in_native, id=9911, stack(0x00007f9f5061b000,0x00007f9f5071c000)]

Stack: [0x00007f9f5061b000,0x00007f9f5071c000],  sp=0x00007f9f50718c28,  free space=1015k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libc.so.6+0x188627]
C  [libc.so.6+0x61d6f]  _IO_printf+0xaf
j  sgxUtils.SgxFunctions.jni_initialize_enclave(I[B)I+0
j  bftsmart.tom.ServiceReplica.initEnclave()V+248
j  bftsmart.tom.ServiceReplica.<init>(ILjava/lang/String;Lbftsmart/tom/server/Executable;Lbftsmart/tom/server/Recoverable;Lbftsmart/tom/server/RequestVerifier;Lbftsmart/tom/server/Replier;Lbftsmart/tom/util/KeyLoader;I)V+147
j  bftsmart.tom.ServiceReplica.<init>(ILbftsmart/tom/server/Executable;Lbftsmart/tom/server/Recoverable;I)V+17
j  bftsmart.demo.map.MapServer.<init>(II)V+35
j  bftsmart.demo.map.MapServer.main([Ljava/lang/String;)V+34
v  ~StubRoutines::call_stub
V  [libjvm.so+0x83ae75]
V  [libjvm.so+0x8cf4e9]
V  [libjvm.so+0x8d2392]
C  [libjli.so+0x4abe]
C  [libjli.so+0x84ed]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  sgxUtils.SgxFunctions.jni_initialize_enclave(I[B)I+0
j  bftsmart.tom.ServiceReplica.initEnclave()V+248
j  bftsmart.tom.ServiceReplica.<init>(ILjava/lang/String;Lbftsmart/tom/server/Executable;Lbftsmart/tom/server/Recoverable;Lbftsmart/tom/server/RequestVerifier;Lbftsmart/tom/server/Replier;Lbftsmart/tom/util/KeyLoader;I)V+147
j  bftsmart.tom.ServiceReplica.<init>(ILbftsmart/tom/server/Executable;Lbftsmart/tom/server/Recoverable;I)V+17
j  bftsmart.demo.map.MapServer.<init>(II)V+35
j  bftsmart.demo.map.MapServer.main([Ljava/lang/String;)V+34
v  ~StubRoutines::call_stub

siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000020

Register to memory mapping:

RAX=0x0000000000000010 is an unknown value
RBX=0x00007f9f51ec7b43: <offset 0x0000000000076b43> in /lib/x86_64-linux-gnu/libc.so.6 at 0x00007f9f51e51000
RCX=0x000000000000000f is an unknown value
RDX=0x000000000000002f is an unknown value
RSP=0x00007f9f50718c28 is pointing into the stack for thread: 0x00007f9f4c012b40
RBP=0x00007f9f507191a0 is pointing into the stack for thread: 0x00007f9f4c012b40
RSI=0x00007f9f50719168 is pointing into the stack for thread: 0x00007f9f4c012b40
RDI=0x0000000000000020 is an unknown value
R8 =0x00000000ffffffff points into unknown readable memory: 00
R9 =0x0000000000000009 is an unknown value
R10=0x00007f9f50610099: <offset 0x0000000000007099> in /home/andrecruz/Tese/Con-BFT/build/install/library/lib/libSgx.so at 0x00007f9f50609000
R11=0x000000000000002f is an unknown value
R12=0x00007f9f5203e6a0: _IO_2_1_stdout_+0x0000000000000000 in /lib/x86_64-linux-gnu/libc.so.6 at 0x00007f9f51e51000
R13=0x00007f9f5061008f: <offset 0x000000000000708f> in /home/andrecruz/Tese/Con-BFT/build/install/library/lib/libSgx.so at 0x00007f9f50609000
R14=0x00007f9f507191b0 is pointing into the stack for thread: 0x00007f9f4c012b40
R15=0x0000000000000073 is an unknown value

Context
I am working on my Master Thesis using Intel SGX in order to use Enclave Code alongside a Java project.

The project uses Gradle for installation, and I have added a .jar containing a Class containing Native calls and the .so file containing the code for these calls.

I am currently only being able to open up an enclave and calculate an EC Curve for DH Key exchange, however, as the java code moves on, segfaults occur. These Segfaults however, dont occur inside the C code, as I am able to retrieve the correct and expected results from the native code in my java project. These segmentation faults usually happen there is heavy I/O workload (At least that is what I deduced so far), usually Sockets, which is something I use, since my thesis is in Distributed Systems.

C Code:

JNIEXPORT jint JNICALL Java_sgxUtils_SgxFunctions_jni_1initialize_1enclave
  (JNIEnv *env , jobject,jint enclaveId, jbyteArray file_path){

    if(file_path == NULL){
      printf("NULL FILEPATH. error.");
      return -1;
    }
    char token_path[MAX_PATH] = {'\0'};
    sgx_launch_token_t token = {0};
    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
    int updated = 0;
    //Get the id of a given Enclave:
    global_eid = (int)enclaveId;
    int length = snprintf(NULL , 0, "%d", enclaveId) + 1; //Gives the length of the Integer as a String.
    char* id_ptr = (char*)malloc(length); 
    snprintf(id_ptr,length,"%d",enclaveId); 


    /* Step 1: try to retrieve the launch token saved by last transaction 
     *         if there is no token, then create a new one.
     */
    /* try to get the token saved in $HOME */
    const char *home_dir = getpwuid(getuid())->pw_dir;
    
    if (home_dir != NULL && 
        (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) {
        /* compose the token path */
        strncpy(token_path, home_dir, strlen(home_dir));
        strncat(token_path, "/", strlen("/"));
        char* correctName = (char*) malloc(length + sizeof(TOKEN_FILENAME) + 1);
        memcpy(correctName,id_ptr,length);
        strncat(correctName,TOKEN_FILENAME,sizeof(TOKEN_FILENAME)+1);
        strncat(token_path,correctName,length + sizeof(TOKEN_FILENAME)+1);
        // strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1);
        // free(correctName);
    } else {
        /* if token path is too long or $HOME is NULL */
        strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
    }

    FILE *fp = fopen(token_path, "rb");
    if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
        printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
    }


    if (fp != NULL) {
        /* read the token from saved file */
        size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
        if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
            /* if token is invalid, clear the buffer */
            memset(&token, 0x0, sizeof(sgx_launch_token_t));
            printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
        }
    }
    printf("\n");
    /* Step 2: call sgx_create_enclave to initialize an enclave instance */
    /* Debug Support: set 2nd parameter to 1 */

    //Here we obtain the char* of the given Enclave file path:
    size_t filename_size = env->GetArrayLength(file_path);
    jbyte* jb_filePath = env->GetByteArrayElements(file_path,NULL);
   
    char* enclave_filePath = (char*) malloc(filename_size);
    memcpy(enclave_filePath,jb_filePath,filename_size);

    ret = sgx_create_enclave(enclave_filePath, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
    if (ret != SGX_SUCCESS) {
        if (fp != NULL) fclose(fp);
        return -1;
    }

    /* Step 3: save the launch token if it is updated */
    if (updated == FALSE || fp == NULL) {
        /* if the token is not updated, or file handler is invalid, do not perform saving */
        if (fp != NULL) fclose(fp);
        return 0;
    }

    /* reopen the file with write capablity */
    fp = freopen(token_path, "wb", fp);
    if (fp == NULL) return 0;
    size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
    if (write_num != sizeof(sgx_launch_token_t))
        printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
    fclose(fp);

    free(id_ptr);
    // env->ReleaseStringUTFChars(file_path,enclave_filePath);
    return 0;
  }

JNIEXPORT jbyteArray JNICALL Java_sgxUtils_SgxFunctions_jni_1sgx_1begin_1ec_1dh(JNIEnv *env, jobject){
    printf("Begin DH \n");

    if(init_happened == 1){ //Verify if the Random generators were seeded.
      sgx_status_t init_status;
      init_mbed(global_eid,&init_status);
      init_happened = 0;
      //printf("Init happened inside enclave.");
    }

    unsigned char* public_ec_key = (unsigned char*)malloc(EC_KEY_SIZE); //32 bytes allocated. (256)
    printf("Calculating EC_DH.\n");

    //Start the ECDH Ecall.
    sgx_status_t ecdh_status;
    create_ec_key_pair(global_eid,&ecdh_status,public_ec_key,EC_KEY_SIZE); //Send the buffer and its size.
    if(ecdh_status != SGX_SUCCESS){
      printf("Failed. ec_key_pair returned %d\n",ecdh_status);
    }

    //Copy the information to a Jbyte in order to return in a JbyteArray:
    jbyte* toCopy = (jbyte*)malloc(EC_KEY_SIZE * sizeof(jbyte));
    memcpy(toCopy,public_ec_key,EC_KEY_SIZE);

    //Return the Public Key:
    jbyteArray result = env->NewByteArray(EC_KEY_SIZE);
    env->SetByteArrayRegion(result,0,EC_KEY_SIZE,toCopy);
    //Free the pointers and return the arrray.
    free(public_ec_key);
    free(toCopy);

    printf("EC_DH Calculated.\n");

    return result;
  }

I will omit the large output from Valgrind, it is just a huge file with '?' every line, since SGX hides the Stack trace, giving me no info on the invalid reads/Writes.

Valgrind Output

==38490== Warning: client switching stacks?  SP change: 0x6a937a0 --> 0x28789d48
==38490==          to suppress, use: --max-stackframe=567240104 or greater
==38490== Warning: client switching stacks?  SP change: 0x28789d48 --> 0x6a937a0
==38490==          to suppress, use: --max-stackframe=567240104 or greater
==38490== Warning: client switching stacks?  SP change: 0x6a97220 --> 0x28789d48
==38490==          to suppress, use: --max-stackframe=567225128 or greater
==38490==          further instances of this message will not be shown.
==38490== 
==38490== Process terminating with default action of signal 11 (SIGSEGV)
==38490==  Access not within mapped region at address 0x2
==38490==    at 0x27CD0B05: sig_handler_sim(int, siginfo_t*, void*) (in /opt/intel/sgxsdk/lib64/libsgx_urts_sim.so)
==38490==  If you believe this happened as a result of a stack
==38490==  overflow in your program's main thread (unlikely but
==38490==  possible), you can try to increase the size of the
==38490==  main thread stack using the --main-stacksize= flag.
==38490==  The main thread stack size used in this run was 8388608.
==38490== 
==38490== HEAP SUMMARY:
==38490==     in use at exit: 16,636,139 bytes in 39,334 blocks
==38490==   total heap usage: 55,264 allocs, 15,930 frees, 71,819,001 bytes allocated

Java Code

    private void initEnclave() {
        this.logger.info("Starting InitEnclave");
        enclave = new SgxFunctions(this.enclaveId);
        try {
            File pemFile = new File(HOME_DIR + "/" + this.enclaveId + ".pem");
            if(!pemFile.exists()) {
                pemFile = SgxFunctions.createPem(this.enclaveId);
            }
            File enclaveFile = new File(HOME_DIR + "/" + this.enclaveId + "enclave_signed.so");
            if(!enclaveFile.exists()) {
                enclave.createSignedEnclave(HOME_DIR, pemFile.getAbsolutePath(), enclaveId);
                this.logger.info("Enclave signed");
            }
            else
                this.logger.info("Enclave file exists. Starting enclave.");
            
            logger.info("ABSOLUTE PATH: " + enclaveFile.getAbsolutePath());
            byte[] enclaveFilePath = enclaveFile.getAbsolutePath().substring(0).getBytes(StandardCharsets.UTF_8);
            byte[] correctPath = Arrays.copyOf(enclaveFilePath, enclaveFilePath.length+1);
            correctPath[correctPath.length-1] = '\0';
            int created = enclave.jni_initialize_enclave(enclaveId,correctPath);
            if(created == 0)
                this.logger.info("Enclave created.");
            else
                this.logger.info("Enclave failed to create.");
//
//          //Create DH parameters:
            this.dh_params = this.enclave.jni_sgx_begin_ec_dh(); //Begin the Enclave EC parameters for DH key exchange.
            this.logger.info("EC-DH Parameters created for Key exchange.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

If I comment out the 'begin_ec_dh()' Call, the program will not segfault. However, even when running this native call, the Enclave will return an acceptable result and I am able to use the result in my Java code no problem, but only up until a certain point where it segfaults for an unkown reason.

I suspect its obviously my code, but I have no idea what is going on.
Any help is appreciated, Thank you for your help and sorry for the long post.

Edit:

I have added a printf() in order to retrieve a Crash file from the JVM over the filename Pointer.
What I dont understand is that If you look at my C code, I have allocated exactly the Array Size that comes from java (And I have added the null terminator in my Java Code, which was previously the source of another segfault), any idea what is causing this? Seems like I am dereferencing an Invalid pointer, but why is it invalid?

JVM Crash File

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f9f51fd9627, pid=9910, tid=9911
#
# JRE version: OpenJDK Runtime Environment (17.0.3+7) (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1)
# Java VM: OpenJDK 64-Bit Server VM (17.0.3+7-Ubuntu-0ubuntu0.20.04.1, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# C  [libc.so.6+0x188627]
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E" (or dumping to /home/andrecruz/Tese/Con-BFT/build/install/library/core.9910)
#
# If you would like to submit a bug report, please visit:
#   Unknown
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

---------------  S U M M A R Y ------------

Command Line: -Djava.security.properties=./config/java.security -Djava.library.path=./lib/ -Dfile.encoding=UTF-8 -XX:ErrorFile=/home/andrecruz/Tese/Con-BFT/ -XX:+ShowCodeDetailsInExceptionMessages -Dlogback.configurationFile=./config/logback.xml bftsmart.demo.map.MapServer 0 10

Host: Intel(R) Core(TM) i5-6440HQ CPU @ 2.60GHz, 4 cores, 7G, Ubuntu 20.04.4 LTS
Time: Sun May 29 23:13:08 2022 WEST elapsed time: 2.134101 seconds (0d 0h 0m 2s)

---------------  T H R E A D  ---------------

Current thread (0x00007f9f4c012b40):  JavaThread "main" [_thread_in_native, id=9911, stack(0x00007f9f5061b000,0x00007f9f5071c000)]

Stack: [0x00007f9f5061b000,0x00007f9f5071c000],  sp=0x00007f9f50718c28,  free space=1015k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libc.so.6+0x188627]
C  [libc.so.6+0x61d6f]  _IO_printf+0xaf
j  sgxUtils.SgxFunctions.jni_initialize_enclave(I[B)I+0
j  bftsmart.tom.ServiceReplica.initEnclave()V+248
j  bftsmart.tom.ServiceReplica.<init>(ILjava/lang/String;Lbftsmart/tom/server/Executable;Lbftsmart/tom/server/Recoverable;Lbftsmart/tom/server/RequestVerifier;Lbftsmart/tom/server/Replier;Lbftsmart/tom/util/KeyLoader;I)V+147
j  bftsmart.tom.ServiceReplica.<init>(ILbftsmart/tom/server/Executable;Lbftsmart/tom/server/Recoverable;I)V+17
j  bftsmart.demo.map.MapServer.<init>(II)V+35
j  bftsmart.demo.map.MapServer.main([Ljava/lang/String;)V+34
v  ~StubRoutines::call_stub
V  [libjvm.so+0x83ae75]
V  [libjvm.so+0x8cf4e9]
V  [libjvm.so+0x8d2392]
C  [libjli.so+0x4abe]
C  [libjli.so+0x84ed]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  sgxUtils.SgxFunctions.jni_initialize_enclave(I[B)I+0
j  bftsmart.tom.ServiceReplica.initEnclave()V+248
j  bftsmart.tom.ServiceReplica.<init>(ILjava/lang/String;Lbftsmart/tom/server/Executable;Lbftsmart/tom/server/Recoverable;Lbftsmart/tom/server/RequestVerifier;Lbftsmart/tom/server/Replier;Lbftsmart/tom/util/KeyLoader;I)V+147
j  bftsmart.tom.ServiceReplica.<init>(ILbftsmart/tom/server/Executable;Lbftsmart/tom/server/Recoverable;I)V+17
j  bftsmart.demo.map.MapServer.<init>(II)V+35
j  bftsmart.demo.map.MapServer.main([Ljava/lang/String;)V+34
v  ~StubRoutines::call_stub

siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000020

Register to memory mapping:

RAX=0x0000000000000010 is an unknown value
RBX=0x00007f9f51ec7b43: <offset 0x0000000000076b43> in /lib/x86_64-linux-gnu/libc.so.6 at 0x00007f9f51e51000
RCX=0x000000000000000f is an unknown value
RDX=0x000000000000002f is an unknown value
RSP=0x00007f9f50718c28 is pointing into the stack for thread: 0x00007f9f4c012b40
RBP=0x00007f9f507191a0 is pointing into the stack for thread: 0x00007f9f4c012b40
RSI=0x00007f9f50719168 is pointing into the stack for thread: 0x00007f9f4c012b40
RDI=0x0000000000000020 is an unknown value
R8 =0x00000000ffffffff points into unknown readable memory: 00
R9 =0x0000000000000009 is an unknown value
R10=0x00007f9f50610099: <offset 0x0000000000007099> in /home/andrecruz/Tese/Con-BFT/build/install/library/lib/libSgx.so at 0x00007f9f50609000
R11=0x000000000000002f is an unknown value
R12=0x00007f9f5203e6a0: _IO_2_1_stdout_+0x0000000000000000 in /lib/x86_64-linux-gnu/libc.so.6 at 0x00007f9f51e51000
R13=0x00007f9f5061008f: <offset 0x000000000000708f> in /home/andrecruz/Tese/Con-BFT/build/install/library/lib/libSgx.so at 0x00007f9f50609000
R14=0x00007f9f507191b0 is pointing into the stack for thread: 0x00007f9f4c012b40
R15=0x0000000000000073 is an unknown value

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文