Skip to content

Commit 5e909a4

Browse files
feat: add MAXKB_SANDBOX_PYTHON_PROCESS_TIMEOUT_SECONDS env.
1 parent eb30b88 commit 5e909a4

File tree

2 files changed

+47
-93
lines changed

2 files changed

+47
-93
lines changed

apps/common/utils/tool_code.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def __init__(self, sandbox=False):
2828
self.sandbox_path = os.path.join(PROJECT_DIR, 'data', 'sandbox')
2929
self.user = None
3030
self.sandbox_so_path = f'{self.sandbox_path}/sandbox.so'
31+
self.process_timeout_seconds = int(CONFIG.get("SANDBOX_PYTHON_PROCESS_TIMEOUT_SECONDS", '3600'))
3132
try:
3233
self._init_dir()
3334
except Exception as e:
@@ -70,10 +71,8 @@ def _init_dir(self):
7071
local_ip = socket.gethostbyname(hostname)
7172
banned_hosts = f"{banned_hosts},{hostname},{local_ip}"
7273
with open(sandbox_conf_file_path, "w") as f:
73-
f.write(f"SANDBOX_PYTHON_BANNED_HOSTS={banned_hosts}")
74-
f.write("\n")
75-
f.write(f"SANDBOX_PYTHON_ALLOW_SUBPROCESS={allow_subprocess}")
76-
f.write("\n")
74+
f.write(f"SANDBOX_PYTHON_BANNED_HOSTS={banned_hosts}\n")
75+
f.write(f"SANDBOX_PYTHON_ALLOW_SUBPROCESS={allow_subprocess}\n")
7776
os.chmod(sandbox_conf_file_path, 0o440)
7877

7978
def exec_code(self, code_str, keywords):
@@ -228,12 +227,17 @@ def _exec_sandbox(self, _code):
228227
}
229228
maxkb_logger.debug(f"Sandbox execute code: {_code}")
230229
compressed_and_base64_encoded_code_str = base64.b64encode(gzip.compress(_code.encode())).decode()
231-
subprocess_result = subprocess.run(
232-
['su', '-s', python_directory, '-c',
233-
f'import base64,gzip; exec(gzip.decompress(base64.b64decode(\'{compressed_and_base64_encoded_code_str}\')).decode())',
234-
self.user],
235-
text=True,
236-
capture_output=True, **kwargs)
230+
try:
231+
subprocess_result = subprocess.run(
232+
['su', '-s', python_directory, '-c',
233+
f'import base64,gzip; exec(gzip.decompress(base64.b64decode(\'{compressed_and_base64_encoded_code_str}\')).decode())',
234+
self.user],
235+
text=True,
236+
capture_output=True,
237+
timeout=self.process_timeout_seconds,
238+
**kwargs)
239+
except subprocess.TimeoutExpired:
240+
raise Exception(_("Sandbox process execution timeout, consider increasing MAXKB_SANDBOX_PYTHON_PROCESS_TIMEOUT_SECONDS."))
237241
return subprocess_result
238242

239243
def validate_mcp_transport(self, code_str):

installer/sandbox.c

Lines changed: 33 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -157,147 +157,101 @@ static int allow_create_subprocess() {
157157
ensure_config_loaded();
158158
return allow_subprocess || !is_sandbox_user();
159159
}
160-
static int return_deny() {
160+
static int deny() {
161161
fprintf(stderr, "[sandbox] Permission denied to create subprocess in sandbox.\n");
162162
_exit(1);
163163
return -1;
164164
}
165-
int execve(const char *filename, char *const argv[], char *const envp[]) {
166-
if (!allow_create_subprocess()) {
167-
return return_deny();
165+
#define RESOLVE_REAL(func) \
166+
static typeof(func) *real_##func = NULL; \
167+
if (!real_##func) { \
168+
real_##func = dlsym(RTLD_NEXT, #func); \
168169
}
169-
static int (*real_execve)(const char *, char *const[], char *const[]) = NULL;
170-
if (!real_execve) real_execve = dlsym(RTLD_NEXT, "execve");
170+
171+
int execve(const char *filename, char *const argv[], char *const envp[]) {
172+
RESOLVE_REAL(execve);
173+
if (!allow_create_subprocess()) return deny();
171174
return real_execve(filename, argv, envp);
172175
}
173176

174177
int execveat(int dirfd, const char *pathname,
175178
char *const argv[], char *const envp[], int flags) {
176-
if (!allow_create_subprocess()) {
177-
return return_deny();
178-
}
179-
static int (*real_execveat)(int, const char *, char *const[], char *const[], int) = NULL;
180-
if (!real_execveat) real_execveat = dlsym(RTLD_NEXT, "execveat");
179+
RESOLVE_REAL(execveat);
180+
if (!allow_create_subprocess()) return deny();
181181
return real_execveat(dirfd, pathname, argv, envp, flags);
182182
}
183183

184184
pid_t fork(void) {
185-
if (!allow_create_subprocess()) {
186-
return return_deny();
187-
}
188-
static pid_t (*real_fork)(void) = NULL;
189-
if (!real_fork) real_fork = dlsym(RTLD_NEXT, "fork");
185+
RESOLVE_REAL(fork);
186+
if (!allow_create_subprocess()) return deny();
190187
return real_fork();
191188
}
192189

193190
pid_t vfork(void) {
194-
if (!allow_create_subprocess()) {
195-
return return_deny();
196-
}
197-
static pid_t (*real_vfork)(void) = NULL;
198-
if (!real_vfork) real_vfork = dlsym(RTLD_NEXT, "vfork");
191+
RESOLVE_REAL(vfork);
192+
if (!allow_create_subprocess()) return deny();
199193
return real_vfork();
200194
}
201195

202196
int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
203-
if (!allow_create_subprocess()) {
204-
return return_deny();
205-
}
206-
static int (*real_clone)(int (*)(void *), void *, int, void *, ...) = NULL;
207-
if (!real_clone) real_clone = dlsym(RTLD_NEXT, "clone");
197+
RESOLVE_REAL(clone);
198+
if (!allow_create_subprocess()) return deny();
208199
va_list ap;
209200
va_start(ap, arg);
210-
int ret = real_clone(fn, child_stack, flags, arg, ap);
201+
long a4 = va_arg(ap, long);
202+
long a5 = va_arg(ap, long);
211203
va_end(ap);
212-
return ret;
204+
return real_clone(fn, child_stack, flags, arg, (void *)a4, (void *)a5);
213205
}
214206

215207
int posix_spawn(pid_t *pid, const char *path,
216208
const posix_spawn_file_actions_t *file_actions,
217209
const posix_spawnattr_t *attrp,
218210
char *const argv[], char *const envp[]) {
219-
if (!allow_create_subprocess()) {
220-
return return_deny();
221-
}
222-
static int (*real_posix_spawn)(pid_t *, const char *, const posix_spawn_file_actions_t *,
223-
const posix_spawnattr_t *, char *const[], char *const[]) = NULL;
224-
if (!real_posix_spawn) real_posix_spawn = dlsym(RTLD_NEXT, "posix_spawn");
211+
RESOLVE_REAL(posix_spawn);
212+
if (!allow_create_subprocess()) return deny();
225213
return real_posix_spawn(pid, path, file_actions, attrp, argv, envp);
226214
}
227215

228216
int posix_spawnp(pid_t *pid, const char *file,
229217
const posix_spawn_file_actions_t *file_actions,
230218
const posix_spawnattr_t *attrp,
231219
char *const argv[], char *const envp[]) {
232-
if (!allow_create_subprocess()) {
233-
return return_deny();
234-
}
235-
static int (*real_posix_spawnp)(pid_t *, const char *, const posix_spawn_file_actions_t *,
236-
const posix_spawnattr_t *, char *const[], char *const[]) = NULL;
237-
if (!real_posix_spawnp) real_posix_spawnp = dlsym(RTLD_NEXT, "posix_spawnp");
220+
RESOLVE_REAL(posix_spawnp);
221+
if (!allow_create_subprocess()) return deny();
238222
return real_posix_spawnp(pid, file, file_actions, attrp, argv, envp);
239223
}
240224
int __posix_spawn(pid_t *pid, const char *path,
241225
const posix_spawn_file_actions_t *file_actions,
242226
const posix_spawnattr_t *attrp,
243227
char *const argv[], char *const envp[]) {
244-
if (!allow_create_subprocess()) {
245-
return return_deny();
246-
}
247-
248-
static int (*real___posix_spawn)(pid_t *, const char *,
249-
const posix_spawn_file_actions_t *,
250-
const posix_spawnattr_t *,
251-
char *const[], char *const[]) = NULL;
252-
253-
if (!real___posix_spawn)
254-
real___posix_spawn = dlsym(RTLD_NEXT, "__posix_spawn");
255-
228+
RESOLVE_REAL(__posix_spawn);
229+
if (!allow_create_subprocess()) return deny();
256230
return real___posix_spawn(pid, path, file_actions, attrp, argv, envp);
257231
}
258232

259233
int __posix_spawnp(pid_t *pid, const char *file,
260234
const posix_spawn_file_actions_t *file_actions,
261235
const posix_spawnattr_t *attrp,
262236
char *const argv[], char *const envp[]) {
263-
if (!allow_create_subprocess()) {
264-
return return_deny();
265-
}
266-
267-
static int (*real___posix_spawnp)(pid_t *, const char *,
268-
const posix_spawn_file_actions_t *,
269-
const posix_spawnattr_t *,
270-
char *const[], char *const[]) = NULL;
271-
272-
if (!real___posix_spawnp)
273-
real___posix_spawnp = dlsym(RTLD_NEXT, "__posix_spawnp");
274-
237+
RESOLVE_REAL(__posix_spawnp);
238+
if (!allow_create_subprocess()) return deny();
275239
return real___posix_spawnp(pid, file, file_actions, attrp, argv, envp);
276240
}
277241

278242
int system(const char *command) {
279-
if (!allow_create_subprocess()) {
280-
return return_deny();
281-
}
282-
static int (*real_system)(const char *) = NULL;
283-
if (!real_system) real_system = dlsym(RTLD_NEXT, "system");
243+
RESOLVE_REAL(system);
244+
if (!allow_create_subprocess()) return deny();
284245
return real_system(command);
285246
}
286247
int __libc_system(const char *command) {
287-
if (!allow_create_subprocess()) {
288-
return return_deny();
289-
}
290-
static int (*real___libc_system)(const char *) = NULL;
291-
if (!real___libc_system)
292-
real___libc_system = dlsym(RTLD_NEXT, "__libc_system");
293-
248+
RESOLVE_REAL(__libc_system);
249+
if (!allow_create_subprocess()) return deny();
294250
return real___libc_system(command);
295251
}
296252
long (*real_syscall)(long, ...) = NULL;
297-
298253
long syscall(long number, ...) {
299254
if (!real_syscall) real_syscall = dlsym(RTLD_NEXT, "syscall");
300-
301255
va_list ap;
302256
va_start(ap, number);
303257
long a1 = va_arg(ap, long);
@@ -307,13 +261,9 @@ long syscall(long number, ...) {
307261
long a5 = va_arg(ap, long);
308262
long a6 = va_arg(ap, long);
309263
va_end(ap);
310-
311264
if (number == SYS_execve || number == SYS_execveat ||
312265
number == SYS_fork || number == SYS_vfork || number == SYS_clone) {
313-
if (!allow_create_subprocess()) {
314-
return return_deny();
315-
}
266+
if (!allow_create_subprocess()) return deny();
316267
}
317-
318268
return real_syscall(number, a1, a2, a3, a4, a5, a6);
319269
}

0 commit comments

Comments
 (0)