Переглянути джерело

add faq for 2 common issues and add tool to quickly figure out required syscalls (#17)

* fix(python): temp solution to import numpy and pydantic

* fix(python): temp solution to import numpy and pydantic

* fix(python): temp solution to import numpy and pydantic

* feat(test): add test cmd to figure out which syscalls are required by your python code

* feat(test): rollback output_capture changes

* feat(test): add test cmd to figure out which syscalls are required by your python code

* feat(test): add test cmd to figure out which syscalls are required by your python code

* feat(test): remove unnecessary docs in FAQ

---------

Co-authored-by: dafang <fangyufeng@bzy.ai>
Wyatt Fang 1 рік тому
батько
коміт
49a1826eda
5 змінених файлів з 225 додано та 0 видалено
  1. 107 0
      FAQ.md
  2. 5 0
      README.md
  3. 6 0
      cmd/test/syscall_dig/README.md
  4. 61 0
      cmd/test/syscall_dig/main.go
  5. 46 0
      cmd/test/syscall_dig/test.py

Різницю між файлами не показано, бо вона завелика
+ 107 - 0
FAQ.md


+ 5 - 0
README.md

@@ -17,3 +17,8 @@ DifySandbox currently only supports Linux, as it's designed for docker container
 4. Run ./main to start the server.
 
 If you want to debug the server, firstly use build script to build the sandbox library binaries, then debug as you want with your IDE.
+
+
+## FAQ
+
+Refer to the [FAQ document](FAQ.md)

+ 6 - 0
cmd/test/syscall_dig/README.md

@@ -0,0 +1,6 @@
+## How to use
+
+- edit the `test.py` code, add what python code you want to test
+- then run: `go run cmd/test/syscall_dig/main.go` to get the required syscalls
+
+If you want to check the syscall name by its number, you can run: `ausyscall ${syscall number}`. `ausyscall` is the cmd from `auditd` service.

+ 61 - 0
cmd/test/syscall_dig/main.go

@@ -0,0 +1,61 @@
+package main
+
+import (
+	"fmt"
+	"os"
+	"os/exec"
+	"strconv"
+	"strings"
+)
+
+const (
+	SYSCALL_NUMS = 500
+)
+
+func run(allowed_syscalls []int) error {
+	nums := []string{}
+	for _, syscall := range allowed_syscalls {
+		nums = append(nums, strconv.Itoa(syscall))
+	}
+	os.Setenv("ALLOWED_SYSCALLS", strings.Join(nums, ","))
+	_, err := exec.Command("python3", "cmd/test/syscall_dig/test.py").Output()
+	if err == nil {
+	} else {
+		failed_msg := fmt.Sprintf("failed with %v", err)
+		fmt.Println(failed_msg)
+	}
+
+	return err
+}
+
+func main() {
+	// generate all syscall list
+	list := make([]int, 0, SYSCALL_NUMS)
+	for i := 0; i < SYSCALL_NUMS; i++ {
+		list = append(list, i)
+	}
+
+	for i := 0; i < SYSCALL_NUMS; i++ {
+		syscall := list[0]
+		list = list[1:]
+		err := run(list)
+		if err != nil {
+			if strings.Contains(err.Error(), "bad system call") {
+				// if run into err, then this syscall is needed, add it back to the end
+				list = append(list, syscall)
+			} else {
+				fmt.Println(fmt.Sprintf("Failed to run your python code, %v", err))
+			}
+		}
+	}
+
+	// final test
+	err := run(list)
+	if err != nil {
+		fmt.Println("Failed to get the needed syscalls")
+	} else {
+		// use ',' to join the list and print, easy for copy the list
+		list_str := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(list)), ","), "[]")
+		fmt.Println("Following syscalls are required:", list_str)
+	}
+}

+ 46 - 0
cmd/test/syscall_dig/test.py

@@ -0,0 +1,46 @@
+import ctypes
+import json
+import os
+import sys
+import traceback
+
+
+# setup sys.excepthook
+def excepthook(type, value, tb):
+    sys.stderr.write("".join(traceback.format_exception(type, value, tb)))
+    sys.stderr.flush()
+    sys.exit(-1)
+
+
+sys.excepthook = excepthook
+
+lib = ctypes.CDLL("/var/sandbox/sandbox-python/python.so")
+lib.DifySeccomp.argtypes = [ctypes.c_uint32, ctypes.c_uint32, ctypes.c_bool]
+lib.DifySeccomp.restype = None
+
+os.chdir("/var/sandbox/sandbox-python")
+
+lib.DifySeccomp(65537, 1001, 1)
+
+
+# declare main function here
+def main() -> dict:
+    return {"message": [1, 2, 3]}
+
+
+from base64 import b64decode
+from json import dumps, loads
+
+# execute main function, and return the result
+# inputs is a dict, and it
+inputs = b64decode("e30=").decode("utf-8")
+output = main(**json.loads(inputs))
+
+# convert output to json and print
+output = dumps(output, indent=4)
+
+result = f"""<<RESULT>>
+{output}
+<<RESULT>>"""
+
+print(result)