add_seccomp.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package lib
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. "os"
  7. "strconv"
  8. "syscall"
  9. "unsafe"
  10. "github.com/langgenius/dify-sandbox/internal/static"
  11. sg "github.com/seccomp/libseccomp-golang"
  12. )
  13. //var allow_syscalls = []int{}
  14. func InitSeccomp() error {
  15. disabled_syscall, err := strconv.Atoi(os.Getenv("DISABLE_SYSCALL"))
  16. if err != nil {
  17. disabled_syscall = -1
  18. }
  19. ctx, err := sg.NewFilter(sg.ActKillProcess)
  20. if err != nil {
  21. return err
  22. }
  23. defer ctx.Release()
  24. // for i := 0; i < 400; i++ {
  25. // allow_syscalls = append(allow_syscalls, i)
  26. // }
  27. for _, syscall := range static.ALLOW_SYSCALLS {
  28. if syscall == disabled_syscall {
  29. continue
  30. }
  31. err = ctx.AddRule(sg.ScmpSyscall(syscall), sg.ActAllow)
  32. if err != nil {
  33. return err
  34. }
  35. }
  36. reader, writer, err := os.Pipe()
  37. if err != nil {
  38. return err
  39. }
  40. defer reader.Close()
  41. defer writer.Close()
  42. file := os.NewFile(uintptr(writer.Fd()), "pipe")
  43. ctx.ExportBPF(file)
  44. // read from pipe
  45. data := make([]byte, 4096)
  46. n, err := reader.Read(data)
  47. if err != nil {
  48. return err
  49. }
  50. // load bpf
  51. sock_filters := make([]syscall.SockFilter, n/8)
  52. bytesBuffer := bytes.NewBuffer(data)
  53. err = binary.Read(bytesBuffer, binary.LittleEndian, &sock_filters)
  54. if err != nil {
  55. return err
  56. }
  57. bpf := syscall.SockFprog{
  58. Len: uint16(len(sock_filters)),
  59. Filter: &sock_filters[0],
  60. }
  61. _, _, err2 := syscall.RawSyscall6(syscall.SYS_PRCTL, syscall.PR_SET_SECCOMP, 2, uintptr(unsafe.Pointer(&bpf)), 0, 0, 0)
  62. if err2 != 0 {
  63. return fmt.Errorf("prctl failed: %v", err2)
  64. }
  65. return nil
  66. }