Непоследовательное поведение 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 никогда не вызывается, как ожидалось.

Другие вопросы по тегам