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;
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");
}
else if (child_pid > 0)
{
}
}
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