2016-09-01 2 views
1

Из-за соображений безопасности я должен предотвратить #include любых файлов из системных каталогов. Существуют ли какие-либо ограничения, которые могут помешать #include<...> и #include"..." из-за небезопасных файлов, таких как #include </dev/tty> или #include "/dev/random"?Как предотвратить включение файлов из системных каталогов?

Я прочитал заголовок главы главы Docs of C Preprocessor, а также аналогичный вопрос How do I prevent a quoted include from searching the directory of the current source file?, но не могу найти правильный способ сделать это.

С -I- команда устарела, и нет другого способа, способного выполнить ту же функцию, можно ли использовать jailkit для компиляции кода как пользователя с низким уровнем привилегий? Или есть другой способ обеспечить безопасность процесса компиляции?

+8

Это не похоже на эффективный способ обеспечения безопасности. Если вы разрешаете пользователям компилировать свой собственный код, принудительное размещение вредоносного кода в исходных файлах вместо файлов заголовков не поможет. – Dmitri

+0

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

+0

Возможно, вы захотите просмотреть [Как запустить препроцессор только для локальных заголовков?] (Http://stackoverflow.com/questions/20889460/), чтобы убедиться, что простое управление тем, что находится в строках '# include', никоим образом не защищает вы не включаете файлы, которые вы не планировали включать. –

ответ

3

godbolt.org решает подобную проблему путем forbidding absolute and relative paths в #include сек:

Входной сигнал:

#include "/etc/passwd" 

Выход:

<stdin>:1:1: no absolute or relative includes please 
Compilation failed 

Это может быть достигнуто путем выполнения простой проверки на источниках, перед вызовом компилятора. Контроллер должен только grep для директив #include и проверить пути против нарушений таких ограничений. Предварительный вариант такого сценария (можно использовать с одного исходного файла) следующим образом:

check_includes:

#!/bin/bash 

if (($# != 1)) 
then 
    echo "Usage: $(basename "$0") source_file" 
    exit 1 
fi 

join_lines() 
{ 
    sed '/\\$/ {N;s/\\\n//;s/^/\n/;D}' "$1" 
} 

absolute_includes() 
{ 
    join_lines "$1"|grep '^\s*#\s*include\s*["<]\s*/' 
} 

relative_includes() 
{ 
    join_lines "$1"|grep '^\s*#\s*include'|fgrep '../' 
} 

includes_via_defines() 
{ 
    join_lines "$1"|grep '^\s*#\s*include\s*[^"< \t]' 
} 

show_and_count() 
{ 
    tee /dev/stderr|wc -l 
} 

exit_status=0 
if ((0 != $(absolute_includes "$1"|show_and_count))) 
then 
    echo 1>&2 "ERROR: $1 contains absolute includes" 
    exit_status=1 
fi 
if ((0 != $(relative_includes "$1"|show_and_count))) 
then 
    echo 1>&2 "ERROR: $1 contains relative includes" 
    exit_status=1 
fi 
if ((0 != $(includes_via_defines "$1"|show_and_count))) 
then 
    echo 1>&2 "ERROR: $1 contains includes via defines" 
    exit_status=1 
fi 
exit $exit_status 

Если предположить, что входной файл может быть скомпилирован без ошибок, этот скрипт идентифицирует #include S, которые содержат абсолютные или относительные пути. Он также обнаруживает включения, выполненные с помощью макроса, как показано ниже (это можно использовать для проверки пути):

#define HEADER "/etc/password" 
#include HEADER 
+0

Это может быть самый простой способ сделать это, но реализация кажется сложной. Есть ли какой-либо проект с открытым исходным кодом? –

+0

@FissureBlue Я считаю, что checker может быть реализован как простой скрипт bash. Я вскоре опубликую черновик, который работает для одного файла. – Leon

+0

Как насчет странной презентации кода? Может быть, нужна проверка регулярных выражений? –

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