diff --git a/apps/common/utils/tool_code.py b/apps/common/utils/tool_code.py index 90d63c068..48d62ac1a 100644 --- a/apps/common/utils/tool_code.py +++ b/apps/common/utils/tool_code.py @@ -186,6 +186,7 @@ except Exception as e: def generate_mcp_server_code(self, code_str, params): python_paths = CONFIG.get_sandbox_python_package_paths().split(',') code = self._generate_mcp_server_code(code_str, params) + set_run_user = f'os.setgid({pwd.getpwnam(self.user).pw_gid});os.setuid({pwd.getpwnam(self.user).pw_uid});' if self.sandbox else '' return f""" import os, sys, logging logging.basicConfig(level=logging.WARNING) @@ -194,6 +195,7 @@ logging.getLogger("mcp.server").setLevel(logging.ERROR) path_to_exclude = ['/opt/py3/lib/python3.11/site-packages', '/opt/maxkb-app/apps'] sys.path = [p for p in sys.path if p not in path_to_exclude] sys.path += {python_paths} +{set_run_user} os.environ.clear() exec({dedent(code)!a}) """ @@ -202,30 +204,17 @@ exec({dedent(code)!a}) _code = self.generate_mcp_server_code(code, params) maxkb_logger.debug(f"Python code of mcp tool: {_code}") compressed_and_base64_encoded_code_str = base64.b64encode(gzip.compress(_code.encode())).decode() - if self.sandbox: - tool_config = { - 'command': 'su', - 'args': [ - '-s', sys.executable, - '-c', - f'import base64,gzip; exec(gzip.decompress(base64.b64decode(\'{compressed_and_base64_encoded_code_str}\')).decode())', - self.user, - ], - 'cwd': self.sandbox_path, - 'env': { - 'LD_PRELOAD': self.sandbox_so_path, - }, - 'transport': 'stdio', - } - else: - tool_config = { - 'command': sys.executable, - 'args': [ - '-c', - f'import base64,gzip; exec(gzip.decompress(base64.b64decode(\'{compressed_and_base64_encoded_code_str}\')).decode())', - ], - 'transport': 'stdio', - } + tool_config = { + 'command': sys.executable, + 'args': [ + '-c', + f'import base64,gzip; exec(gzip.decompress(base64.b64decode(\'{compressed_and_base64_encoded_code_str}\')).decode())', + ], + 'env': { + 'LD_PRELOAD': self.sandbox_so_path, + }, + 'transport': 'stdio', + } return tool_config def _exec(self, execute_file): diff --git a/installer/Dockerfile-base b/installer/Dockerfile-base index 925bb61c0..763f7ab62 100644 --- a/installer/Dockerfile-base +++ b/installer/Dockerfile-base @@ -29,8 +29,6 @@ RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ mkdir -p /opt/maxkb-app/sandbox/lib && chmod -R 550 /opt/maxkb-app/sandbox && \ useradd --no-create-home --home /opt/maxkb-app/sandbox sandbox -g root && \ chmod g-xr /usr/local/bin/* /usr/bin/* /bin/* /usr/sbin/* /sbin/* /usr/lib/postgresql/17/bin/* && \ - chmod g+xr /usr/bin/ld.so && \ - chmod g+x /usr/local/bin/python* && \ chmod -R g-rwx /tmp /var/tmp /var/lock && \ apt-get clean all && \ rm -rf /var/lib/postgresql /var/lib/apt/lists/* /usr/share/doc/* /usr/share/man/* /usr/share/info/* /usr/share/locale/* /usr/share/lintian/* /usr/share/linda/* /var/cache/* /var/log/* /var/tmp/* /tmp/* diff --git a/installer/sandbox.c b/installer/sandbox.c index 377e24232..3b89fe1f2 100644 --- a/installer/sandbox.c +++ b/installer/sandbox.c @@ -212,11 +212,6 @@ static int not_supported(const char *function_name) { _exit(1); return -1; } -static pid_t ppid = 0; -// 在进程初始化时保存 PID -__attribute__((constructor)) static void init_sandbox() { - ppid = getpid(); -} #define RESOLVE_REAL(func) \ static typeof(func) *real_##func = NULL; \ if (!real_##func) { \ @@ -224,22 +219,12 @@ __attribute__((constructor)) static void init_sandbox() { } int execv(const char *path, char *const argv[]) { RESOLVE_REAL(execv); - // fprintf(stdout, "execv path: %s ppid=%d pid=%d\n", path, sandbox_pid, getpid()); - if (!allow_create_subprocess()) { - // 只允许创建python进程,但不允许python进程替换(用os.execvp里又启动另一个python进程) - if (strstr(path, "bin/python") == NULL || getpid() == ppid) { - return deny(); - } - } + if (!allow_create_subprocess()) return deny(); return real_execv(path, argv); } int __execv(const char *path, char *const argv[]) { RESOLVE_REAL(__execv); - if (!allow_create_subprocess()) { - if (strstr(path, "bin/python") == NULL || getpid() == ppid) { - return deny(); - } - } + if (!allow_create_subprocess()) return deny(); return real___execv(path, argv); } int execve(const char *filename, char *const argv[], char *const envp[]) { @@ -259,16 +244,24 @@ int execveat(int dirfd, const char *pathname, return real_execveat(dirfd, pathname, argv, envp, flags); } int execvpe(const char *file, char *const argv[], char *const envp[]) { - return not_supported("execvpe"); + RESOLVE_REAL(execvpe); + if (!allow_create_subprocess()) return deny(); + return real_execvpe(file, argv, envp); } int __execvpe(const char *file, char *const argv[], char *const envp[]) { - return not_supported("__execvpe"); + RESOLVE_REAL(__execvpe); + if (!allow_create_subprocess()) return deny(); + return real___execvpe(file, argv, envp); } int execvp(const char *file, char *const argv[]) { - return not_supported("execvp"); + RESOLVE_REAL(execvp); + if (!allow_create_subprocess()) return deny(); + return real_execvp(file, argv); } int __execvp(const char *file, char *const argv[]) { - return not_supported("__execvp"); + RESOLVE_REAL(__execvp); + if (!allow_create_subprocess()) return deny(); + return real___execvp(file, argv); } int execl(const char *path, const char *arg, ...) { return not_supported("execl");