Загрузка данных


#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <linux/filter.h>
#include <stddef.h>

int main() {
    // BPF программа: разрешаем только write и exit_group
    struct sock_filter filter[] = {
        // Загружаем номер системного вызова
        BPF_STMT(BPF_LD | BPF_W | BPF_ABS, 
                 offsetof(struct seccomp_data, nr)),
        
        // Если это write (номер 1) -> разрешить
        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 1, 0),
        
        // Если это exit_group (номер 231) -> разрешить  
        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 231, 1, 0),
        
        // Иначе - убить процесс
        BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS),
        
        // Разрешить syscall
        BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
    };
    
    struct sock_fprog prog = {
        .len = sizeof(filter) / sizeof(filter[0]),
        .filter = filter,
    };
    
    // Обязательно: запрещаем получение привилегий
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
        perror("prctl");
        return 1;
    }
    
    // Устанавливаем фильтр
    if (syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog) == -1) {
        perror("seccomp");
        return 1;
    }
    
    printf("Seccomp фильтр активен! Разрешены только write и exit_group\n");
    printf("Эта строка выведется (write разрешен)\n");
    
    // Пытаемся выполнить запрещенный syscall - процесс будет убит
    printf("Сейчас попробуем выполнить fork() - процесс будет убит\n");
    sleep(1);
    
    fork();  // Это убьет процесс
    
    // Сюда программа никогда не дойдет
    printf("Это сообщение никогда не появится\n");
    
    return 0;
}