main.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "os/exec"
  6. "strconv"
  7. "strings"
  8. "sync"
  9. "github.com/langgenius/dify-sandbox/internal/static/python_syscall"
  10. )
  11. const (
  12. SYSCALL_NUMS = 500
  13. )
  14. var (
  15. total_rans = 0
  16. total_rans_lock = sync.Mutex{}
  17. )
  18. func run(allowed_syscalls []int) error {
  19. total_rans_lock.Lock()
  20. total_rans++
  21. total_rans_lock.Unlock()
  22. nums := []string{}
  23. for _, syscall := range allowed_syscalls {
  24. nums = append(nums, strconv.Itoa(syscall))
  25. }
  26. os.Setenv("ALLOWED_SYSCALLS", strings.Join(nums, ","))
  27. cmd := exec.Command("python3", "cmd/test/fuzz_python_amd64/test.py")
  28. cmd.Stderr = os.Stderr
  29. _, err := cmd.Output()
  30. if err == nil {
  31. return nil
  32. } else {
  33. return err
  34. }
  35. }
  36. func find_syscall(syscall int, syscalls []int) int {
  37. for i, s := range syscalls {
  38. if s == syscall {
  39. return i
  40. }
  41. }
  42. return -1
  43. }
  44. func fuzz_range(r []int) bool {
  45. original := python_syscall.ALLOW_SYSCALLS
  46. original = append(original, python_syscall.ALLOW_NETWORK_SYSCALLS...)
  47. // generate task list
  48. list := make([][]int, 10)
  49. for i := 0; i < 10; i++ {
  50. list[i] = make([]int, len(original))
  51. copy(list[i], original)
  52. for _, j := range r {
  53. if find_syscall(j, list[i]) == -1 {
  54. list[i] = append(list[i], j)
  55. }
  56. }
  57. }
  58. lock := sync.Mutex{}
  59. wg := sync.WaitGroup{}
  60. i := 0
  61. // run 4 tasks concurrently
  62. failed := false
  63. for j := 0; j < 4; j++ {
  64. wg.Add(1)
  65. go func() {
  66. defer wg.Done()
  67. for {
  68. lock.Lock()
  69. if i >= len(list) {
  70. lock.Unlock()
  71. return
  72. }
  73. task := list[i]
  74. i++
  75. lock.Unlock()
  76. if run(task) != nil {
  77. failed = true
  78. // stop all tasks
  79. lock.Lock()
  80. i = len(list)
  81. lock.Unlock()
  82. }
  83. }
  84. }()
  85. }
  86. // wait for all tasks to finish
  87. wg.Wait()
  88. return !failed
  89. }
  90. func fuzz() {
  91. unnecessary_syscalls := []int{}
  92. for i := 0; i < SYSCALL_NUMS; i++ {
  93. // remove syscall
  94. fmt.Println(i)
  95. nr := []int{}
  96. for j := 0; j < SYSCALL_NUMS; j++ {
  97. // skip i and unnecessary syscalls
  98. if i != j && find_syscall(j, unnecessary_syscalls) == -1 &&
  99. find_syscall(j, python_syscall.ALLOW_SYSCALLS) == -1 &&
  100. find_syscall(j, python_syscall.ALLOW_NETWORK_SYSCALLS) == -1 {
  101. nr = append(nr, j)
  102. }
  103. }
  104. if fuzz_range(nr) {
  105. unnecessary_syscalls = append(unnecessary_syscalls, i)
  106. } else {
  107. fmt.Printf("syscall %d is necessary\n", i)
  108. }
  109. }
  110. }
  111. func main() {
  112. fuzz()
  113. fmt.Printf("Total rans: %d\n", total_rans)
  114. }