Open colek42 opened 1 year ago
I think the best way forward is going to be to use user namespaces and SEComp
package main
// #include <stdlib.h>
// #include <seccomp.h>
import "C"
import (
"fmt"
"os/exec"
"unsafe"
)
func main() {
// Define the policy rules
rules := []string{
"open",
"close",
"read",
"write",
"exit",
}
// Create a new SEComp filter
filter, err := C.seccomp_init(C.SCMP_ACT_ALLOW)
if err != nil {
fmt.Println("Error initializing seccomp:", err)
return
}
// Add rules to the filter
for _, rule := range rules {
syscallNr := C.int(C.__NR_##rule)
if _, err := C.seccomp_rule_add(filter, C.SCMP_ACT_ALLOW, syscallNr, 0); err != nil {
fmt.Println("Error adding seccomp rule:", err)
return
}
}
// Load the filter into the kernel
if _, err := C.seccomp_load(filter); err != nil {
fmt.Println("Error loading seccomp filter:", err)
return
}
// Execute the command with the SEComp filter applied
cmd := exec.Command("/bin/bash", "-c", "echo 'Hello, world!'")
cmd.SysProcAttr = &syscall.SysProcAttr{
Seccomp: &syscall.SockFilter{
Len: uint16(filter.len),
Filter: (*syscall.SockFilterElem)(unsafe.Pointer(filter.filter)),
},
}
if err := cmd.Run(); err != nil {
fmt.Println("Error running command:", err)
return
}
}
Possible filters.
Restrict access to network resources Restrict access to system files and directories Prevent process from creating or modifying files outside of a specific directory Prevent process from executing other processes Limit the amount of CPU and memory resources that the process can use Limit the use of system calls to a whitelist of allowed calls Restrict access to kernel modules Restrict access to specific system devices Restrict access to inter-process communication mechanisms (e.g. sockets, pipes, signals) Prevent process from changing its UID or GID Restrict access to shared memory regions Restrict access to system configuration files (e.g. /etc/passwd, /etc/shadow) Restrict access to sensitive environment variables (e.g. PATH, LD_LIBRARY_PATH) Restrict access to system logs Restrict access to the proc file system Restrict access to system calls related to time manipulation (e.g. gettimeofday, settimeofday) Restrict access to system calls related to process control (e.g. fork, clone, exec) Prevent process from binding to privileged ports (i.e. ports below 1024) Restrict access to system calls related to signal handling (e.g. sigaction, sigprocmask) Restrict access to system calls related to file system manipulation (e.g. mount, umount)
https://github.com/containers/common/tree/main/pkg/seccomp seems to provide a pure go implementation
I'm a bit confused -- is this issue referring to our builds or builds that Witness observes? If the latter I'm not sure if we will have all the info necessary to create seccomp rules for any arbitrary command.
The ones that witness observes. Most of the items in the list above could be done. We will have to have some config flags to set though.
Currently, our sandboxing is weak and does not meet the requirements for SLSA level 3/4 attestations. To improve our security posture, we should implement SEComp for sandboxing on Linux.
SEComp provides an additional layer of protection by allowing us to restrict a process's access to system resources based on its label. This ensures that the build process cannot tamper with the build observer.
We need to research and implement SEComp rules to restrict the build runner's access to only necessary system resources. This will prevent any unauthorized access or modification of the system and ensure that our build process is secure.
Once we have implemented SEComp for Linux, we can investigate similar options for Windows.