4

I am trying to run the following code in order to enable SGX in my machine (BIOS: software controlled):

//enable_device.c
#include "stdio.h"
#include "sgx_capable.h"
#include "sgx_eid.h"
#include "sgx_urts.h"
#include "sgx_error.h"

int main(void) {
        sgx_device_status_t sgx_device_status;
        sgx_status_t ret;

        ret = sgx_cap_enable_device(&sgx_device_status);

        if(ret == SGX_SUCCESS) {
                switch(sgx_device_status) {
                        case SGX_ENABLED:
                                printf("The platform is enabled for Intel SGX.\n$
                                break;
                        case SGX_DISABLED_REBOOT_REQUIRED:
                                printf("This platform is disabled for Intel SGX.$
                                break;
                        case SGX_DISABLED_MANUAL_ENABLE:
                                printf("The platform is disabled for Intel SGX b$
                                break;
//                      case SGX_DISABLED_HYPERV_ENABLED:
//                              printf("The detected version of Windows* 10 is i$
//                              break;
                        case SGX_DISABLED_LEGACY_OS:
                                printf("The operating system does not support UE$
                                break;
                        case SGX_DISABLED_UNSUPPORTED_CPU:
                                printf("Intel SGX is not supported by this proce$
                                break;
                        case SGX_DISABLED:
                                printf("This platform is disabled for Intel SGX.$
                                break;
                        default:
                                printf("UNKNOWN RESPONSE\n");
                }
        } else {
                switch(ret) {
                        case SGX_ERROR_INVALID_PARAMETER:
                                printf("The sgx_device_status pointer is invalid$
                                break;
                        case SGX_ERROR_NO_PRIVILEGE:
                                printf("The application does not have the requir$
                                break;
//                      case SGX_ERROR_HYPERV_ENABLED:
//                              printf("The detected version of Windows* 10 is i$
//                              break;
                        default:
                                printf("An unexpected error is detected.\n");
                }
        }

        return 0;
}

Here is the Makefile I am using:

######### SGX TOOLS ######################
SGX_SDK := /usr/local/lib/intel/sgxsdk
SGX_LIBRARY_PATH := $(SGX_SDK)/lib64

######## App Settings ########
App_C_Files := enable_device.c
App_C_Flags := -fPIC -Wno-attributes -IInclude -IApp -I$(SGX_SDK)/include
App_Cpp_Flags := $(App_C_Flags) -std=c++11
App_Link_Flags := -L$(SGX_LIBRARY_PATH) -lsgx_capable
App_C_Objects := $(App_C_Files:.c=.o)
App_Name := app

.PHONY: all run

all: $(App_Name)

run: all

######## App Objects ########

enable_device.o: enable_device.c
        @$(CC) $(App_C_Flags) -c $< -o $@

$(App_Name): enable_device.o
        @$(CC) $^ -o $@ $(App_Link_Flags)

.PHONY: clean

clean:
        @rm -f $(App_Name) $(App_C_Objects)

When I run the application, I receive this message:

The application does not have the required privileges to read an EFI variable. Run the application with the administrator privileges to enable the Intel SGX device status.

Then, I run sudo ./app and receive the following error:

./app: error while loading shared libraries: libsgx_capable.so: cannot open shared object file: No such file or directory

The strange thing is that this library is not being found when compiling:

$ldd app 
linux-vdso.so.1 (0x00007ffe065bc000)
libsgx_capable.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f15a060d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f15a0c01000)

Then, I use:

export LD_LIBRARY_PATH=/usr/local/lib/intel/sgxsdk/lib64/

I run again and the same error message returns. Can anyone tell what I am missing?

Dalton Cézane
  • 3,672
  • 2
  • 35
  • 60

1 Answers1

6

The strange thing is that this library is not being found when compiling.

It is being found when compiling (actually, when linking). Otherwise the linkage of app would fail and it would not exist. The ldd app output:

libsgx_capable.so => not found

shows that the linker found libsgx_capable.so, and duly wrote a NEEDED entry for it in the .dynamic section of app, which ldd - invoking the runtime loader - attempts resolve to an actual file, and cannot resolve because the loader cannot now find libsgx_capable.so in any of the directories where it always looks:

  1. The LD_LIBRARY_PATH directories
  2. The ldconfig cache directories listed in /etc/ld.so.conf
  3. The trusted directories /lib and /usr/lib

That is because /usr/local/lib/intel/sgxsdk/lib64/ is not one of directories 2 or 3 and is not one of directories 1 at the moment when you run ldd app.

You say that app requires root privilege and you run it with sudo ./app, but even when you execute:

$ export LD_LIBRARY_PATH=/usr/local/lib/intel/sgxsdk/lib64/
$ sudo ./app

you still encounter:

./app: error while loading shared libraries: libsgx_capable.so: cannot open shared object file: No such file or directory

This happens because the sudo command does not by default pass the environment in which it is called to the commands that it executes as root. See:

$ cat main.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char const *foobar = getenv("FOOBAR");
    printf("FOOBAR=[%s]\n",foobar ? foobar : "<null>");
    return 0;
}

$ gcc -Wall -o prog main.c
$ export FOOBAR=foobar
$ ./prog
FOOBAR=[foobar]
$ sudo ./prog
FOOBAR=[<null>]

To transmit environment settings through sudo you can pass them as parameters to sudo:

$ sudo FOOBAR=barfoo ./prog
FOOBAR=[barfoo]
$ echo $FOOBAR
foobar

or you can give the option -E to sudo:

$ sudo -E ./prog
FOOBAR=[foobar]

So either:

$ sudo LD_LIBRARY_PATH=/usr/local/lib/intel/sgxsdk/lib64/ ./app

or:

$ export LD_LIBRARY_PATH=/usr/local/lib/intel/sgxsdk/lib64/
$ sudo -E ./app

will work. You may prefer however not to depend on LD_LIBRARY_PATH to let app load libsgx_capable.so at runtime. In that case you can get it into the ldconfig cache by running:

$ sudo ldconfig /usr/local/lib/intel/sgxsdk/lib64/

which will cache any shared libraries in /usr/local/lib/intel/sgxsdk/lib64/ for the loader.

Or, if you would rather keep your ldconfig cache as your distro defined it, you can just change:

App_Link_Flags := -L$(SGX_LIBRARY_PATH) -lsgx_capable

to:

App_Link_Flags := -L$(SGX_LIBRARY_PATH) -lsgx_capable -Wl,-rpath=$(SGX_LIBRARY_PATH)

in your makefile. That will make the linker add a RUNPATH entry to the .dynamic section in app prompting the loader to search /usr/local/lib/intel/sgxsdk/lib64/ for needed libraries after directories 1 and before directories 2 and 3.

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182