Score:0

When executing a compiled C/C++ file using seccomp and execve in the below code, it is exiting with status 159 and signal 31

mx flag

I'm trying to execute C/C++ code in a secure environment using Seccomp and Ececve. But, C/C++ code is not being executed while trying with this setup. Please look at the files.

seccomp_rules.c

#include <stdio.h>
#include <seccomp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h>

#include "seccomp_rules.h"


int c_cpp_seccomp_rules(struct config *_config, bool allow_write_file)
{

    int syscalls_whitelist[] = {SCMP_SYS(read), SCMP_SYS(fstat),
                                SCMP_SYS(mmap), SCMP_SYS(mprotect),
                                SCMP_SYS(munmap), SCMP_SYS(uname),
                                SCMP_SYS(arch_prctl), SCMP_SYS(brk),
                                SCMP_SYS(access), SCMP_SYS(exit_group),
                                SCMP_SYS(close), SCMP_SYS(readlink),
                                SCMP_SYS(sysinfo), SCMP_SYS(write),
                                SCMP_SYS(writev), SCMP_SYS(lseek),
                                SCMP_SYS(clock_gettime), SCMP_SYS(pread64)}; // add extra rule for pread64

    int syscalls_whitelist_length = sizeof(syscalls_whitelist) / sizeof(int);
    scmp_filter_ctx ctx = NULL;

    // /proc/sys/kernel/seccomp/actions_logged - Supposed to log here, but not logging???
    // ctx = seccomp_init(SCMP_ACT_LOG);
    ctx = seccomp_init(SCMP_ACT_KILL);

    if (!ctx)
    {
        return LOAD_SECCOMP_FAILED;
    }
    for (int i = 0; i < syscalls_whitelist_length; i++)
    {
        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls_whitelist[i], 0) != 0)
        {
            return LOAD_SECCOMP_FAILED;
        }
    }
    if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve), 1, SCMP_A0(SCMP_CMP_EQ, (scmp_datum_t)(_config->exe_path))) != 0)
    {
        return LOAD_SECCOMP_FAILED;
    }
    if (!allow_write_file)
    {
        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1, SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) != 0)
        {
            return LOAD_SECCOMP_FAILED;
        }
        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 1, SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) != 0)
        {
            return LOAD_SECCOMP_FAILED;
        }
    }
    else
    {
        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0) != 0)
        {
            return LOAD_SECCOMP_FAILED;
        }
        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(dup), 0) != 0)
        {
            return LOAD_SECCOMP_FAILED;
        }
        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(dup2), 0) != 0)
        {
            return LOAD_SECCOMP_FAILED;
        }
        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(dup3), 0) != 0)
        {
            return LOAD_SECCOMP_FAILED;
        }
    }

    if (seccomp_load(ctx) != 0)
    {
        return LOAD_SECCOMP_FAILED;
    }
    seccomp_release(ctx);
    return 0;
}

main.c

temp.c is a simple C file, temp is the C object file that I'm trying to execute in the project

#include <stdio.h>
#include <seccomp.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h>

#include "seccomp_rules.h"

int main()
{

    struct config _config;
    long orig_eax;
    _config.exe_path = "/home/ubuntu/runner/temp";
    _config.args[0] = _config.exe_path;
    _config.args[1] = NULL;
    _config.env[0] = "PATH=/usr/local/bin:/usr/bin:/bin";
    _config.env[1] = "LANG=en_US.UTF-8";
    _config.env[2] = "LANGUAGE=en_US:en";
    _config.env[3] = "LC_ALL=en_US.UTF-8";
    _config.env[4] = NULL;

    pid_t child_pid = fork();

    // pid < 0 shows clone failed
    if (child_pid < 0)
    {
        printf("FORK_FAILED");
    }
    else if (child_pid == 0)
    {
        c_cpp_seccomp_rules(&_config, true);
        execve(_config.exe_path, _config.args, _config.env);
        printf("execve failed\n");
    }
}

seccomp_rules.h

#ifndef SECCOMP_RULES_H
#define SECCOMP_RULES_H
#include <stdbool.h>
#include <sys/types.h>

#define LOAD_SECCOMP_FAILED -1;

struct config
{
    char *exe_path;
    char *args[20];
    char *env[20];
};

int c_cpp_seccomp_rules(struct config *_config, bool allow_write_file);

#endif // SECCOMP_RULES_H

CMakeLists.txt

cmake_minimum_required(VERSION 2.5)
# set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
# SET (CMAKE_C_COMPILER_WORKS 1)
# SET (CMAKE_CXX_COMPILER_WORKS 1)
project(Seccomp)

#set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/output)

set(CMAKE_C_FLAGS "-g -Wall -O3 -std=c99 -pie -fPIC")

file(GLOB SOURCE "./*.c")
add_executable(seccomp.so ${SOURCE})
target_link_libraries(seccomp.so pthread seccomp)


install(FILES output/seccomp.so
    PERMISSIONS OWNER_EXECUTE OWNER_READ
    DESTINATION /usr/lib/runner)

Put all these files in a folder and execute these commands.

  • cmake . && make

  • ./output/seccomp.so

muru avatar
us flag
How did you enable Seccomp in Ubuntu? Ubuntu uses AppArmor and it's not advisable to use both at the same time.
Vikram Ayaluri avatar
mx flag
@muru It's aws EC2 server - ubuntu 20
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.