Передача вектора в анклав в Intel SGX

У меня есть vector<vector <string>> a; Как я мог передать его анклаву? Как я объявляю функцию edl. Очень ценится пример объявления функции для приложения, edl и анклава.

Мне известно об этом: Аргументы C++ для функций SGX Enclave Edge.

Образец, чтобы пройти даже vector<string>, для меня в порядке.

update1: я придумал это:

App.cpp

const char *convert(const std::string & s)
{
   return s.c_str();
}

vector<string> members_data;
member_data.push_back("apple");
member_data.push_back("orange"); //just for sample

    std::vector<const char*>  vc;
    std::transform(members_data.begin(), members_data.end(), std::back_inserter(vc), convert);

Эдл:

trusted {
       public void ecall_receive_vector([in, size=len] const char **arr, size_t len);
};

анклав

void ecall_receive_vector(const char *arr[], size_t len)
{
    vector<string> v(arr, arr+len);

    printf("%s\n", v[2].c_str());

}

Но анклав не получает никаких данных, программа компилируется отлично, без ошибок. Может ли кто-нибудь помочь? printf — это образец вызова.


person Roshan Mehta    schedule 19.02.2018    source источник
comment
И какие у вас проблемы с реализацией того, на что намекает ответ на этот другой вопрос?   -  person Antti Haapala    schedule 19.02.2018
comment
Не могу понять намек.   -  person Roshan Mehta    schedule 19.02.2018
comment
Не могли бы вы предоставить код вызывающего абонента?   -  person asonnino    schedule 20.04.2018
comment
Принятый ответ правильный.   -  person Roshan Mehta    schedule 20.04.2018
comment
да, но у меня есть похожая проблема, которую я пытаюсь выяснить (это поможет мне)   -  person asonnino    schedule 20.04.2018
comment
Разместите свой вопрос, поделитесь ссылкой на вопрос здесь.   -  person Roshan Mehta    schedule 20.04.2018


Ответы (1)


В EDL используйте count вместо size.

trusted {
    public void ecall_receive_vector([in, count=len] const char **arr, size_t len);
};

Вы передаете двойной указатель, это указатель на указатель на char (char **).

При маршалировании/демаршалинге указателей процессор EDL обрабатывает (копирует и проверяет ввод и вывод) только первый уровень косвенности, разработчик должен обрабатывать дополнительные уровни косвенности. Следовательно, для массива указателей он будет копировать только первый массив указателей, а не указанные значения, их копирование является обязанностью разработчика.

Если не указано, count и size по умолчанию равны 1 и sizeof(<pointed-type>) соответственно. В вашем случае size = sizeof(<pointer>), что на большинстве платформ равно 4.

В вашем случае вы предоставили только size. Поскольку вы не предоставляете код вызывающего абонента, я предполагаю, что вы передаете длину строки, и, поскольку count не было указано, по умолчанию используется значение 1. Тогда общее количество байтов, основанное на Total number of bytes = count * size, будет 1 * len, что неверно.

Использование только count позволит size по умолчанию иметь значение sizeof(<pointed-type>), тогда Total number of bytes = count * size будет count * sizeof(<pointed-type>), что правильно, потому что вы передаете массив указателей.

Чтобы закрыть, находясь внутри анклава, вам нужно скопировать данные указателей, поскольку эти указатели находятся за пределами анклава, это можно сделать автоматически, назначив их std::string.


Из документации Intel SGX SDK:

Обработка указателей (последний абзац )

Вы можете использовать атрибут направления, чтобы обменять защиту на производительность. В противном случае вы должны использовать атрибут user_check, описанный ниже, и проверять данные, полученные из ненадежной памяти с помощью указателей, перед их использованием, поскольку память, на которую указывает указатель, может неожиданно измениться, поскольку она хранится в ненадежной памяти. Однако атрибут направления не помогает со структурами, содержащими указатели. В этом сценарии разработчики должны сами проверять и копировать содержимое буфера, при необходимости рекурсивно.

А также,

Расчет размера буфера

Обобщенная формула для расчета размера буфера с использованием этих атрибутов:

Total number of bytes = count * size

  • Вышеупомянутая формула верна, когда указаны и count, и size/sizefunc.
  • size может быть задан атрибутом size или sizefunc.
  • Если для параметра указателя не указано count, то предполагается, что он равен 1, т. е. count=1. Тогда общее количество байтов равно size/sizefunc.
  • Если size не указано, то размер буфера рассчитывается по приведенной выше формуле, где size равно sizeof (element pointed by the pointer).
person ruizpauker    schedule 27.02.2018
comment
Не могли бы вы немного объяснить, почему это имеет значение, если я напишу len вместо size? - person Roshan Mehta; 27.02.2018
comment
Это не len, это count. len — это имя используемой вами переменной. - person ruizpauker; 01.03.2018
comment
Вы хотите передать двойной указатель Что вы предлагаете передать в этом новом аргументе? - person Lightness Races in Orbit; 01.03.2018
comment
Я имел в виду «вы проходите», исправлено! - person ruizpauker; 01.03.2018