2016-01-11 4 views
0

Скажем, мой кусок кода сканирует каталог ./plugins и загружает .dll S/.so S с известным символом («функции» здесь) для того, чтобы расширить свою functionnality, как это:Как я могу защитить загружаемые плагины?

main.c

#include <stdlib.h> 
#include <dirent.h> 
#include <string.h> 
#include <stdio.h> 
#include <dlfcn.h> 

int 
main(void) 
{ 
    DIR *dir; 
    struct dirent *entry; 
    dir = opendir("./plugins"); 
    if (dir == NULL) 
     return -1; 
    while ((entry = readdir(dir)) != NULL) 
    { 
     void *handle; 
     char path[PATH_MAX]; 
     int (*function)(char *); 
     if (strstr(entry->d_name, ".so") == NULL) 
      continue; 
     if (snprintf(path, sizeof(path), "./%s", entry->d_name) >= sizeof(path)) 
      continue; 
     handle = dlopen(path, RTLD_LAZY); 
     if (handle == NULL) 
      continue; // Better: report the error with `dlerror()' 
     function = (int (*)(char *)) dlsym(handle, "function"); 
     if (function != NULL) 
      fprintf(stdout, "function: %d\n", function("example")); 
     else 
      fprintf(stderr, "symbol-not-found: %s\n", entry->d_name); 
     dlclose(handle); 
    } 
    closedir(dir); 
    return 0; 
} 

Это может привести к серьезному вопросу безопасности: Если мое приложение работает как корень, или имеет право администратора, это означает, что любой непривилегированных злоумышленник может выполнить код в качестве привилегированного пользователя, производя общий объект, содержащий функцию с именем, как известный символ (h ere, function).

Что я могу сделать для защиты своей папки plugins? Как я могу проверить, безопасны ли загруженные объекты?

Это продолжение this question.

+0

Не могли бы вы объяснить, почему вы заботитесь о безопасности плагинов? –

+0

Это общая проблема. Безопасность должна иметь в виду каждый разработчик программного обеспечения, будь то безопасность его приложения или всей системы. Здесь вся система может быть взломана злоумышленником из-за моего кода. – Magix

+0

Но почему вы не доверяете плагину? –

ответ

2

Я считаю, что вы не можете защитить свой плагин в общем случае. Злоумышленник может делать произвольные вещи в своем плагине (включая испускание некоторого кода C во время выполнения, а затем форматирование его компиляции и dlopen -ing, JIT-компиляция машинного кода в памяти и т. Д.). Помните, что плагины dlopen -ed (или mmap -ed) делят virtual address spaceprocess с их программой загрузки.

Мои MELT [мета-] плагин для GCC компилятор делает именно это: генерировать C или код C++ во время выполнения компиляции на лету, dlopen -ную его. Но это не злой.

Обратите внимание, что (как answered by Art), dlopen(3) работают произвольный код инициализации плагина (перед тем вы любая dlsym получить функцию от его имени "function"). Читайте перевод информации о __attribute__((constructor)) in GCC.

Если вы чрезвычайно амбициозные (годы работы, стоит доктора философии ...) вы можете сгенерировать код плагина, делая код доказательства или звук static analysis на нем.

(Так вы похожи на меня, недалеко от Парижа, Франция, заглянуть в работах Xavier Leroy -INRIA- например CompCert, Эммануэль Chailloux -LIP6-, Юлия Lavall & Coccinelle -LIP6-, читайте также о Frama-C & GCC MELT; но понимаю, что есть no silver bullet ...., вы можете отправить мне по электронной почте, упоминая адрес вашего вопроса)

Читайте также о halting problem, Rice's theorem, trusted computing base и proof-carrying code. Ваш запрос undecidable или не менее intractable.

Вы могли бы рассмотреть некоторые двойной подход: есть доверенного процедуру в «знак» или «печать» хорошие плагин (так сисадмин отвечает говорить, что такой плагин хорошо), и только dlopen плагин когда он был «сертифицирован» или просто «одобрен человеком» каким-то образом. Может быть так же просто, как хранение (доверенная и безопасной) базы данных или текст ассоциации между доверенными именами плагин и их подписями md5, и вычислением контрольной суммы, то проверяя, что перед dlopen ...

Хороших эвристик при программировании, чтобы спросить очень часто к себе: пытаюсь ли я решить проблему остановки? J.Pitrat's blog имеет интересную информацию ....

+0

означает ли это, что каждый звонок на 'dlopen()' может привести к проблеме безопасности?! – Magix

+1

Да, конечно. Фактически, любой указатель функции уже является проблемой безопасности. –

+2

В качестве примечания, проверяющего, что каталог, содержащий плагины, принадлежит доверенному пользователю и группе и не доступен для записи в мире, а файл плагина также принадлежит как правило, достаточно доверенного пользователя и группы, а не для записи в мире, и имеет ровно одну жесткую ссылку, прежде чем открывать ее. По-прежнему подозревается в гонке. переименование родительского каталога (хотя вы можете попытаться смягчить это, также проверив все родительские каталоги). Однако большинство приложений (например, Apache) используют фиксированную доверенную (или «системную») директорию вместо этих проверок. –

3

Единственное, что вы можете сделать в этом случае, - это разрешить только привилегированному пользователю писать файлы в каталоге плагина.

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

Вы не можете проверить, находятся ли общие объекты в безопасности. Для этого было бы равнозначно решению проблемы остановки.

Смежные вопросы