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


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <seccomp.h>
#include <errno.h>

// Функция для установки seccomp-фильтра
int apply_seccomp_filter() {
    scmp_filter_ctx ctx;
    
    // Создаём контекст с действием по умолчанию KILL (убивать процесс)
    ctx = seccomp_init(SCMP_ACT_KILL);
    if (ctx == NULL) {
        perror("seccomp_init");
        return -1;
    }
    
    // Разрешаем базовые системные вызовы, необходимые для работы C-программы
    
    // Основные syscall'ы для ввода/вывода и управления процессом
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0);      // Для malloc
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0);
    
    // Необходимы для работы динамического линковщика и открытия файлов
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(arch_prctl), 0); // Для TLS на x86_64
    
    // Для вывода в консоль (используется printf)
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 0);
    
    // Разрешаем доступ к /etc/ld.so.cache и другим служебным файлам
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getdents64), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(newfstatat), 0);
    
    // Иногда требуется при старте
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
    
    // Загружаем фильтр в ядро
    if (seccomp_load(ctx) < 0) {
        perror("seccomp_load");
        seccomp_release(ctx);
        return -1;
    }
    
    seccomp_release(ctx);
    return 0;
}

int main() {
    printf("До применения seccomp-фильтра\n");
    
    // Применяем фильтр
    if (apply_seccomp_filter() != 0) {
        fprintf(stderr, "Не удалось установить seccomp фильтр\n");
        return 1;
    }
    
    printf("Seccomp фильтр установлен. Разрешены только ограниченные syscall'ы.\n");
    
    // Тестируем разрешённые операции
    FILE *f = fopen("/etc/hostname", "r");
    if (f) {
        char buf[256];
        if (fgets(buf, sizeof(buf), f)) {
            printf("Прочитано из файла: %s", buf);
        }
        fclose(f);
    } else {
        perror("fopen");
    }
    
    // Эта строка отработает нормально, так как write разрешён
    printf("Завершаем работу\n");
    
    // Попытка запрещённого syscall'а (например, fork)
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork (должен упасть)");
    } else if (pid == 0) {
        printf("Дочерний процесс (не должен выполниться)\n");
    } else {
        wait(NULL);
    }
    
    return 0;
}