Некоторое время назад я задал несколько вопросов о разработке сетевого судьи по stackoverflow, и я нашел немало хороших ответов на это. Я начал работать над его созданием и, похоже, столкнулся с серьезным недостатком в моем коде.
Отправленный пользователем источник будет скомпилирован на сервере. Это делается с помощью exec () gcc в разветвленном процессе. Теперь я установил лимит ресурсов на процессорное время и при превышении этого, сигнал SIGXCPU отправляется в процесс. Все хорошо до сих пор. Но предположим, что кто-то пишет вредоносный код, который обрабатывает сам код SIGXCPU, затем он продолжит работу на сервере и, возможно, откроет для кого-то возможность удаленного управления сервером.
Так чего мне здесь не хватает? Должно быть, так или иначе это можно предотвратить.
Базовый прототип модуля компиляции выглядит так:
int main()
{
int pid;
int rv;
if (!( pid=fork() ))
{
struct rlimit limit;
getrlimit(RLIMIT_CPU, &limit);
limit.rlim_cur = 1;
setrlimit(RLIMIT_CPU, &limit);
//execl() with gcc and source file name
}
else if(pid)
{
wait(&rv);
}
else
printf("Error forking\n");
return 0;
}
и если исходный файл содержит что-то вроде
void handler(int signum)
{
if (signum == SIGXCPU)
printf("Caught SIGXCPU signal\n");
}
int main()
{
signal(SIGXCPU, handler);
while(1);
return 0;
}
... это большая проблема