Я должен предотвратить #include
любых файлов из системных каталогов по соображениям безопасности. Есть ли какие-то ограничения, которые могут помешать #include<...>
а также #include"..."
от включения небезопасных файлов, таких как #include </dev/tty>
или же #include "/dev/random"
?
Я прочитал главу о файлах заголовков Документы препроцессора C а также похожий вопрос Как запретить поиск по каталогу в текущем исходном файле? но не могу найти правильный способ сделать это.
поскольку -I-
Команда устарела, и нет другого способа выполнить ту же функцию. Могу ли я использовать jailkit для компиляции кода как пользователь с низким уровнем привилегий? Или есть другой способ обеспечить безопасность процесса компиляции?
godbolt.org решает аналогичную проблему путем запрещающие абсолютные и относительные пути в #include
s:
Входные данные:
#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
Других решений пока нет …