name: "compiler explorer user execution sandbox"

mode: ONCE
hostname: "ce"

time_limit: 0

log_level: FATAL

rlimit_as_type: INF
rlimit_cpu_type: SOFT
rlimit_fsize: 16 # 16 MiB
rlimit_nofile: 100

uidmap {
    inside_id: "0"
}

gidmap {
    inside_id: "0"
}

detect_cgroupv2: true

# for cgroups v1:
# must run following as root during system startup
# cgcreate -a $USER:$USER -g memory,pids,cpu,net_cls:ce-sandbox
cgroup_mem_parent: "ce-sandbox"
cgroup_pids_parent: "ce-sandbox"
cgroup_net_cls_parent: "ce-sandbox"
cgroup_cpu_parent: "ce-sandbox"

cgroup_mem_max: 209715200 # 200 MiB
cgroup_pids_max: 14
cgroup_cpu_ms_per_sec: 500

# for cgroups v2:
# must run following as root during system startup
# cgcreate -a $USER:$USER -g memory,pids,cpu:ce-sandbox
# sudo chown $USER:root /sys/fs/cgroup/cgroup.procs
cgroupv2_mount: "/sys/fs/cgroup/ce-sandbox"

mount {
    src: "/lib"
    dst: "/lib"
    is_bind: true
}

mount {
    src: "/usr/lib"
    dst: "/usr/lib"
    is_bind: true
}

# To allow cctz to work
mount {
    src: "/usr/share/zoneinfo"
    dst: "/usr/share/zoneinfo"
    is_bind: true
}

# Might as well shitelist this (cc @apmorton #2095)
mount {
    src: "/etc/localtime"
    dst: "/etc/localtime"
    is_bind: true
}
mount {
    src_content: "ce:x:10240:10240:Not a real account:/app:/bin/bash"
    dst: "/etc/passwd"
    is_bind: true
}
mount {
    # this password hash is here intentionally, and is not actually used for anything
    src_content: "ce:$1$rockyou$hty8SH9lK4mcCQXKENxaa1:18723:0:99999:7:::"
    dst: "/etc/shadow"
    is_bind: true
}

mount {
    src: "/lib64"
    dst: "/lib64"
    is_bind: true
    mandatory: false
}

mount {
    src: "/lib32"
    dst: "/lib32"
    is_bind: true
    mandatory: false
}

mount {
    dst: "/tmp"
    fstype: "tmpfs"
    options: "size=20971520,nr_inodes=100" # 20 MiB
    rw: true
    noexec: true
    nodev: true
    nosuid: true
}

mount {
    dst: "/dev"
    fstype: "tmpfs"
}

mount {
    src: "/dev/null"
    dst: "/dev/null"
    rw: true
    is_bind: true
}

mount {
    src: "/dev/zero"
    dst: "/dev/zero"
    is_bind: true
}

mount {
    src: "/dev/urandom"
    dst: "/dev/random"
    is_bind: true
}

mount {
    src: "/dev/urandom"
    dst: "/dev/urandom"
    is_bind: true
}

###
# Support for stdbuf
mount {
    src: "/usr/bin/stdbuf"
    dst: "/usr/bin/stdbuf"
    is_bind: true
}
mount {
    src: "/usr/libexec/coreutils/libstdbuf.so"
    dst: "/usr/libexec/coreutils/libstdbuf.so"
    is_bind: true
}
###

###
# NVidia support
mount {
    src: "/dev/nvidia0"
    dst: "/dev/nvidia0"
    is_bind: true
    mandatory: false
}

mount {
    src: "/dev/nvidiactl"
    dst: "/dev/nvidiactl"
    is_bind: true
    mandatory: false
}

mount {
    src: "/dev/nvidia-modeset"
    dst: "/dev/nvidia-modeset"
    is_bind: true
    mandatory: false
}

mount {
    src: "/dev/nvidia-uvm"
    dst: "/dev/nvidia-uvm"
    is_bind: true
    mandatory: false
}
mount {
    src: "/dev/nvidia-uvm-tools"
    dst: "/dev/nvidia-uvm-tools"
    is_bind: true
    mandatory: false
}

mount {
  src: "/sys/module/nvidia"
  dst: "/sys/module/nvidia"
  is_bind: true
  mandatory: false
}

mount {
  src: "/sys/module/nvidia_uvm"
  dst: "/sys/module/nvidia_uvm"
  is_bind: true
  mandatory: false
}
# End NVidia support
###

mount {
    dst: "/proc"
    fstype: "proc"
    rw: true # Needed for NVidia driver
}

mount {
    src: "/opt/compiler-explorer"
    dst: "/opt/compiler-explorer"
    is_bind: true
}

mount {
    src: "/cefs"
    dst: "/cefs"
    is_bind: true
    # needed for cefs to see new mounts.
    # needs ce's patched nsjail to work
    # http://github.com/compiler-explorer/nsjail
    needs_mount_propagation: true
}

# Remove some sensitive stuff from execution
mount {
    dst: "/opt/compiler-explorer/sonar"
    fstype: "tmpfs"
}

# TODO: this is commented out per @apmorton's advice for now:
# kafel (the library nsjail uses) doesn't correctly handle non-native syscall architectures currently
# so if you compile/run a 32bit binary and apply a seccomp policy it incorrectly matches 32bit syscall numbers against
# your given policy which contains 64bit syscall numbers and things go sideways
#seccomp_string: "ALLOW {"
#seccomp_string: "    accept, accept4, access, acct, alarm, arch_prctl, bind, brk, capget, chdir, chmod, chown, clock_getres,"
#seccomp_string: "    clock_gettime, clock_nanosleep, clone, close, connect, copy_file_range, creat, dup, dup2,"
#seccomp_string: "    dup3, epoll_create, epoll_create1, epoll_ctl, epoll_ctl_old, epoll_pwait, epoll_wait,"
#seccomp_string: "    epoll_wait_old, eventfd, eventfd2, execve, execveat, exit, exit_group, faccessat, fadvise64,"
#seccomp_string: "    fallocate, fanotify_init, fanotify_mark, fchdir, fchmod, fchmodat, fchown, fchownat, fcntl,"
#seccomp_string: "    fdatasync, fgetxattr, flistxattr, flock, fork, fremovexattr, fsetxattr, fstatfs, fsync,"
#seccomp_string: "    ftruncate, futex, futimesat, getcpu, getcwd, getdents, getdents64, getegid, geteuid, getgid,"
#seccomp_string: "    getgroups, getitimer, get_mempolicy, getpeername, getpgid, getpgrp, getpid, getpmsg, getppid,"
#seccomp_string: "    getpriority, getrandom, getresgid, getresuid, getrlimit, get_robust_list, getrusage, getsid,"
#seccomp_string: "    getsockname, getsockopt, get_thread_area, gettid, gettimeofday, getuid, getxattr,"
#seccomp_string: "    inotify_add_watch, inotify_init, inotify_init1, inotify_rm_watch, io_cancel, io_destroy,"
#seccomp_string: "    io_getevents, ioprio_get, ioprio_set, io_setup, io_submit, kill, lchown, lgetxattr, link,"
#seccomp_string: "    linkat, listen, listxattr, llistxattr, lremovexattr, lseek, lsetxattr, madvise, mbind,"
#seccomp_string: "    membarrier, memfd_create, migrate_pages, mincore, mkdir, mkdirat, mknod, mknodat, mlock, mlock2,"
#seccomp_string: "    mlockall, mmap, modify_ldt, mount, move_pages, mprotect, mq_getsetattr, mq_notify, mq_open,"
#seccomp_string: "    mq_timedreceive, mq_timedsend, mq_unlink, mremap, msgctl, msgget, msgrcv, msgsnd, msync, munlock,"
#seccomp_string: "    munlockall, munmap, name_to_handle_at, nanosleep, newfstat, newfstatat, newlstat, newstat,"
#seccomp_string: "    newuname, open, openat, open_by_handle_at, pause, personality, pipe, pipe2, poll, ppoll, prctl,"
#seccomp_string: "    pread64, preadv, preadv2, prlimit64, pselect6, putpmsg, pwrite64, pwritev, pwritev2, quotactl,"
#seccomp_string: "    read, readahead, readlink, readlinkat, readv, recvfrom, recvmmsg, recvmsg, remap_file_pages,"
#seccomp_string: "    removexattr, rename, renameat, renameat2, rmdir, select, semctl, semget, semop, semtimedop,"
#seccomp_string: "    sendfile64, sendmmsg, sendmsg, sendto, setitimer, set_mempolicy, set_robust_list, setsockopt,"
#seccomp_string: "    set_thread_area, set_tid_address, setxattr, shmat, shmctl, shmdt, shmget, shutdown, sigaltstack,"
#seccomp_string: "    signalfd, signalfd4, socket, socketpair, splice, statfs, symlink, symlinkat, sync,"
#seccomp_string: "    sync_file_range, syncfs, sysctl, sysfs, sysinfo, tee, tgkill, time, timer_create, timer_delete,"
#seccomp_string: "    timerfd_create, timerfd_gettime, timerfd_settime, timer_getoverrun, timer_gettime, timer_settime,"
#seccomp_string: "    times, tkill, truncate, umask, umount, unlink, unlinkat, unshare, uselib, userfaultfd, ustat,"
#seccomp_string: "    utime, utimensat, utimes, vfork, vhangup, vmsplice, wait4, waitid, write, writev"
#seccomp_string: "}"
#seccomp_string: "DEFAULT LOG"
