Я разрабатываю грейдер для программирования конкурсов. В принципе, грейдер должен запускать программу решения в «изолированном» процессе. Поэтому я хотел бы, чтобы решение не вызывало каких-либо вредоносных системных вызовов (таких как system(), fork() и т. Д.). Могу ли я использовать ptrace() для достижения этого?UNIX ptrace() блокирует системные вызовы ребенка
ответ
Я думаю, что есть 2 возможных решения:
- Использование механизма LD_PRELOAD создать «подкладку», чтобы заменить системные вызовы вы хотите остановить.
-
Используйте setrlimit(), чтобы ограничить процесс вызова. К сожалению, эти ограничения кажутся для каждого пользователя, а не для каждого процесса, что делает вычисление правильного значения очень сложным.
EDIT: У меня есть первый вариант работы и включил в него необходимый код. Сборка бинарных файлов с помощью make all
, а затем проверить с make runtests
:
$ make all
gcc -fPIC -shared -Wl,-soname,libmy.so.1 -o libmy.so.1.0 lib.c
ln -sf libmy.so.1.0 libmy.so.1
ln -sf libmy.so.1 libmy.so
gcc -o test test.c
$ make runtests
Without LD_PRELOAD:
./test
in child: retval=9273
in parent: retval=0
With LD_PRELOAD:
LD_PRELOAD=./libmy.so ./test
libmy.so fork!
fork error: error=Operation not permitted (1)
Makefile:
all: libs test
runtests:
@echo Without LD_PRELOAD:
./test
@echo With LD_PRELOAD:
LD_PRELOAD=./libmy.so ./test
libs: lib.c
gcc -fPIC -shared -Wl,-soname,libmy.so.1 -o libmy.so.1.0 lib.c
ln -sf libmy.so.1.0 libmy.so.1
ln -sf libmy.so.1 libmy.so
test: test.c
gcc -o test test.c
clean:
rm -f test libmy.so.1.0 libmy.so.1 libmy.so lib.o
lib.c:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
pid_t fork()
{
printf("libmy.so fork!\n");
errno = EPERM;
return (pid_t)-1;
}
test.c:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(int argc, char **argv)
{
int retval = fork();
if (retval == 0)
printf("in parent: retval=%d\n", retval);
else if (retval > 0)
printf("in child: retval=%d\n", retval);
else
printf("fork error: error=%s (%d)\n", strerror(errno), errno);
return 0;
}
Да ты можешь использовать ptrace() для блокировки определенных системных вызовов с использованием параметра PTRACE_SYSCALL. Вот проект с использованием этой функции:
https://github.com/t00sh/p-sandbox/blob/master/p-sandbox.c
Если вы нацелены только на Linux, я хотел бы предложить Seccomp вместо этого, что более быстрый метод, в белый список/черный список некоторых системных вызовов или ограничить свои аргументы.
Альтернативой будет Native Client Google. Эти проекты обеспечивают кросс-платформенную реализацию изолированной программной среды приложения.
Вы также можете запускать приложения в качестве непривилегированного пользователя в контейнере, таком как докер или LXC, для ограничения ущерба.
Использование только LD_PRELOAD
небезопасно, так как исполняемый файл может поставляться со своей реализацией и отключать основной libc.
- 1. Системные вызовы в Unix
- 2. Неявные системные вызовы в командах UNIX
- 3. Как написать терминалу UNIX через системные вызовы?
- 4. Системные вызовы и системные программы
- 5. Это хороший способ перехватить системные вызовы?
- 6. Являются ли системные вызовы Unix/Linux частью функций библиотеки POSIX?
- 7. Системные вызовы Windows-программ
- 8. Системные вызовы, управляющие каталогами
- 9. Системные вызовы, сделанные KVM
- 10. Сборочные и системные вызовы
- 11. Системные вызовы C++ «SED»
- 12. Системные вызовы завершаются
- 13. Системные вызовы от php
- 14. Системные вызовы в Perl
- 15. Системные вызовы с c
- 16. windbg log системные вызовы
- 17. Системные вызовы в Windows
- 18. Системные вызовы труб
- 19. Системные процессы в Unix
- 20. некорневая ptrace/waitpid на не-ребенка
- 21. Какие системные вызовы не прерываются сигналом?
- 22. _exit(), fork() и waitpid() системные вызовы
- 23. Linux: Системные вызовы для кого
- 24. LTTng 2.0: системные вызовы sys_unknown
- 25. Дескрипторы файлов и системные вызовы
- 26. Как использовать системные вызовы C++
- 27. C Системные вызовы и сообщения
- 28. qtscript engine - делать системные вызовы
- 29. C системные вызовы, удалите файл
- 30. Как системные вызовы прерываются сигналом?
Спасибо, но можете ли вы объяснить немного больше о «механизме LD_PRELOAD»? – fushar
Если вы задали переменную среды $ LD_PRELOAD, указывающую на общую библиотеку, тогда эта библиотека будет использоваться по сравнению с теми, которые установлены в исполняемом файле. Я не знаю, работает ли он для функций системного уровня или нет. – trojanfoe
Хорошо, тогда второй вариант: какой ресурс в setrlimit() мне нужно установить для предотвращения системных вызовов? – fushar