version 1.3, 2011/06/23 09:34:13 |
version 1.4, 2011/07/29 14:42:45 |
|
|
#include "ssh-sandbox.h" |
#include "ssh-sandbox.h" |
#include "xmalloc.h" |
#include "xmalloc.h" |
|
|
static const int preauth_policy[] = { |
struct sandbox_policy { |
SYS___sysctl, |
int syscall; |
SYS_close, |
int action; |
SYS_exit, |
|
SYS_getpid, |
|
SYS_gettimeofday, |
|
SYS_madvise, |
|
SYS_mmap, |
|
SYS_mprotect, |
|
SYS_poll, |
|
SYS_munmap, |
|
SYS_read, |
|
SYS_select, |
|
SYS_sigprocmask, |
|
SYS_write, |
|
-1 |
|
}; |
}; |
|
|
|
/* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */ |
|
static const struct sandbox_policy preauth_policy[] = { |
|
{ SYS_open, SYSTR_POLICY_NEVER }, |
|
|
|
{ SYS___sysctl, SYSTR_POLICY_PERMIT }, |
|
{ SYS_close, SYSTR_POLICY_PERMIT }, |
|
{ SYS_exit, SYSTR_POLICY_PERMIT }, |
|
{ SYS_getpid, SYSTR_POLICY_PERMIT }, |
|
{ SYS_gettimeofday, SYSTR_POLICY_PERMIT }, |
|
{ SYS_madvise, SYSTR_POLICY_PERMIT }, |
|
{ SYS_mmap, SYSTR_POLICY_PERMIT }, |
|
{ SYS_mprotect, SYSTR_POLICY_PERMIT }, |
|
{ SYS_poll, SYSTR_POLICY_PERMIT }, |
|
{ SYS_munmap, SYSTR_POLICY_PERMIT }, |
|
{ SYS_read, SYSTR_POLICY_PERMIT }, |
|
{ SYS_select, SYSTR_POLICY_PERMIT }, |
|
{ SYS_sigprocmask, SYSTR_POLICY_PERMIT }, |
|
{ SYS_write, SYSTR_POLICY_PERMIT }, |
|
{ -1, -1 } |
|
}; |
|
|
struct ssh_sandbox { |
struct ssh_sandbox { |
int child_sock; |
int child_sock; |
int parent_sock; |
int parent_sock; |
int systrace_fd; |
int systrace_fd; |
pid_t child_pid; |
pid_t child_pid; |
struct systrace_policy policy; |
|
}; |
}; |
|
|
struct ssh_sandbox * |
struct ssh_sandbox * |
|
|
|
|
static void |
static void |
ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, |
ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, |
const int *allowed_syscalls) |
const struct sandbox_policy *allowed_syscalls) |
{ |
{ |
int dev_systrace, i, j, found; |
int dev_systrace, i, j, found; |
char whatever = 0; |
char whatever = 0; |
|
struct systrace_policy policy; |
|
|
debug3("%s: wait for child %ld", __func__, (long)child_pid); |
debug3("%s: wait for child %ld", __func__, (long)child_pid); |
box->child_pid = child_pid; |
box->child_pid = child_pid; |
|
|
box->systrace_fd, child_pid, strerror(errno)); |
box->systrace_fd, child_pid, strerror(errno)); |
|
|
/* Allocate and assign policy */ |
/* Allocate and assign policy */ |
bzero(&box->policy, sizeof(box->policy)); |
bzero(&policy, sizeof(policy)); |
box->policy.strp_op = SYSTR_POLICY_NEW; |
policy.strp_op = SYSTR_POLICY_NEW; |
box->policy.strp_maxents = SYS_MAXSYSCALL; |
policy.strp_maxents = SYS_MAXSYSCALL; |
if (ioctl(box->systrace_fd, STRIOCPOLICY, &box->policy) == -1) |
if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) |
fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__, |
fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__, |
box->systrace_fd, strerror(errno)); |
box->systrace_fd, strerror(errno)); |
|
|
box->policy.strp_op = SYSTR_POLICY_ASSIGN; |
policy.strp_op = SYSTR_POLICY_ASSIGN; |
box->policy.strp_pid = box->child_pid; |
policy.strp_pid = box->child_pid; |
if (ioctl(box->systrace_fd, STRIOCPOLICY, &box->policy) == -1) |
if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) |
fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s", |
fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s", |
__func__, box->systrace_fd, strerror(errno)); |
__func__, box->systrace_fd, strerror(errno)); |
|
|
/* Set per-syscall policy */ |
/* Set per-syscall policy */ |
for (i = 0; i < SYS_MAXSYSCALL; i++) { |
for (i = 0; i < SYS_MAXSYSCALL; i++) { |
for (j = found = 0; allowed_syscalls[j] != -1 && !found; j++) { |
found = 0; |
if (allowed_syscalls[j] == i) |
for (j = 0; allowed_syscalls[j].syscall != -1; j++) { |
|
if (allowed_syscalls[j].syscall == i) { |
found = 1; |
found = 1; |
|
break; |
|
} |
} |
} |
box->policy.strp_op = SYSTR_POLICY_MODIFY; |
policy.strp_op = SYSTR_POLICY_MODIFY; |
box->policy.strp_code = i; |
policy.strp_code = i; |
box->policy.strp_policy = found ? |
policy.strp_policy = found ? |
SYSTR_POLICY_PERMIT : SYSTR_POLICY_KILL; |
allowed_syscalls[j].action : SYSTR_POLICY_KILL; |
if (found) |
if (found) |
debug3("%s: policy: enable syscall %d", __func__, i); |
debug3("%s: policy: enable syscall %d", __func__, i); |
if (ioctl(box->systrace_fd, STRIOCPOLICY, |
if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) |
&box->policy) == -1) |
|
fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s", |
fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s", |
__func__, box->systrace_fd, strerror(errno)); |
__func__, box->systrace_fd, strerror(errno)); |
} |
} |