2 * Part of Very Secure FTPd
7 * Generic routines to setup and run a process under a restrictive ptrace()
9 * Note that the style in this file is to not go via the helper functions in
10 * sysutil.c, but instead hit the system APIs directly. This is because I may
11 * very well release just this file to the public domain, and do not want
12 * dependencies on other parts of vsftpd.
15 #include "ptracesandbox.h"
17 #if defined(__linux__) && defined(__i386__)
20 #include <sys/prctl.h>
21 #include <sys/ptrace.h>
22 /* For AF_MAX (NPROTO is defined to this) */
23 #include <sys/socket.h>
24 #include <sys/types.h>
36 #include <asm/unistd.h>
38 #ifndef __NR_sendfile64
39 #define __NR_sendfile64 239
42 #ifndef __NR_exit_group
43 #define __NR_exit_group 252
47 #define __NR_utimes 271
50 /* For the socketcall() multiplex args. */
51 #include <linux/net.h>
53 #ifndef PTRACE_SETOPTIONS
54 #define PTRACE_SETOPTIONS 0x4200
57 #ifndef PTRACE_O_TRACESYSGOOD
58 #define PTRACE_O_TRACESYSGOOD 1
61 #ifndef PTRACE_O_TRACEFORK
62 #define PTRACE_O_TRACEFORK 2
65 #ifndef PTRACE_O_TRACEVFORK
66 #define PTRACE_O_TRACEVFORK 4
69 #ifndef PTRACE_O_TRACECLONE
70 #define PTRACE_O_TRACECLONE 8
74 #define O_DIRECT 040000
77 static void sanitize_child();
78 static int get_action(struct pt_sandbox
* p_sandbox
);
80 static int validate_mmap2(struct pt_sandbox
* p_sandbox
, void* p_arg
);
81 static int validate_open_default(struct pt_sandbox
* p_sandbox
, void* p_arg
);
82 static int validate_open_readonly(struct pt_sandbox
* p_sandbox
, void* p_arg
);
83 static int validate_fcntl(struct pt_sandbox
* p_sandbox
, void* p_arg
);
84 static int validate_socketcall(struct pt_sandbox
* p_sandbox
, void* p_arg
);
85 static void install_socketcall(struct pt_sandbox
* p_sandbox
);
87 #define MAX_SYSCALL 300
94 int is_allowed
[MAX_SYSCALL
];
95 ptrace_sandbox_validator_t validator
[MAX_SYSCALL
];
96 void* validator_arg
[MAX_SYSCALL
];
98 struct user_regs_struct regs
;
99 int is_socketcall_allowed
[NPROTO
];
100 ptrace_sandbox_validator_t socketcall_validator
[NPROTO
];
101 void* socketcall_validator_arg
[NPROTO
];
104 static int s_sigchld_fd
= -1;
107 handle_sigchld(int sig
)
114 if (s_sigchld_fd
!= -1)
118 static const char zero
= '\0';
119 ret
= write(s_sigchld_fd
, &zero
, sizeof(zero
));
120 } while (ret
== -1 && errno
== EINTR
);
129 ptrace_sandbox_alloc()
132 struct sigaction sigact
;
133 struct pt_sandbox
* ret
= malloc(sizeof(struct pt_sandbox
));
139 ret
->read_event_fd
= -1;
140 ret
->write_event_fd
= -1;
142 memset(&ret
->regs
, '\0', sizeof(ret
->regs
));
143 for (i
= 0; i
< MAX_SYSCALL
; ++i
)
145 ret
->is_allowed
[i
] = 0;
146 ret
->validator
[i
] = 0;
147 ret
->validator_arg
[i
] = 0;
149 for (i
= 0; i
< NPROTO
; ++i
)
151 ret
->is_socketcall_allowed
[i
] = 0;
152 ret
->socketcall_validator
[i
] = 0;
153 ret
->socketcall_validator_arg
[i
] = 0;
155 memset((void*) &sigact
, '\0', sizeof(sigact
));
156 sigact
.sa_handler
= handle_sigchld
;
157 if (sigaction(SIGCHLD
, &sigact
, NULL
) != 0)
163 ptrace_sandbox_free(ret
);
168 ptrace_sandbox_free(struct pt_sandbox
* p_sandbox
)
170 if (p_sandbox
->pid
!= -1)
172 warnx("bug: pid active in ptrace_sandbox_free");
173 /* We'll kill it for you so it doesn't escape the sandbox totally, but
174 * we won't reap the zombie.
175 * Killing it like this is a risk: if it's stopped in syscall entry,
176 * that syscall will execute before the pending kill takes effect.
177 * If that pending syscall were to be a fork(), there could be trouble.
179 (void) kill(p_sandbox
->pid
, SIGKILL
);
181 if (p_sandbox
->read_event_fd
!= -1)
184 close(p_sandbox
->read_event_fd
);
185 close(p_sandbox
->write_event_fd
);
191 ptrace_sandbox_attach_point()
195 pid_t pid
= getpid();
201 /* You don't have to use PTRACE_TRACEME, but if you don't, a rogue SIGCONT
202 * might wake you up from the STOP below before the tracer has attached.
204 pt_ret
= ptrace(PTRACE_TRACEME
, 0, 0, 0);
207 warn("PTRACE_TRACEME failed");
210 ret
= kill(pid
, SIGSTOP
);
213 warn("kill SIGSTOP failed");
219 ptrace_sandbox_launch_process(struct pt_sandbox
* p_sandbox
,
220 void (*p_func
)(void*),
226 if (p_sandbox
->pid
!= -1)
228 warnx("bug: process already active");
244 p_sandbox
->pid
= ret
;
247 ret
= waitpid(p_sandbox
->pid
, &status
, 0);
248 } while (ret
== -1 && errno
== EINTR
);
251 warn("waitpid failed");
254 else if (ret
!= p_sandbox
->pid
)
256 warnx("unknown pid %d", ret
);
259 if (!WIFSTOPPED(status
))
261 warnx("not stopped status %d\n", status
);
264 if (WSTOPSIG(status
) != SIGSTOP
)
266 warnx("not SIGSTOP status %d\n", status
);
269 /* The fork, etc. tracing options are worth a bit of explanation. We don't
270 * permit process launching syscalls at all as they are dangerous. But
271 * there's a small race if the untrusted process attempts a denied fork()
272 * and then takes a rouge SIGKILL before the supervisor gets a chance to
273 * clear the orig_eax register. In this case the syscall will still execute.
274 * (Policies may not include signal sending capabilities, thus mitigating this
275 * direct attack, however a rogue SIGKILL may come from a non-malicious
276 * source). Therefore, we'd rather any fork()ed process starts off traced,
277 * just in case this tiny race condition triggers.
279 pt_ret
= ptrace(PTRACE_SETOPTIONS
,
282 PTRACE_O_TRACESYSGOOD
| PTRACE_O_TRACEFORK
|
283 PTRACE_O_TRACEVFORK
| PTRACE_O_TRACECLONE
);
286 warn("PTRACE_SETOPTIONS failure");
289 return p_sandbox
->pid
;
291 (void) kill(p_sandbox
->pid
, SIGKILL
);
297 ptrace_sandbox_continue_process(struct pt_sandbox
* p_sandbox
, int sig
)
299 long pt_ret
= ptrace(PTRACE_SYSCALL
, p_sandbox
->pid
, 0, sig
);
302 warn("PTRACE_SYSCALL failure");
305 return PTRACE_SANDBOX_ERR_DEAD
;
307 return PTRACE_SANDBOX_ERR_PTRACE
;
313 ptrace_sandbox_get_event_fd(struct pt_sandbox
* p_sandbox
)
315 /* TODO: allocate pipe fds */
321 ptrace_sandbox_get_event(struct pt_sandbox
* p_sandbox
, int* status
, int block
)
331 pid
= waitpid(p_sandbox
->pid
, status
, options
);
332 } while (pid
== -1 && errno
== EINTR
);
335 warn("waitpid failure");
338 return PTRACE_SANDBOX_ERR_DEAD
;
340 return PTRACE_SANDBOX_ERR_WAITPID
;
346 ptrace_sandbox_handle_event(struct pt_sandbox
* p_sandbox
, int status
)
350 if (WIFEXITED(status
) || WIFSIGNALED(status
))
355 if (!WIFSTOPPED(status
))
357 warnx("weird status: %d\n", status
);
358 return PTRACE_SANDBOX_ERR_WAIT_STATUS
;
360 sig
= WSTOPSIG(status
);
361 if (sig
>= 0 && sig
< 0x80)
363 /* It's a normal signal; deliver it right on. SIGSTOP / SIGCONT handling
364 * are buggy in the kernel and I'm not sure it's safe to pass either on,
365 * so the signal becomes a little more... robust :)
367 if (sig
== SIGSTOP
|| sig
== SIGCONT
)
371 return ptrace_sandbox_continue_process(p_sandbox
, sig
);
375 warnx("weird status: %d\n", status
);
376 return PTRACE_SANDBOX_ERR_WAIT_STATUS
;
379 if (p_sandbox
->is_exit
)
381 p_sandbox
->is_exit
= 0;
385 p_sandbox
->is_exit
= 1;
386 action
= get_action(p_sandbox
);
392 return ptrace_sandbox_continue_process(p_sandbox
, 0);
396 ptrace_sandbox_run_processes(struct pt_sandbox
* p_sandbox
)
398 if (ptrace_sandbox_continue_process(p_sandbox
, 0) != 0)
405 int ret
= ptrace_sandbox_get_event(p_sandbox
, &status
, 1);
410 ret
= ptrace_sandbox_handle_event(p_sandbox
, status
);
413 warnx("couldn't handle sandbox event");
422 ptrace_sandbox_kill_processes(p_sandbox
);
427 ptrace_sandbox_kill_processes(struct pt_sandbox
* p_sandbox
)
430 struct user_regs_struct regs
;
431 pid_t pid
= p_sandbox
->pid
;
437 pt_ret
= ptrace(PTRACE_GETREGS
, pid
, 0, ®s
);
440 warn("PTRACE_GETREGS failure");
441 /* This API is supposed to be called with the process stopped; but if it
442 * is still running, we can at least help a bit. See security related
443 * comment in ptrace_sandbox_free(), though.
445 (void) kill(pid
, SIGKILL
);
448 /* Kind of nasty, but the only way of stopping a started syscall from
449 * executing is to rewrite the registers to execute a different syscall.
451 regs
.orig_eax
= __NR_exit_group
;
452 regs
.eip
= 0xffffffff;
453 pt_ret
= ptrace(PTRACE_SETREGS
, pid
, 0, ®s
);
456 warn("PTRACE_SETREGS failure");
457 /* Deliberate fall-thru. */
459 pt_ret
= ptrace(PTRACE_KILL
, pid
, 0, 0);
462 warn("PTRACE_KILL failure");
463 /* Deliberate fall-thru. */
465 /* Just to make ourselves clear. */
466 (void) kill(pid
, SIGKILL
);
467 /* So the GETREGS succeeded, so the process definitely _was_ there. We can
468 * safely wait for it to reap the zombie.
470 (void) waitpid(pid
, NULL
, 0);
474 ptrace_sandbox_get_arg(struct pt_sandbox
* p_sandbox
,
476 unsigned long* p_out
)
479 struct user_regs_struct
* p_regs
= &p_sandbox
->regs
;
480 if (p_regs
->orig_eax
== 0)
482 return PTRACE_SANDBOX_ERR_API_ABUSE_STOPIT
;
484 if (arg
< 0 || arg
> 5)
486 return PTRACE_SANDBOX_ERR_API_ABUSE_STOPIT
;
514 ptrace_sandbox_get_socketcall_arg(struct pt_sandbox
* p_sandbox
,
516 unsigned long* p_out
)
520 struct user_regs_struct
* p_regs
= &p_sandbox
->regs
;
521 if (p_regs
->orig_eax
== 0)
523 return PTRACE_SANDBOX_ERR_API_ABUSE_STOPIT
;
525 if (arg
< 0 || arg
> 2)
527 return PTRACE_SANDBOX_ERR_API_ABUSE_STOPIT
;
529 ret
= ptrace_sandbox_get_arg(p_sandbox
, 1, &ptr
);
535 ret
= ptrace_sandbox_get_long(p_sandbox
, ptr
, p_out
);
540 ptrace_sandbox_get_long(struct pt_sandbox
* p_sandbox
,
542 unsigned long* p_out
)
544 return ptrace_sandbox_get_buf(p_sandbox
, ptr
, sizeof(long), (void*) p_out
);
548 ptrace_sandbox_get_buf(struct pt_sandbox
* p_sandbox
,
554 char* p_out
= (char*) p_buf
;
555 for (; len
> 0; len
-= sizeof(long))
558 pt_ret
= ptrace(PTRACE_PEEKDATA
, p_sandbox
->pid
, (void*) ptr
, 0);
559 if (pt_ret
== -1 && errno
!= 0)
561 warn("PTRACE_GETREGS failure");
564 return PTRACE_SANDBOX_ERR_DEAD
;
566 return PTRACE_SANDBOX_ERR_PTRACE
;
568 if (len
>= sizeof(long))
570 memcpy(p_out
, &pt_ret
, sizeof(long));
574 memcpy(p_out
, &pt_ret
, len
);
576 p_out
+= sizeof(long);
585 /* Ensure that if our sandbox supervisor goes down, so do we. */
586 int ret
= prctl(PR_SET_PDEATHSIG
, SIGKILL
, 0, 0, 0);
594 get_action(struct pt_sandbox
* p_sandbox
)
599 long pt_ret
= ptrace(PTRACE_GETREGS
, p_sandbox
->pid
, 0, &(p_sandbox
->regs
));
602 warn("PTRACE_GETREGS failure");
605 return PTRACE_SANDBOX_ERR_DEAD
;
607 return PTRACE_SANDBOX_ERR_PTRACE
;
609 /* We need to be sure that the child is attempting a syscall against the
610 * 32-bit syscall table, otherwise they can bypass the policy by abusing the
611 * fact that e.g. syscall 200 is getgid32() on 32-bit but tkill() on 64-bit.
612 * If the syscall instruct was int80 or sysenter, is it guaranteed to hit
613 * the 32-bit table. If it is syscall, the current CS selector determines
614 * the table. Therefore, we can check the current CS selector references a
615 * known system-only selector that is guaranteed 32-bit (not long mode).
617 cs
= p_sandbox
->regs
.xcs
;
618 if (cs
!= 0x73 && cs
!= 0x23)
620 warnx("bad CS %d", cs
);
621 ret
= PTRACE_SANDBOX_ERR_BAD_SYSCALL
;
624 call
= (int) p_sandbox
->regs
.orig_eax
;
625 if (call
< 0 || call
>= MAX_SYSCALL
)
627 warnx("syscall %d out of bounds", call
);
628 ret
= PTRACE_SANDBOX_ERR_BAD_SYSCALL
;
631 if (p_sandbox
->is_allowed
[call
] != 1)
633 syslog(LOG_LOCAL0
| LOG_DEBUG
, "syscall not permitted: %d", call
);
634 warnx("syscall not permitted: %d", call
);
635 ret
= PTRACE_SANDBOX_ERR_POLICY_SYSCALL
;
638 if (p_sandbox
->validator
[call
])
640 ptrace_sandbox_validator_t p_validate
= p_sandbox
->validator
[call
];
641 int validate_ret
= (*p_validate
)(p_sandbox
, p_sandbox
->validator_arg
[call
]);
642 if (validate_ret
!= 0)
644 syslog(LOG_LOCAL0
| LOG_DEBUG
,
645 "syscall validate fail: %d (%d)",
648 warnx("syscall validate failed: %d (%d)", call
, validate_ret
);
649 ret
= PTRACE_SANDBOX_ERR_POLICY_ARGS
;
655 memset(&p_sandbox
->regs
, '\0', sizeof(&p_sandbox
->regs
));
660 ptrace_sandbox_permit_exit(struct pt_sandbox
* p_sandbox
)
662 p_sandbox
->is_allowed
[__NR_exit
] = 1;
663 p_sandbox
->is_allowed
[__NR_exit_group
] = 1;
667 ptrace_sandbox_permit_read(struct pt_sandbox
* p_sandbox
)
669 p_sandbox
->is_allowed
[__NR_read
] = 1;
673 ptrace_sandbox_permit_write(struct pt_sandbox
* p_sandbox
)
675 p_sandbox
->is_allowed
[__NR_write
] = 1;
679 ptrace_sandbox_permit_sigaction(struct pt_sandbox
* p_sandbox
)
681 p_sandbox
->is_allowed
[__NR_sigaction
] = 1;
682 p_sandbox
->is_allowed
[__NR_rt_sigaction
] = 1;
686 ptrace_sandbox_permit_alarm(struct pt_sandbox
* p_sandbox
)
688 p_sandbox
->is_allowed
[__NR_alarm
] = 1;
692 ptrace_sandbox_permit_query_time(struct pt_sandbox
* p_sandbox
)
694 p_sandbox
->is_allowed
[__NR_gettimeofday
] = 1;
695 p_sandbox
->is_allowed
[__NR_time
] = 1;
699 ptrace_sandbox_permit_mmap(struct pt_sandbox
* p_sandbox
)
701 p_sandbox
->is_allowed
[__NR_mmap2
] = 1;
702 p_sandbox
->validator
[__NR_mmap2
] = validate_mmap2
;
706 validate_mmap2(struct pt_sandbox
* p_sandbox
, void* p_arg
)
709 int ret
= ptrace_sandbox_get_arg(p_sandbox
, 3, &arg4
);
715 if (arg4
& MAP_SHARED
)
723 ptrace_sandbox_permit_mprotect(struct pt_sandbox
* p_sandbox
)
725 p_sandbox
->is_allowed
[__NR_mprotect
] = 1;
729 ptrace_sandbox_permit_file_stats(struct pt_sandbox
* p_sandbox
)
731 p_sandbox
->is_allowed
[__NR_stat
] = 1;
732 p_sandbox
->is_allowed
[__NR_stat64
] = 1;
733 p_sandbox
->is_allowed
[__NR_lstat
] = 1;
734 p_sandbox
->is_allowed
[__NR_lstat64
] = 1;
738 ptrace_sandbox_permit_fd_stats(struct pt_sandbox
* p_sandbox
)
740 p_sandbox
->is_allowed
[__NR_fstat
] = 1;
741 p_sandbox
->is_allowed
[__NR_fstat64
] = 1;
745 ptrace_sandbox_permit_getcwd(struct pt_sandbox
* p_sandbox
)
747 p_sandbox
->is_allowed
[__NR_getcwd
] = 1;
751 ptrace_sandbox_permit_chdir(struct pt_sandbox
* p_sandbox
)
753 p_sandbox
->is_allowed
[__NR_chdir
] = 1;
757 ptrace_sandbox_permit_umask(struct pt_sandbox
* p_sandbox
)
759 p_sandbox
->is_allowed
[__NR_umask
] = 1;
763 ptrace_sandbox_permit_open(struct pt_sandbox
* p_sandbox
, int writeable
)
765 p_sandbox
->is_allowed
[__NR_open
] = 1;
768 p_sandbox
->validator
[__NR_open
] = validate_open_default
;
772 p_sandbox
->validator
[__NR_open
] = validate_open_readonly
;
777 validate_open_default(struct pt_sandbox
* p_sandbox
, void* p_arg
)
780 int ret
= ptrace_sandbox_get_arg(p_sandbox
, 1, &arg2
);
786 if (arg2
& (O_ASYNC
| O_DIRECT
| O_SYNC
))
794 validate_open_readonly(struct pt_sandbox
* p_sandbox
, void* p_arg
)
797 int ret
= validate_open_default(p_sandbox
, p_arg
);
802 ret
= ptrace_sandbox_get_arg(p_sandbox
, 1, &arg2
);
807 if ((arg2
& O_ACCMODE
) != O_RDONLY
)
815 ptrace_sandbox_permit_close(struct pt_sandbox
* p_sandbox
)
817 p_sandbox
->is_allowed
[__NR_close
] = 1;
821 ptrace_sandbox_permit_getdents(struct pt_sandbox
* p_sandbox
)
823 p_sandbox
->is_allowed
[__NR_getdents
] = 1;
824 p_sandbox
->is_allowed
[__NR_getdents64
] = 1;
828 ptrace_sandbox_permit_fcntl(struct pt_sandbox
* p_sandbox
)
830 p_sandbox
->is_allowed
[__NR_fcntl
] = 1;
831 p_sandbox
->validator
[__NR_fcntl
] = validate_fcntl
;
832 p_sandbox
->is_allowed
[__NR_fcntl64
] = 1;
833 p_sandbox
->validator
[__NR_fcntl64
] = validate_fcntl
;
837 validate_fcntl(struct pt_sandbox
* p_sandbox
, void* p_arg
)
841 int ret
= ptrace_sandbox_get_arg(p_sandbox
, 1, &arg2
);
847 ret
= ptrace_sandbox_get_arg(p_sandbox
, 2, &arg3
);
852 if (arg2
!= F_GETFL
&&
858 arg2
!= F_SETLKW64
&&
862 syslog(LOG_LOCAL0
| LOG_DEBUG
, "fcntl not permitted: %ld", arg2
);
863 warnx("fcntl not permitted: %ld", arg2
);
866 if (arg2
== F_SETFL
&& (arg3
& (O_ASYNC
| O_DIRECT
)))
870 if (arg2
== F_SETOWN
&& (int) arg3
!= p_sandbox
->pid
)
878 ptrace_sandbox_permit_sendfile(struct pt_sandbox
* p_sandbox
)
880 p_sandbox
->is_allowed
[__NR_sendfile
] = 1;
881 p_sandbox
->is_allowed
[__NR_sendfile64
] = 1;
885 ptrace_sandbox_permit_seek(struct pt_sandbox
* p_sandbox
)
887 p_sandbox
->is_allowed
[__NR_lseek
] = 1;
888 p_sandbox
->is_allowed
[__NR__llseek
] = 1;
892 ptrace_sandbox_permit_select(struct pt_sandbox
* p_sandbox
)
894 p_sandbox
->is_allowed
[__NR_select
] = 1;
895 p_sandbox
->is_allowed
[__NR__newselect
] = 1;
899 ptrace_sandbox_permit_unlink(struct pt_sandbox
* p_sandbox
)
901 p_sandbox
->is_allowed
[__NR_unlink
] = 1;
905 ptrace_sandbox_permit_mkdir(struct pt_sandbox
* p_sandbox
)
907 p_sandbox
->is_allowed
[__NR_mkdir
] = 1;
911 ptrace_sandbox_permit_rmdir(struct pt_sandbox
* p_sandbox
)
913 p_sandbox
->is_allowed
[__NR_rmdir
] = 1;
917 ptrace_sandbox_permit_rename(struct pt_sandbox
* p_sandbox
)
919 p_sandbox
->is_allowed
[__NR_rename
] = 1;
923 ptrace_sandbox_permit_utime(struct pt_sandbox
* p_sandbox
)
925 p_sandbox
->is_allowed
[__NR_utime
] = 1;
926 p_sandbox
->is_allowed
[__NR_utimes
] = 1;
930 ptrace_sandbox_permit_sigreturn(struct pt_sandbox
* p_sandbox
)
932 p_sandbox
->is_allowed
[__NR_sigreturn
] = 1;
936 ptrace_sandbox_permit_recv(struct pt_sandbox
* p_sandbox
)
938 install_socketcall(p_sandbox
);
939 p_sandbox
->is_socketcall_allowed
[SYS_RECV
] = 1;
943 install_socketcall(struct pt_sandbox
* p_sandbox
)
945 p_sandbox
->is_allowed
[__NR_socketcall
] = 1;
946 p_sandbox
->validator
[__NR_socketcall
] = validate_socketcall
;
950 validate_socketcall(struct pt_sandbox
* p_sandbox
, void* p_arg
)
953 int ret
= ptrace_sandbox_get_arg(p_sandbox
, 0, &arg1
);
959 if (arg1
< 1 || arg1
>= NPROTO
)
963 if (p_sandbox
->is_socketcall_allowed
[arg1
] != 1)
965 syslog(LOG_LOCAL0
| LOG_DEBUG
, "socketcall not permitted: %ld", arg1
);
966 warnx("socketcall not permitted: %ld", arg1
);
969 if (p_sandbox
->socketcall_validator
[arg1
])
971 ptrace_sandbox_validator_t p_val
= p_sandbox
->socketcall_validator
[arg1
];
972 ret
= (*p_val
)(p_sandbox
, p_sandbox
->socketcall_validator_arg
[arg1
]);
975 syslog(LOG_LOCAL0
| LOG_DEBUG
,
976 "socketcall validate fail: %ld (%d)",
979 warnx("socketcall validate fail: %ld (%d)", arg1
, ret
);
987 ptrace_sandbox_permit_readlink(struct pt_sandbox
* p_sandbox
)
989 p_sandbox
->is_allowed
[__NR_readlink
] = 1;
993 ptrace_sandbox_permit_brk(struct pt_sandbox
* p_sandbox
)
995 p_sandbox
->is_allowed
[__NR_brk
] = 1;
999 ptrace_sandbox_permit_sleep(struct pt_sandbox
* p_sandbox
)
1001 p_sandbox
->is_allowed
[__NR_nanosleep
] = 1;
1005 ptrace_sandbox_permit_fchmod(struct pt_sandbox
* p_sandbox
)
1007 p_sandbox
->is_allowed
[__NR_fchmod
] = 1;
1011 ptrace_sandbox_permit_chmod(struct pt_sandbox
* p_sandbox
)
1013 p_sandbox
->is_allowed
[__NR_chmod
] = 1;
1017 ptrace_sandbox_permit_fchown(struct pt_sandbox
* p_sandbox
)
1019 p_sandbox
->is_allowed
[__NR_fchown
] = 1;
1020 p_sandbox
->is_allowed
[__NR_fchown32
] = 1;
1024 ptrace_sandbox_permit_mremap(struct pt_sandbox
* p_sandbox
)
1026 p_sandbox
->is_allowed
[__NR_mremap
] = 1;
1030 ptrace_sandbox_permit_ftruncate(struct pt_sandbox
* p_sandbox
)
1032 p_sandbox
->is_allowed
[__NR_ftruncate
] = 1;
1033 p_sandbox
->is_allowed
[__NR_ftruncate64
] = 1;
1037 ptrace_sandbox_permit_socket(struct pt_sandbox
* p_sandbox
)
1039 install_socketcall(p_sandbox
);
1040 p_sandbox
->is_socketcall_allowed
[SYS_SOCKET
] = 1;
1044 ptrace_sandbox_set_socket_validator(struct pt_sandbox
* p_sandbox
,
1045 ptrace_sandbox_validator_t val
,
1048 p_sandbox
->socketcall_validator
[SYS_SOCKET
] = val
;
1049 p_sandbox
->socketcall_validator_arg
[SYS_SOCKET
] = p_arg
;
1053 ptrace_sandbox_permit_bind(struct pt_sandbox
* p_sandbox
)
1055 install_socketcall(p_sandbox
);
1056 p_sandbox
->is_socketcall_allowed
[SYS_BIND
] = 1;
1060 ptrace_sandbox_set_bind_validator(struct pt_sandbox
* p_sandbox
,
1061 ptrace_sandbox_validator_t val
,
1064 p_sandbox
->socketcall_validator
[SYS_BIND
] = val
;
1065 p_sandbox
->socketcall_validator_arg
[SYS_BIND
] = p_arg
;
1069 ptrace_sandbox_permit_connect(struct pt_sandbox
* p_sandbox
)
1071 install_socketcall(p_sandbox
);
1072 p_sandbox
->is_socketcall_allowed
[SYS_CONNECT
] = 1;
1076 ptrace_sandbox_set_connect_validator(struct pt_sandbox
* p_sandbox
,
1077 ptrace_sandbox_validator_t val
,
1080 p_sandbox
->socketcall_validator
[SYS_CONNECT
] = val
;
1081 p_sandbox
->socketcall_validator_arg
[SYS_CONNECT
] = p_arg
;
1085 ptrace_sandbox_permit_listen(struct pt_sandbox
* p_sandbox
)
1087 install_socketcall(p_sandbox
);
1088 p_sandbox
->is_socketcall_allowed
[SYS_LISTEN
] = 1;
1092 ptrace_sandbox_permit_accept(struct pt_sandbox
* p_sandbox
)
1094 install_socketcall(p_sandbox
);
1095 p_sandbox
->is_socketcall_allowed
[SYS_ACCEPT
] = 1;
1099 ptrace_sandbox_permit_setsockopt(struct pt_sandbox
* p_sandbox
)
1101 install_socketcall(p_sandbox
);
1102 p_sandbox
->is_socketcall_allowed
[SYS_SETSOCKOPT
] = 1;
1106 ptrace_sandbox_set_setsockopt_validator(struct pt_sandbox
* p_sandbox
,
1107 ptrace_sandbox_validator_t val
,
1110 p_sandbox
->socketcall_validator
[SYS_SETSOCKOPT
] = val
;
1111 p_sandbox
->socketcall_validator_arg
[SYS_SETSOCKOPT
] = p_arg
;
1115 ptrace_sandbox_permit_getsockopt(struct pt_sandbox
* p_sandbox
)
1117 install_socketcall(p_sandbox
);
1118 p_sandbox
->is_socketcall_allowed
[SYS_GETSOCKOPT
] = 1;
1122 ptrace_sandbox_set_getsockopt_validator(struct pt_sandbox
* p_sandbox
,
1123 ptrace_sandbox_validator_t val
,
1126 p_sandbox
->socketcall_validator
[SYS_GETSOCKOPT
] = val
;
1127 p_sandbox
->socketcall_validator_arg
[SYS_GETSOCKOPT
] = p_arg
;
1131 ptrace_sandbox_permit_shutdown(struct pt_sandbox
* p_sandbox
)
1133 install_socketcall(p_sandbox
);
1134 p_sandbox
->is_socketcall_allowed
[SYS_SHUTDOWN
] = 1;
1137 #else /* __linux__ && __i386__ */
1140 ptrace_sandbox_alloc()
1146 ptrace_sandbox_free(struct pt_sandbox
* p_sandbox
)
1152 ptrace_sandbox_launch_process(struct pt_sandbox
* p_sandbox
,
1153 void (*p_func
)(void*),
1163 ptrace_sandbox_run_processes(struct pt_sandbox
* p_sandbox
)
1170 ptrace_sandbox_attach_point(void)
1175 ptrace_sandbox_permit_exit(struct pt_sandbox
* p_sandbox
)
1181 ptrace_sandbox_permit_read(struct pt_sandbox
* p_sandbox
)
1187 ptrace_sandbox_permit_write(struct pt_sandbox
* p_sandbox
)
1193 ptrace_sandbox_permit_sigaction(struct pt_sandbox
* p_sandbox
)
1199 ptrace_sandbox_permit_alarm(struct pt_sandbox
* p_sandbox
)
1205 ptrace_sandbox_permit_query_time(struct pt_sandbox
* p_sandbox
)
1211 ptrace_sandbox_permit_mmap(struct pt_sandbox
* p_sandbox
)
1217 ptrace_sandbox_permit_mprotect(struct pt_sandbox
* p_sandbox
)
1223 ptrace_sandbox_permit_file_stats(struct pt_sandbox
* p_sandbox
)
1229 ptrace_sandbox_permit_fd_stats(struct pt_sandbox
* p_sandbox
)
1235 ptrace_sandbox_permit_getcwd(struct pt_sandbox
* p_sandbox
)
1241 ptrace_sandbox_permit_chdir(struct pt_sandbox
* p_sandbox
)
1247 ptrace_sandbox_permit_umask(struct pt_sandbox
* p_sandbox
)
1253 ptrace_sandbox_permit_open(struct pt_sandbox
* p_sandbox
, int writeable
)
1260 ptrace_sandbox_permit_close(struct pt_sandbox
* p_sandbox
)
1266 ptrace_sandbox_permit_getdents(struct pt_sandbox
* p_sandbox
)
1272 ptrace_sandbox_permit_fcntl(struct pt_sandbox
* p_sandbox
)
1278 ptrace_sandbox_permit_sendfile(struct pt_sandbox
* p_sandbox
)
1284 ptrace_sandbox_permit_seek(struct pt_sandbox
* p_sandbox
)
1290 ptrace_sandbox_permit_select(struct pt_sandbox
* p_sandbox
)
1296 ptrace_sandbox_permit_unlink(struct pt_sandbox
* p_sandbox
)
1302 ptrace_sandbox_permit_mkdir(struct pt_sandbox
* p_sandbox
)
1308 ptrace_sandbox_permit_rmdir(struct pt_sandbox
* p_sandbox
)
1314 ptrace_sandbox_permit_rename(struct pt_sandbox
* p_sandbox
)
1320 ptrace_sandbox_permit_utime(struct pt_sandbox
* p_sandbox
)
1326 ptrace_sandbox_permit_utimes(struct pt_sandbox
* p_sandbox
)
1332 ptrace_sandbox_permit_sigreturn(struct pt_sandbox
* p_sandbox
)
1338 ptrace_sandbox_permit_recv(struct pt_sandbox
* p_sandbox
)
1344 ptrace_sandbox_kill_processes(struct pt_sandbox
* p_sandbox
)
1350 ptrace_sandbox_get_arg(struct pt_sandbox
* p_sandbox
,
1352 unsigned long* p_out
)
1361 ptrace_sandbox_get_socketcall_arg(struct pt_sandbox
* p_sandbox
,
1363 unsigned long* p_out
)
1372 ptrace_sandbox_get_long(struct pt_sandbox
* p_sandbox
,
1374 unsigned long* p_out
)
1383 ptrace_sandbox_get_buf(struct pt_sandbox
* p_sandbox
,
1396 ptrace_sandbox_permit_readlink(struct pt_sandbox
* p_sandbox
)
1402 ptrace_sandbox_permit_brk(struct pt_sandbox
* p_sandbox
)
1408 ptrace_sandbox_permit_sleep(struct pt_sandbox
* p_sandbox
)
1414 ptrace_sandbox_permit_fchmod(struct pt_sandbox
* p_sandbox
)
1420 ptrace_sandbox_permit_chmod(struct pt_sandbox
* p_sandbox
)
1426 ptrace_sandbox_permit_fchown(struct pt_sandbox
* p_sandbox
)
1432 ptrace_sandbox_permit_mremap(struct pt_sandbox
* p_sandbox
)
1438 ptrace_sandbox_permit_ftruncate(struct pt_sandbox
* p_sandbox
)
1444 ptrace_sandbox_permit_socket(struct pt_sandbox
* p_sandbox
)
1450 ptrace_sandbox_set_socket_validator(struct pt_sandbox
* p_sandbox
,
1451 ptrace_sandbox_validator_t val
,
1460 ptrace_sandbox_permit_bind(struct pt_sandbox
* p_sandbox
)
1466 ptrace_sandbox_set_bind_validator(struct pt_sandbox
* p_sandbox
,
1467 ptrace_sandbox_validator_t val
,
1476 ptrace_sandbox_permit_connect(struct pt_sandbox
* p_sandbox
)
1482 ptrace_sandbox_set_connect_validator(struct pt_sandbox
* p_sandbox
,
1483 ptrace_sandbox_validator_t val
,
1492 ptrace_sandbox_permit_listen(struct pt_sandbox
* p_sandbox
)
1498 ptrace_sandbox_permit_accept(struct pt_sandbox
* p_sandbox
)
1504 ptrace_sandbox_permit_setsockopt(struct pt_sandbox
* p_sandbox
)
1510 ptrace_sandbox_set_setsockopt_validator(struct pt_sandbox
* p_sandbox
,
1511 ptrace_sandbox_validator_t val
,
1520 ptrace_sandbox_permit_getsockopt(struct pt_sandbox
* p_sandbox
)
1526 ptrace_sandbox_set_getsockopt_validator(struct pt_sandbox
* p_sandbox
,
1527 ptrace_sandbox_validator_t val
,
1536 ptrace_sandbox_permit_shutdown(struct pt_sandbox
* p_sandbox
)
1541 #endif /* __linux__ && __i386__ */