Я отлаживаю ошибку сегментации в модуле php, написанном кем-то для приложения (поэтому об изменении рабочего процесса и других трудоемких операциях не может быть и речи).
У меня есть следующий код:
…
...some code...
int marker=0;
ENGINE_load_dynamic();
ENGINE *e=ENGINE_by_id("dynamic");
if (e==NULL) return NULL;
...some more code to set some parameters using ENGINE_ctrl_cmd_string(...)
marker++; // gets about 10 or something
e=ENGINE_by_id("pkcs11");
if (e==NULL) return NULL;
Здесь начинается самое интересное — SIGSEGV:
marker++; //11
if (!ENGINE_init(e)){
std::cout<<"..error..";
ENGINE_finish(e);
ENGINE_free(e);
ENGINE_cleanup();
return null;
}
...code using pkcs#11 token that does work....
Проблема появляется случайным образом, вроде. Фрагмент является частью модуля php. Сценарий вызывается из сценария PostgreSQL, который, в свою очередь, вызывается другим приложением php, находящимся на другом сервере (не вините меня за этот дизайн, я здесь для отладки). SIGSEGV появляется, когда я быстро обновляю основную страницу приложения php, что, как я полагаю, вызывает несколько раз одновременно вышеуказанные сценарии, поэтому я пытаюсь одновременно использовать токен из отдельных процессов.
Верны ли мои предположения? могут ли вызовы ENGINE_init / finish / free из отдельных процессов, использующих один и тот же токен, сталкиваться и вызывать ошибку сегментации?
Ошибка сегментации фиксируется с помощью моего обработчика, который выбирает значение маркера и печатает его перед выходом, это самый простой метод, который я мог найти для отладки sigsegv. Если этот метод может дать неправильные результаты, я буду признателен за уведомление.
Какие-нибудь мысли?
Есть README.ENGINE это обеспечивает обсуждение двигателей. Я не уверен, насколько это будет полезно, потому что он предъявляет высокие требования. Например, «… исходный код достаточно хорошо самодокументирован, но необходимы некоторые резюме и инструкции по использованию».
Но вот что-то на dynamic
:
Новый «динамический» ДВИГАТЕЛЬ обеспечивает простой способ поддержки
Реализации ENGINE, которые предварительно не скомпилированы и не связаны с
OpenSSL-приложения. Это может быть потому, что существующие
Скомпилированные реализации имеют известные проблемы, и вы хотите использовать
более новая версия с существующим приложением. Это также может быть
потому что приложение (или библиотека OpenSSL) вы используете просто
не поддерживает двигатель, который вы хотите использовать, и двигатель
поставщик (например, поставщик оборудования) предоставляет вам
Автономная реализация в форме разделяемой библиотеки.
другой вариант использования для «динамического» с приложениями, которые хотят
поддерживать минимально возможный отпечаток и не связывать
различные реализации двигателя из OpenSSL, но вместо этого оставляет вас
предоставить их, если вы хотите, в виде «динамически» загружаемых
разделяемая библиотека. Поставщики оборудования должны иметь возможность
предоставить свои собственные разделяемые библиотеки для поддержки произвольного оборудования
работать с приложениями на основе OpenSSL 0.9.7 или новее. Если вы
используя приложение на основе 0.9.7 (или более поздней версии) и поддержку, которую вы
Желание объявляется только для версий позже той, которая вам нужна,
попросите продавца зарегистрировать свой ДВИГАТЕЛЬ в нужной вам версии.Как работает «динамический»?
The dynamic ENGINE has a special flag in its implementation such that every time application code asks for the 'dynamic' ENGINE, it in fact gets its own copy of it. As such, multi-threaded code (or code that multiplexes multiple uses of 'dynamic' in a single application in any way at all) does not get confused by 'dynamic' being used to do many independent things. Other ENGINEs typically don't do this so there is only ever 1 ENGINE structure of its type (and reference counts are used to keep order). The dynamic ENGINE itself provides absolutely no cryptographic functionality, and any attempt to "initialise" the ENGINE automatically fails. All it does provide are a few "control commands"that can be used to control how it will load an external ENGINE implementation from a shared-library. To see these control commands, use the command-line; openssl engine -vvvv dynamic The "SO_PATH" control command should be used to identify the shared-library that contains the ENGINE implementation, and "NO_VCHECK"might possibly be useful if there is a minor version conflict and you (or a vendor helpdesk) is convinced you can safely ignore it. "ID" is probably only needed if a shared-library implements multiple ENGINEs, but if you know the engine id you expect to be using, it doesn't hurt to specify it (and this provides a sanity check if nothing else). "LIST_ADD" is only required if you actually wish the loaded ENGINE to be discoverable by application code later on using the ENGINE's "id". For most applications, this isn't necessary - but some application authors may have nifty reasons for using it. The "LOAD"command is the only one that takes no parameters and is the command that uses the settings from any previous commands to actually *load* the shared-library ENGINE implementation. If this command succeeds, the (copy of the) 'dynamic' ENGINE will magically morph into the ENGINE that has been loaded from the shared-library. As such, any control commands supported by the loaded ENGINE could then be executed as per normal. Eg. if ENGINE "foo" is implemented in the shared-library "libfoo.so" and it supports some special control command "CMD_FOO", the following code would load and use it (NB: obviously this code has no error checking); ENGINE *e = ENGINE_by_id("dynamic"); ENGINE_ctrl_cmd_string(e, "SO_PATH", "/lib/libfoo.so", 0); ENGINE_ctrl_cmd_string(e, "ID", "foo", 0); ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0); ENGINE_ctrl_cmd_string(e, "CMD_FOO", "some input data", 0); For testing, the "openssl engine" utility can be useful for this sort of thing. For example the above code excerpt would achieve much the same result as; openssl engine dynamic \ -pre SO_PATH:/lib/libfoo.so \ -pre ID:foo \ -pre LOAD \ -pre "CMD_FOO:some input data" Or to simply see the list of commands supported by the "foo" ENGINE; openssl engine -vvvv dynamic \ -pre SO_PATH:/lib/libfoo.so \ -pre ID:foo \ -pre LOAD Applications that support the ENGINE API and more specifically, the "control commands" mechanism, will provide some way for you to pass such commands through to ENGINEs. As such, you would select "dynamic"as the ENGINE to use, and the parameters/commands you pass would control the *actual* ENGINE used. Each command is actually a name-value pair and the value can sometimes be omitted (eg. the "LOAD" command). Whilst the syntax demonstrated in "openssl engine" uses a colon to separate the command name from the value, applications may provide their own syntax for making that separation (eg. a win32 registry key-value pair may be used by some applications). The reason for the "-pre" syntax in the "openssl engine" utility is that some commands might be issued to an ENGINE *after* it has been initialised for use. Eg. if an ENGINE implementation requires a smart-card to be inserted during initialisation (or a PIN to be typed, or whatever), there may be a control command you can issue afterwards to "forget" the smart-card so that additional initialisation is no longer possible. In applications such as web-servers, where potentially volatile code may run on the same host system, this may provide some arguable security value. In such a case, the command would be passed to the ENGINE after it has been initialised for use, and so the "-post" switch would be used instead. Applications may provide a different syntax for supporting this distinction, and some may simply not provide it at all ("-pre" is almost always what you're after, in reality).
Других решений пока нет …