gramineproject / graphene

Graphene / Graphene-SGX - a library OS for Linux multi-process applications, with Intel SGX support
https://grapheneproject.io
GNU Lesser General Public License v3.0
771 stars 261 forks source link

Binary file identified as being non-PIE #2515

Closed Relyor closed 3 years ago

Relyor commented 3 years ago

Hello,

I am trying to run a C program which is mostly using libusb library.

include

include

include

include

define OUT_BULK_KINGSTON_ENDPOINT 0x02

define IN_BULK_KINGSTON_ENDPOINT 0x81

int main(void) { libusb_device **devs; int r; ssize_t cnt;

r = libusb_init(NULL);
if (r < 0) {
    printf("%s\n", libusb_error_name(r));
    return r;
}

cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0){
    libusb_exit(NULL);
    return (int) cnt;
}

printf("Hello\n");

for (size_t i = 0; i < cnt; ++i) {
    libusb_device *device = devs[i];
    struct libusb_device_descriptor desc;
    struct libusb_config_descriptor *config;
    libusb_device_handle *deviceHandle;

    r = libusb_get_device_descriptor(device, &desc);
    if (r < 0) {
        printf("%s\n", libusb_error_name(r));
        return r;
    }

    /* Check after Vendor ID 
     *  Kingston Technology - 0x0951
     *  HP, Inc - 0x03f0
     *     Samsung Electronics - 0x04e8
    **/
    if (desc.idVendor == 0x04e8) {

        /* Open device to perform I/O */
        r = libusb_open(device, &deviceHandle);
        if (r < 0) {
            printf("%s\n", libusb_error_name(r));
            return r;
        }

        if (desc.bNumConfigurations == 1) {
            r = libusb_get_config_descriptor(device, 0, &config);
            printf("  Configuration:\n");
            printf("    wTotalLength:            %u\n", config->wTotalLength);
            printf("    bNumInterfaces:          %u\n", config->bNumInterfaces);
            printf("    bConfigurationValue:     %u\n", config->bConfigurationValue);
            printf("    iConfiguration:          %u\n", config->iConfiguration);
            printf("    bmAttributes:            %02xh\n", config->bmAttributes);
            printf("    MaxPower:                %u\n", config->MaxPower);
        } else {
            printf("Multiple configurations found! Please select the right one!\n");
            return -1;
        }

        /* Iterate through interfaces */
        for (int j = 0; j < config->bNumInterfaces; ++j) {
            struct libusb_interface *interface = &config->interface[j];

            /* Select Alternate Setting for interface */
            if (interface->num_altsetting == 1) {
                const struct libusb_interface_descriptor *altsetting = &interface->altsetting[0];
                printf("    Interface:\n");
                printf("      bInterfaceNumber:      %u\n", altsetting->bInterfaceNumber);
                printf("      bAlternateSetting:     %u\n", altsetting->bAlternateSetting);
                printf("      bNumEndpoints:         %u\n", altsetting->bNumEndpoints);
                printf("      bInterfaceClass:       %u\n", altsetting->bInterfaceClass);
                printf("      bInterfaceSubClass:    %u\n", altsetting->bInterfaceSubClass);
                printf("      bInterfaceProtocol:    %u\n", altsetting->bInterfaceProtocol);
                printf("      iInterface:            %u\n", altsetting->iInterface);

                /* InterfaceClass = 7 (Printer) 
                 *  InterfaceClass = 8 (Mass Storage) 
                **/
                if (altsetting->bInterfaceClass == 7) {
                    int status, transferredData, receivedData, readBytes;
                    FILE *fp, *fw;
                    char buff[1024*1024];
                    char readBuff[1024];

                    if (libusb_kernel_driver_active(deviceHandle, j) == 1) {
                        printf("Kernel Driver Active\n");
                        if (libusb_detach_kernel_driver(deviceHandle, j) == 0)
                            printf("Kernel Driver Detached!\n");
                        else
                            printf("Couldn't detach kernel driver!\n");
                    }

                    r = libusb_claim_interface(deviceHandle, altsetting->bInterfaceNumber);
                    if (r < 0) {
                        printf("Claim Interface: %s\n", libusb_error_name(r));
                        return r;
                    }

                    fp = fopen("testpcl6.pcl", "r");
                    fw = fopen("written.pcl", "w");

                    while(!feof(fp)) {
                        readBytes = fread(&buff, 1, sizeof(buff), fp);
                        status = libusb_bulk_transfer(deviceHandle, OUT_BULK_KINGSTON_ENDPOINT, buff, readBytes, &transferredData, 60000);
                        if (status < 0) {
                            printf("%s\n", libusb_strerror(status));
                        }
                        printf("Bulk Transfer Status: %d\n", status);
                        printf("Data transferred: %d\n", transferredData);
                        // printf("ReadBytes: %d\n", readBytes);
                    }

                    fclose(fp);
                }

            } else {
                printf("Multiple altsettings found! Please select the right one!\n");
                return -1;
            }
        }
        libusb_free_config_descriptor(config);
        libusb_close(deviceHandle);
    }
}

libusb_exit(NULL);
return 0;

}

I am compiling the code using: gcc -Wall -fpie -o listdevs listdevs.c -I/usr/include/libusb-1.0 -lusb-1.0

When running the binary, in simulation mode using: ~/graphene/Runtime/pal_loader my_binary I'm getting the following:

error: Using insecure argv source. Graphene will continue application execution, but this configuration must not be used in production! [P9410:T1:gs] error: Failed to load . This may be caused by the binary being non-PIE, in which case Graphene requires a specially-crafted memory layout. You can enable it by adding 'sgx.nonpie_binary = 1' to the manifest. [P9410:T1:gs] error: Error during shim_init() in init_loader (-2)

Though, I have a PIE executable. I've checked with hardening-check tool to assure.

Any advise would be much appreciated!

Thanks!

dimakuv commented 3 years ago

First, you seem to be using a very old Graphene version. Please try with the latest master commit.

Second, libusb works with devices, doesn't it? Graphene currently doesn't support accesses to devices (other than pseudo-devices like /dev/null, /dev/random). So I don't think Graphene will work at all in your use case.

Relyor commented 3 years ago

Hi @dimakuv, thanks for the answer.

Is it possible to call all the libusb functions through some ECALLS and run the other part of my program over graphene? If yes, can I find a similar example on github?

dimakuv commented 3 years ago

@Relyor Currently this is not possible. We have plans for implementing such functionality, but this is rather long-term (6 months from now? I can't say).

dimakuv commented 3 years ago

Since there is nothing that can be done at the moment, and we are aware of the device support requests (but this will not happen soon), I'll close this issue.