Непоследовательное поведение seccomp
Я работаю над созданием различных приложений, использующих seccomp для Linux, и попал в несоответствие, которое не могу объяснить.
Я попытался дать вам примеры, достаточно ясные, чтобы воспроизвести проблему.
Я создаю "модуль защиты", который запрещает вызов процесса set_robust_list
(ради демонстрации проблемы). Затем я запускаю процессы, в которых я внедряю этот "модуль защиты", используя LD_PRELOAD, и ожидаю, что процесс остановится, когда будет выполнен этот системный вызов.
Я делаю общий объект на основе этого кода:
#include <seccomp.h>
#include <sys/prctl.h>
static void __attribute__((constructor)) Initialization(void) {
scmp_filter_ctx ctx;
prctl(PR_SET_NO_NEW_PRIVS, 1);
ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(set_robust_list), 0);
seccomp_load(ctx);
}
Я строю это с gcc -shared seccompdemo.c -lseccomp -o libseccompdemo.so
,
Затем, чтобы проверить это, я создаю этот исполняемый файл:
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
int main() {
syscall(SYS_set_robust_list,0,0);
return 0;
}
Я строю это с gcc set_robust_list.c -o set_robust_list
,
Затем, как и ожидалось, я запускаю этот исполняемый файл с помощью вышеупомянутого, и он убивается сигналом:
$ LD_PRELOAD=./libseccompdemo.so ./set_robust_list
Bad system call (core dumped)
Проблема в том, когда я пытаюсь сделать то же самое с Java.
Я вызываю тот же "модуль протектора" на Java, он не работает, несмотря на то, что я знаю, что Java вызывает set_robust_list
от strace:
$ LD_PRELOAD=./libseccompdemo.so java FileWriterTest /tmp/hosts < /etc/hosts
$ echo $?
0
Посмотрите, что вывод strace доказывает, что Java вызывает 'set_robust_list':
$ strace -f java FileWriterTest /tmp/hosts < /etc/hosts 2>&1 | grep set_robust_list
set_robust_list(0x7f0b168af660, 24) = 0
[pid 12847] set_robust_list(0x7f0b168ad9e0, 24 <unfinished ...>
[pid 12847] <... set_robust_list resumed> ) = 0
[pid 12848] set_robust_list(0x7f0b12b259e0, 24) = 0
Я вижу, что вызовы Java clone
Системный вызов по существу для создания потоков. Я подумал, что фильтры seccomp не наследуются, но согласно документации они есть.
Я был бы очень рад, если бы кто-то мог объяснить мне, почему это не работает.
Для справки вот код Java:
import java.io.FileOutputStream;
import java.io.IOException;
public class FileWriterTest {
public static void main(String[] args) {
try {
FileOutputStream f = new FileOutputStream(args[0]);
f.write(System.in.readAllBytes());
}
catch (IOException e) {
System.out.format("Caught exception: "+e.toString());
}
}
}
1 ответ
Тот Bad system call (core dumped)
сообщение - это ваша оболочка, сообщающая, что дочерний процесс завершился из-за SIGSYS
сигнал. Но если SIGSYS
заблокирован, системный вызов просто вернет ошибку, которая будет обработана в зависимости от приложения.
я думаю что pthread_create
блокирует сигналы во время выполнения и, следовательно, set_robust_list
вызывается только с SIGSYS
заблокирован, в отличие от вашего примера кода, который не изменяет маску сигнала.
В любом случае, это не должно влиять на то, что вы пытаетесь достичь: System.out.println("Hello from Java!");
к твоей яве main
и вы увидите, что он не будет печататься, если вы предварительно загрузите фильтры segcomp, потому что main
никогда не вызывается, как ожидалось.