summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in4
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure72
-rw-r--r--configure.ac47
-rw-r--r--debian/changelog4
-rw-r--r--debian/patches/sandbox-fallback.patch925
-rw-r--r--debian/patches/series1
-rw-r--r--sandbox-darwin.c54
-rw-r--r--sandbox-null.c35
-rw-r--r--sandbox-rlimit.c52
-rw-r--r--sandbox-seccomp-filter.c81
-rw-r--r--sandbox-systrace.c55
-rw-r--r--sandbox.c82
-rw-r--r--ssh-sandbox.h25
-rw-r--r--sshd.c2
15 files changed, 1285 insertions, 157 deletions
diff --git a/Makefile.in b/Makefile.in
index 80155cc77..e2d040ad5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -93,8 +93,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
93 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ 93 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
94 sftp-server.o sftp-common.o \ 94 sftp-server.o sftp-common.o \
95 roaming_common.o roaming_serv.o \ 95 roaming_common.o roaming_serv.o \
96 sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ 96 sandbox.o sandbox-null.o sandbox-rlimit.o sandbox-systrace.o \
97 sandbox-seccomp-filter.o 97 sandbox-darwin.o sandbox-seccomp-filter.o
98 98
99MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-vulnkey.1.out sshd_config.5.out ssh_config.5.out 99MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-vulnkey.1.out sshd_config.5.out ssh_config.5.out
100MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-vulnkey.1 sshd_config.5 ssh_config.5 100MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-vulnkey.1 sshd_config.5 ssh_config.5
diff --git a/config.h.in b/config.h.in
index e51117b81..b977a3424 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1365,9 +1365,6 @@
1365/* Sandbox using Darwin sandbox_init(3) */ 1365/* Sandbox using Darwin sandbox_init(3) */
1366#undef SANDBOX_DARWIN 1366#undef SANDBOX_DARWIN
1367 1367
1368/* no privsep sandboxing */
1369#undef SANDBOX_NULL
1370
1371/* Sandbox using setrlimit(2) */ 1368/* Sandbox using setrlimit(2) */
1372#undef SANDBOX_RLIMIT 1369#undef SANDBOX_RLIMIT
1373 1370
diff --git a/configure b/configure
index 4f4d596ab..dc98069c8 100755
--- a/configure
+++ b/configure
@@ -5598,48 +5598,6 @@ if test "x$ac_cv_have_decl_SECCOMP_MODE_FILTER" = xyes; then :
5598fi 5598fi
5599 5599
5600fi 5600fi
5601if test "x$have_seccomp_filter" = "x1" ; then
5602{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel for seccomp_filter support" >&5
5603$as_echo_n "checking kernel for seccomp_filter support... " >&6; }
5604if test "$cross_compiling" = yes; then :
5605 { $as_echo "$as_me:${as_lineno-$LINENO}: result: cross-compiling, assuming yes" >&5
5606$as_echo "cross-compiling, assuming yes" >&6; }
5607
5608else
5609 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
5610/* end confdefs.h. */
5611
5612 #include <errno.h>
5613 #include <linux/seccomp.h>
5614 #include <stdlib.h>
5615 #include <sys/prctl.h>
5616
5617int
5618main ()
5619{
5620 errno = 0;
5621 prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
5622 exit(errno == EFAULT ? 0 : 1);
5623 ;
5624 return 0;
5625}
5626_ACEOF
5627if ac_fn_c_try_run "$LINENO"; then :
5628 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
5629$as_echo "yes" >&6; }
5630else
5631
5632 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
5633$as_echo "no" >&6; }
5634 # Disable seccomp filter as a target
5635 have_seccomp_filter=0
5636
5637fi
5638rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
5639 conftest.$ac_objext conftest.beam conftest.$ac_ext
5640fi
5641
5642fi
5643 5601
5644use_stack_protector=1 5602use_stack_protector=1
5645 5603
@@ -11898,25 +11856,28 @@ if test "${with_sandbox+set}" = set; then :
11898 11856
11899fi 11857fi
11900 11858
11859SANDBOX_STYLE=""
11901if test "x$sandbox_arg" = "xsystrace" || \ 11860if test "x$sandbox_arg" = "xsystrace" || \
11902 ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then 11861 ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then
11903 test "x$have_systr_policy_kill" != "x1" && \ 11862 test "x$have_systr_policy_kill" != "x1" && \
11904 as_fn_error $? "systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" "$LINENO" 5 11863 as_fn_error $? "systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" "$LINENO" 5
11905 SANDBOX_STYLE="systrace" 11864 SANDBOX_STYLE="$SANDBOX_STYLE systrace"
11906 11865
11907$as_echo "#define SANDBOX_SYSTRACE 1" >>confdefs.h 11866$as_echo "#define SANDBOX_SYSTRACE 1" >>confdefs.h
11908 11867
11909elif test "x$sandbox_arg" = "xdarwin" || \ 11868fi
11869if test "x$sandbox_arg" = "xdarwin" || \
11910 ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \ 11870 ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \
11911 test "x$ac_cv_header_sandbox_h" = "xyes") ; then 11871 test "x$ac_cv_header_sandbox_h" = "xyes") ; then
11912 test "x$ac_cv_func_sandbox_init" != "xyes" -o \ 11872 test "x$ac_cv_func_sandbox_init" != "xyes" -o \
11913 "x$ac_cv_header_sandbox_h" != "xyes" && \ 11873 "x$ac_cv_header_sandbox_h" != "xyes" && \
11914 as_fn_error $? "Darwin seatbelt sandbox requires sandbox.h and sandbox_init function" "$LINENO" 5 11874 as_fn_error $? "Darwin seatbelt sandbox requires sandbox.h and sandbox_init function" "$LINENO" 5
11915 SANDBOX_STYLE="darwin" 11875 SANDBOX_STYLE="$SANDBOX_STYLE darwin"
11916 11876
11917$as_echo "#define SANDBOX_DARWIN 1" >>confdefs.h 11877$as_echo "#define SANDBOX_DARWIN 1" >>confdefs.h
11918 11878
11919elif test "x$sandbox_arg" = "xseccomp_filter" || \ 11879fi
11880if test "x$sandbox_arg" = "xseccomp_filter" || \
11920 ( test -z "$sandbox_arg" && \ 11881 ( test -z "$sandbox_arg" && \
11921 test "x$have_seccomp_filter" = "x1" && \ 11882 test "x$have_seccomp_filter" = "x1" && \
11922 test "x$ac_cv_header_linux_audit_h" = "xyes" && \ 11883 test "x$ac_cv_header_linux_audit_h" = "xyes" && \
@@ -11931,27 +11892,28 @@ elif test "x$sandbox_arg" = "xseccomp_filter" || \
11931 as_fn_error $? "seccomp_filter sandbox requires seccomp headers" "$LINENO" 5 11892 as_fn_error $? "seccomp_filter sandbox requires seccomp headers" "$LINENO" 5
11932 test "x$ac_cv_func_prctl" != "xyes" && \ 11893 test "x$ac_cv_func_prctl" != "xyes" && \
11933 as_fn_error $? "seccomp_filter sandbox requires prctl function" "$LINENO" 5 11894 as_fn_error $? "seccomp_filter sandbox requires prctl function" "$LINENO" 5
11934 SANDBOX_STYLE="seccomp_filter" 11895 SANDBOX_STYLE="$SANDBOX_STYLE seccomp_filter"
11935 11896
11936$as_echo "#define SANDBOX_SECCOMP_FILTER 1" >>confdefs.h 11897$as_echo "#define SANDBOX_SECCOMP_FILTER 1" >>confdefs.h
11937 11898
11938elif test "x$sandbox_arg" = "xrlimit" || \ 11899fi
11900if test "x$sandbox_arg" = "xrlimit" || \
11939 ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" ) ; then 11901 ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" ) ; then
11940 test "x$ac_cv_func_setrlimit" != "xyes" && \ 11902 test "x$ac_cv_func_setrlimit" != "xyes" && \
11941 as_fn_error $? "rlimit sandbox requires setrlimit function" "$LINENO" 5 11903 as_fn_error $? "rlimit sandbox requires setrlimit function" "$LINENO" 5
11942 SANDBOX_STYLE="rlimit" 11904 SANDBOX_STYLE="$SANDBOX_STYLE rlimit"
11943 11905
11944$as_echo "#define SANDBOX_RLIMIT 1" >>confdefs.h 11906$as_echo "#define SANDBOX_RLIMIT 1" >>confdefs.h
11945 11907
11946elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ 11908fi
11909if test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
11947 test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then 11910 test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then
11948 SANDBOX_STYLE="none" 11911 SANDBOX_STYLE="$SANDBOX_STYLE none"
11949 11912fi
11950$as_echo "#define SANDBOX_NULL 1" >>confdefs.h 11913if test -z "$SANDBOX_STYLE" ; then
11951
11952else
11953 as_fn_error $? "unsupported --with-sandbox" "$LINENO" 5 11914 as_fn_error $? "unsupported --with-sandbox" "$LINENO" 5
11954fi 11915fi
11916SANDBOX_STYLE="${SANDBOX_STYLE# }"
11955 11917
11956# Cheap hack to ensure NEWS-OS libraries are arranged right. 11918# Cheap hack to ensure NEWS-OS libraries are arranged right.
11957if test ! -z "$SONY" ; then 11919if test ! -z "$SONY" ; then
diff --git a/configure.ac b/configure.ac
index 14d1d196b..dbbd6e857 100644
--- a/configure.ac
+++ b/configure.ac
@@ -126,25 +126,6 @@ AC_CHECK_DECL([SECCOMP_MODE_FILTER], [have_seccomp_filter=1], , [
126 #include <linux/seccomp.h> 126 #include <linux/seccomp.h>
127]) 127])
128fi 128fi
129if test "x$have_seccomp_filter" = "x1" ; then
130AC_MSG_CHECKING([kernel for seccomp_filter support])
131AC_RUN_IFELSE([AC_LANG_PROGRAM([[
132 #include <errno.h>
133 #include <linux/seccomp.h>
134 #include <stdlib.h>
135 #include <sys/prctl.h>
136 ]],
137 [[ errno = 0;
138 prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
139 exit(errno == EFAULT ? 0 : 1); ]])],
140 [ AC_MSG_RESULT([yes]) ], [
141 AC_MSG_RESULT([no])
142 # Disable seccomp filter as a target
143 have_seccomp_filter=0
144 ],
145 [ AC_MSG_RESULT([cross-compiling, assuming yes]) ]
146)
147fi
148 129
149use_stack_protector=1 130use_stack_protector=1
150AC_ARG_WITH([stackprotect], 131AC_ARG_WITH([stackprotect],
@@ -2599,21 +2580,24 @@ AC_ARG_WITH([sandbox],
2599 fi 2580 fi
2600 ] 2581 ]
2601) 2582)
2583SANDBOX_STYLE=""
2602if test "x$sandbox_arg" = "xsystrace" || \ 2584if test "x$sandbox_arg" = "xsystrace" || \
2603 ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then 2585 ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then
2604 test "x$have_systr_policy_kill" != "x1" && \ 2586 test "x$have_systr_policy_kill" != "x1" && \
2605 AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support]) 2587 AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support])
2606 SANDBOX_STYLE="systrace" 2588 SANDBOX_STYLE="$SANDBOX_STYLE systrace"
2607 AC_DEFINE([SANDBOX_SYSTRACE], [1], [Sandbox using systrace(4)]) 2589 AC_DEFINE([SANDBOX_SYSTRACE], [1], [Sandbox using systrace(4)])
2608elif test "x$sandbox_arg" = "xdarwin" || \ 2590fi
2591if test "x$sandbox_arg" = "xdarwin" || \
2609 ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \ 2592 ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \
2610 test "x$ac_cv_header_sandbox_h" = "xyes") ; then 2593 test "x$ac_cv_header_sandbox_h" = "xyes") ; then
2611 test "x$ac_cv_func_sandbox_init" != "xyes" -o \ 2594 test "x$ac_cv_func_sandbox_init" != "xyes" -o \
2612 "x$ac_cv_header_sandbox_h" != "xyes" && \ 2595 "x$ac_cv_header_sandbox_h" != "xyes" && \
2613 AC_MSG_ERROR([Darwin seatbelt sandbox requires sandbox.h and sandbox_init function]) 2596 AC_MSG_ERROR([Darwin seatbelt sandbox requires sandbox.h and sandbox_init function])
2614 SANDBOX_STYLE="darwin" 2597 SANDBOX_STYLE="$SANDBOX_STYLE darwin"
2615 AC_DEFINE([SANDBOX_DARWIN], [1], [Sandbox using Darwin sandbox_init(3)]) 2598 AC_DEFINE([SANDBOX_DARWIN], [1], [Sandbox using Darwin sandbox_init(3)])
2616elif test "x$sandbox_arg" = "xseccomp_filter" || \ 2599fi
2600if test "x$sandbox_arg" = "xseccomp_filter" || \
2617 ( test -z "$sandbox_arg" && \ 2601 ( test -z "$sandbox_arg" && \
2618 test "x$have_seccomp_filter" = "x1" && \ 2602 test "x$have_seccomp_filter" = "x1" && \
2619 test "x$ac_cv_header_linux_audit_h" = "xyes" && \ 2603 test "x$ac_cv_header_linux_audit_h" = "xyes" && \
@@ -2628,21 +2612,24 @@ elif test "x$sandbox_arg" = "xseccomp_filter" || \
2628 AC_MSG_ERROR([seccomp_filter sandbox requires seccomp headers]) 2612 AC_MSG_ERROR([seccomp_filter sandbox requires seccomp headers])
2629 test "x$ac_cv_func_prctl" != "xyes" && \ 2613 test "x$ac_cv_func_prctl" != "xyes" && \
2630 AC_MSG_ERROR([seccomp_filter sandbox requires prctl function]) 2614 AC_MSG_ERROR([seccomp_filter sandbox requires prctl function])
2631 SANDBOX_STYLE="seccomp_filter" 2615 SANDBOX_STYLE="$SANDBOX_STYLE seccomp_filter"
2632 AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter]) 2616 AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter])
2633elif test "x$sandbox_arg" = "xrlimit" || \ 2617fi
2618if test "x$sandbox_arg" = "xrlimit" || \
2634 ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" ) ; then 2619 ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" ) ; then
2635 test "x$ac_cv_func_setrlimit" != "xyes" && \ 2620 test "x$ac_cv_func_setrlimit" != "xyes" && \
2636 AC_MSG_ERROR([rlimit sandbox requires setrlimit function]) 2621 AC_MSG_ERROR([rlimit sandbox requires setrlimit function])
2637 SANDBOX_STYLE="rlimit" 2622 SANDBOX_STYLE="$SANDBOX_STYLE rlimit"
2638 AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)]) 2623 AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)])
2639elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ 2624fi
2625if test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
2640 test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then 2626 test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then
2641 SANDBOX_STYLE="none" 2627 SANDBOX_STYLE="$SANDBOX_STYLE none"
2642 AC_DEFINE([SANDBOX_NULL], [1], [no privsep sandboxing]) 2628fi
2643else 2629if test -z "$SANDBOX_STYLE" ; then
2644 AC_MSG_ERROR([unsupported --with-sandbox]) 2630 AC_MSG_ERROR([unsupported --with-sandbox])
2645fi 2631fi
2632SANDBOX_STYLE="${SANDBOX_STYLE# }"
2646 2633
2647# Cheap hack to ensure NEWS-OS libraries are arranged right. 2634# Cheap hack to ensure NEWS-OS libraries are arranged right.
2648if test ! -z "$SONY" ; then 2635if test ! -z "$SONY" ; then
diff --git a/debian/changelog b/debian/changelog
index 0e1b026d2..476ae4334 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -15,6 +15,10 @@ openssh (1:6.0p1-1) UNRELEASED; urgency=low
15 seccomp sandbox, automatically enabled on platforms that support it. 15 seccomp sandbox, automatically enabled on platforms that support it.
16 (Note: privilege separation sandboxing is still experimental.) 16 (Note: privilege separation sandboxing is still experimental.)
17 * Fix a bashism in configure's seccomp_filter check. 17 * Fix a bashism in configure's seccomp_filter check.
18 * Add a sandbox fallback mechanism, so that behaviour on Linux depends on
19 whether the running system's kernel has seccomp_filter support, not the
20 build system's kernel (forwarded upstream as
21 https://bugzilla.mindrot.org/show_bug.cgi?id=2011).
18 22
19 -- Colin Watson <cjwatson@debian.org> Sat, 21 Apr 2012 10:57:23 +0100 23 -- Colin Watson <cjwatson@debian.org> Sat, 21 Apr 2012 10:57:23 +0100
20 24
diff --git a/debian/patches/sandbox-fallback.patch b/debian/patches/sandbox-fallback.patch
new file mode 100644
index 000000000..124504b36
--- /dev/null
+++ b/debian/patches/sandbox-fallback.patch
@@ -0,0 +1,925 @@
1Description: Add a sandbox fallback mechanism
2Author: Colin Watson <cjwatson@debian.org>
3Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=2011
4Forwarded: https://bugzilla.mindrot.org/show_bug.cgi?id=2011
5Last-Update: 2012-05-26
6
7Index: b/Makefile.in
8===================================================================
9--- a/Makefile.in
10+++ b/Makefile.in
11@@ -93,8 +93,8 @@
12 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
13 sftp-server.o sftp-common.o \
14 roaming_common.o roaming_serv.o \
15- sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
16- sandbox-seccomp-filter.o
17+ sandbox.o sandbox-null.o sandbox-rlimit.o sandbox-systrace.o \
18+ sandbox-darwin.o sandbox-seccomp-filter.o
19
20 MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-vulnkey.1.out sshd_config.5.out ssh_config.5.out
21 MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-vulnkey.1 sshd_config.5 ssh_config.5
22Index: b/configure.ac
23===================================================================
24--- a/configure.ac
25+++ b/configure.ac
26@@ -126,25 +126,6 @@
27 #include <linux/seccomp.h>
28 ])
29 fi
30-if test "x$have_seccomp_filter" = "x1" ; then
31-AC_MSG_CHECKING([kernel for seccomp_filter support])
32-AC_RUN_IFELSE([AC_LANG_PROGRAM([[
33- #include <errno.h>
34- #include <linux/seccomp.h>
35- #include <stdlib.h>
36- #include <sys/prctl.h>
37- ]],
38- [[ errno = 0;
39- prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
40- exit(errno == EFAULT ? 0 : 1); ]])],
41- [ AC_MSG_RESULT([yes]) ], [
42- AC_MSG_RESULT([no])
43- # Disable seccomp filter as a target
44- have_seccomp_filter=0
45- ],
46- [ AC_MSG_RESULT([cross-compiling, assuming yes]) ]
47-)
48-fi
49
50 use_stack_protector=1
51 AC_ARG_WITH([stackprotect],
52@@ -2599,21 +2580,24 @@
53 fi
54 ]
55 )
56+SANDBOX_STYLE=""
57 if test "x$sandbox_arg" = "xsystrace" || \
58 ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then
59 test "x$have_systr_policy_kill" != "x1" && \
60 AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support])
61- SANDBOX_STYLE="systrace"
62+ SANDBOX_STYLE="$SANDBOX_STYLE systrace"
63 AC_DEFINE([SANDBOX_SYSTRACE], [1], [Sandbox using systrace(4)])
64-elif test "x$sandbox_arg" = "xdarwin" || \
65+fi
66+if test "x$sandbox_arg" = "xdarwin" || \
67 ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \
68 test "x$ac_cv_header_sandbox_h" = "xyes") ; then
69 test "x$ac_cv_func_sandbox_init" != "xyes" -o \
70 "x$ac_cv_header_sandbox_h" != "xyes" && \
71 AC_MSG_ERROR([Darwin seatbelt sandbox requires sandbox.h and sandbox_init function])
72- SANDBOX_STYLE="darwin"
73+ SANDBOX_STYLE="$SANDBOX_STYLE darwin"
74 AC_DEFINE([SANDBOX_DARWIN], [1], [Sandbox using Darwin sandbox_init(3)])
75-elif test "x$sandbox_arg" = "xseccomp_filter" || \
76+fi
77+if test "x$sandbox_arg" = "xseccomp_filter" || \
78 ( test -z "$sandbox_arg" && \
79 test "x$have_seccomp_filter" = "x1" && \
80 test "x$ac_cv_header_linux_audit_h" = "xyes" && \
81@@ -2628,21 +2612,24 @@
82 AC_MSG_ERROR([seccomp_filter sandbox requires seccomp headers])
83 test "x$ac_cv_func_prctl" != "xyes" && \
84 AC_MSG_ERROR([seccomp_filter sandbox requires prctl function])
85- SANDBOX_STYLE="seccomp_filter"
86+ SANDBOX_STYLE="$SANDBOX_STYLE seccomp_filter"
87 AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter])
88-elif test "x$sandbox_arg" = "xrlimit" || \
89+fi
90+if test "x$sandbox_arg" = "xrlimit" || \
91 ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" ) ; then
92 test "x$ac_cv_func_setrlimit" != "xyes" && \
93 AC_MSG_ERROR([rlimit sandbox requires setrlimit function])
94- SANDBOX_STYLE="rlimit"
95+ SANDBOX_STYLE="$SANDBOX_STYLE rlimit"
96 AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)])
97-elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
98+fi
99+if test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
100 test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then
101- SANDBOX_STYLE="none"
102- AC_DEFINE([SANDBOX_NULL], [1], [no privsep sandboxing])
103-else
104+ SANDBOX_STYLE="$SANDBOX_STYLE none"
105+fi
106+if test -z "$SANDBOX_STYLE" ; then
107 AC_MSG_ERROR([unsupported --with-sandbox])
108 fi
109+SANDBOX_STYLE="${SANDBOX_STYLE# }"
110
111 # Cheap hack to ensure NEWS-OS libraries are arranged right.
112 if test ! -z "$SONY" ; then
113Index: b/configure
114===================================================================
115--- a/configure
116+++ b/configure
117@@ -5598,48 +5598,6 @@
118 fi
119
120 fi
121-if test "x$have_seccomp_filter" = "x1" ; then
122-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel for seccomp_filter support" >&5
123-$as_echo_n "checking kernel for seccomp_filter support... " >&6; }
124-if test "$cross_compiling" = yes; then :
125- { $as_echo "$as_me:${as_lineno-$LINENO}: result: cross-compiling, assuming yes" >&5
126-$as_echo "cross-compiling, assuming yes" >&6; }
127-
128-else
129- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
130-/* end confdefs.h. */
131-
132- #include <errno.h>
133- #include <linux/seccomp.h>
134- #include <stdlib.h>
135- #include <sys/prctl.h>
136-
137-int
138-main ()
139-{
140- errno = 0;
141- prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
142- exit(errno == EFAULT ? 0 : 1);
143- ;
144- return 0;
145-}
146-_ACEOF
147-if ac_fn_c_try_run "$LINENO"; then :
148- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
149-$as_echo "yes" >&6; }
150-else
151-
152- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
153-$as_echo "no" >&6; }
154- # Disable seccomp filter as a target
155- have_seccomp_filter=0
156-
157-fi
158-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
159- conftest.$ac_objext conftest.beam conftest.$ac_ext
160-fi
161-
162-fi
163
164 use_stack_protector=1
165
166@@ -11898,25 +11856,28 @@
167
168 fi
169
170+SANDBOX_STYLE=""
171 if test "x$sandbox_arg" = "xsystrace" || \
172 ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then
173 test "x$have_systr_policy_kill" != "x1" && \
174 as_fn_error $? "systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" "$LINENO" 5
175- SANDBOX_STYLE="systrace"
176+ SANDBOX_STYLE="$SANDBOX_STYLE systrace"
177
178 $as_echo "#define SANDBOX_SYSTRACE 1" >>confdefs.h
179
180-elif test "x$sandbox_arg" = "xdarwin" || \
181+fi
182+if test "x$sandbox_arg" = "xdarwin" || \
183 ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \
184 test "x$ac_cv_header_sandbox_h" = "xyes") ; then
185 test "x$ac_cv_func_sandbox_init" != "xyes" -o \
186 "x$ac_cv_header_sandbox_h" != "xyes" && \
187 as_fn_error $? "Darwin seatbelt sandbox requires sandbox.h and sandbox_init function" "$LINENO" 5
188- SANDBOX_STYLE="darwin"
189+ SANDBOX_STYLE="$SANDBOX_STYLE darwin"
190
191 $as_echo "#define SANDBOX_DARWIN 1" >>confdefs.h
192
193-elif test "x$sandbox_arg" = "xseccomp_filter" || \
194+fi
195+if test "x$sandbox_arg" = "xseccomp_filter" || \
196 ( test -z "$sandbox_arg" && \
197 test "x$have_seccomp_filter" = "x1" && \
198 test "x$ac_cv_header_linux_audit_h" = "xyes" && \
199@@ -11931,27 +11892,28 @@
200 as_fn_error $? "seccomp_filter sandbox requires seccomp headers" "$LINENO" 5
201 test "x$ac_cv_func_prctl" != "xyes" && \
202 as_fn_error $? "seccomp_filter sandbox requires prctl function" "$LINENO" 5
203- SANDBOX_STYLE="seccomp_filter"
204+ SANDBOX_STYLE="$SANDBOX_STYLE seccomp_filter"
205
206 $as_echo "#define SANDBOX_SECCOMP_FILTER 1" >>confdefs.h
207
208-elif test "x$sandbox_arg" = "xrlimit" || \
209+fi
210+if test "x$sandbox_arg" = "xrlimit" || \
211 ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" ) ; then
212 test "x$ac_cv_func_setrlimit" != "xyes" && \
213 as_fn_error $? "rlimit sandbox requires setrlimit function" "$LINENO" 5
214- SANDBOX_STYLE="rlimit"
215+ SANDBOX_STYLE="$SANDBOX_STYLE rlimit"
216
217 $as_echo "#define SANDBOX_RLIMIT 1" >>confdefs.h
218
219-elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
220+fi
221+if test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
222 test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then
223- SANDBOX_STYLE="none"
224-
225-$as_echo "#define SANDBOX_NULL 1" >>confdefs.h
226-
227-else
228+ SANDBOX_STYLE="$SANDBOX_STYLE none"
229+fi
230+if test -z "$SANDBOX_STYLE" ; then
231 as_fn_error $? "unsupported --with-sandbox" "$LINENO" 5
232 fi
233+SANDBOX_STYLE="${SANDBOX_STYLE# }"
234
235 # Cheap hack to ensure NEWS-OS libraries are arranged right.
236 if test ! -z "$SONY" ; then
237Index: b/config.h.in
238===================================================================
239--- a/config.h.in
240+++ b/config.h.in
241@@ -1365,9 +1365,6 @@
242 /* Sandbox using Darwin sandbox_init(3) */
243 #undef SANDBOX_DARWIN
244
245-/* no privsep sandboxing */
246-#undef SANDBOX_NULL
247-
248 /* Sandbox using setrlimit(2) */
249 #undef SANDBOX_RLIMIT
250
251Index: b/sandbox-darwin.c
252===================================================================
253--- a/sandbox-darwin.c
254+++ b/sandbox-darwin.c
255@@ -16,10 +16,12 @@
256
257 #include "includes.h"
258
259-#ifdef SANDBOX_DARWIN
260-
261 #include <sys/types.h>
262
263+#include "ssh-sandbox.h"
264+
265+#ifdef SANDBOX_DARWIN
266+
267 #include <sandbox.h>
268
269 #include <errno.h>
270@@ -30,7 +32,6 @@
271 #include <unistd.h>
272
273 #include "log.h"
274-#include "sandbox.h"
275 #include "xmalloc.h"
276
277 /* Darwin/OS X sandbox */
278@@ -39,8 +40,14 @@
279 pid_t child_pid;
280 };
281
282-struct ssh_sandbox *
283-ssh_sandbox_init(void)
284+static int
285+sandbox_darwin_probe(void)
286+{
287+ return 1;
288+}
289+
290+static void *
291+sandbox_darwin_init(void)
292 {
293 struct ssh_sandbox *box;
294
295@@ -55,9 +62,10 @@
296 return box;
297 }
298
299-void
300-ssh_sandbox_child(struct ssh_sandbox *box)
301+static void
302+sandbox_darwin_child(void *vbox)
303 {
304+ struct ssh_sandbox *box = vbox;
305 char *errmsg;
306 struct rlimit rl_zero;
307
308@@ -82,17 +90,39 @@
309 __func__, strerror(errno));
310 }
311
312-void
313-ssh_sandbox_parent_finish(struct ssh_sandbox *box)
314+static void
315+sandbox_darwin_parent_finish(void *vbox)
316 {
317- free(box);
318+ free(vbox);
319 debug3("%s: finished", __func__);
320 }
321
322-void
323-ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
324+static void
325+sandbox_darwin_parent_preauth(void *box, pid_t child_pid)
326 {
327+ struct ssh_sandbox *box = vbox;
328+
329 box->child_pid = child_pid;
330 }
331
332+Sandbox ssh_sandbox_darwin = {
333+ "darwin",
334+ sandbox_darwin_probe,
335+ sandbox_darwin_init,
336+ sandbox_darwin_child,
337+ sandbox_darwin_parent_finish,
338+ sandbox_darwin_parent_preauth
339+};
340+
341+#else /* !SANDBOX_DARWIN */
342+
343+Sandbox ssh_sandbox_darwin = {
344+ "darwin",
345+ NULL,
346+ NULL,
347+ NULL,
348+ NULL,
349+ NULL
350+};
351+
352 #endif /* SANDBOX_DARWIN */
353Index: b/sandbox-null.c
354===================================================================
355--- a/sandbox-null.c
356+++ b/sandbox-null.c
357@@ -17,8 +17,6 @@
358
359 #include "includes.h"
360
361-#ifdef SANDBOX_NULL
362-
363 #include <sys/types.h>
364
365 #include <errno.h>
366@@ -38,8 +36,14 @@
367 int junk;
368 };
369
370-struct ssh_sandbox *
371-ssh_sandbox_init(void)
372+static int
373+sandbox_null_probe(void)
374+{
375+ return 1;
376+}
377+
378+static void *
379+sandbox_null_init(void)
380 {
381 struct ssh_sandbox *box;
382
383@@ -51,22 +55,29 @@
384 return box;
385 }
386
387-void
388-ssh_sandbox_child(struct ssh_sandbox *box)
389+static void
390+sandbox_null_child(void *vbox)
391 {
392 /* Nothing to do here */
393 }
394
395-void
396-ssh_sandbox_parent_finish(struct ssh_sandbox *box)
397+static void
398+sandbox_null_parent_finish(void *vbox)
399 {
400- free(box);
401+ free(vbox);
402 }
403
404-void
405-ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
406+static void
407+sandbox_null_parent_preauth(void *box, pid_t child_pid)
408 {
409 /* Nothing to do here */
410 }
411
412-#endif /* SANDBOX_NULL */
413+Sandbox ssh_sandbox_null = {
414+ "null",
415+ sandbox_null_probe,
416+ sandbox_null_init,
417+ sandbox_null_child,
418+ sandbox_null_parent_finish,
419+ sandbox_null_parent_preauth
420+};
421Index: b/sandbox-rlimit.c
422===================================================================
423--- a/sandbox-rlimit.c
424+++ b/sandbox-rlimit.c
425@@ -17,9 +17,12 @@
426
427 #include "includes.h"
428
429+#include <sys/types.h>
430+
431+#include "ssh-sandbox.h"
432+
433 #ifdef SANDBOX_RLIMIT
434
435-#include <sys/types.h>
436 #include <sys/param.h>
437 #include <sys/time.h>
438 #include <sys/resource.h>
439@@ -32,7 +35,6 @@
440 #include <unistd.h>
441
442 #include "log.h"
443-#include "ssh-sandbox.h"
444 #include "xmalloc.h"
445
446 /* Minimal sandbox that sets zero nfiles, nprocs and filesize rlimits */
447@@ -41,8 +43,14 @@
448 pid_t child_pid;
449 };
450
451-struct ssh_sandbox *
452-ssh_sandbox_init(void)
453+static int
454+sandbox_rlimit_probe(void)
455+{
456+ return 1;
457+}
458+
459+static void *
460+sandbox_rlimit_init(void)
461 {
462 struct ssh_sandbox *box;
463
464@@ -57,8 +65,8 @@
465 return box;
466 }
467
468-void
469-ssh_sandbox_child(struct ssh_sandbox *box)
470+static void
471+sandbox_rlimit_child(void *vbox)
472 {
473 struct rlimit rl_zero;
474
475@@ -77,17 +85,39 @@
476 #endif
477 }
478
479-void
480-ssh_sandbox_parent_finish(struct ssh_sandbox *box)
481+static void
482+sandbox_rlimit_parent_finish(void *vbox)
483 {
484- free(box);
485+ free(vbox);
486 debug3("%s: finished", __func__);
487 }
488
489-void
490-ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
491+static void
492+sandbox_rlimit_parent_preauth(void *vbox, pid_t child_pid)
493 {
494+ struct ssh_sandbox *box = vbox;
495+
496 box->child_pid = child_pid;
497 }
498
499+Sandbox ssh_sandbox_rlimit = {
500+ "rlimit",
501+ sandbox_rlimit_probe,
502+ sandbox_rlimit_init,
503+ sandbox_rlimit_child,
504+ sandbox_rlimit_parent_finish,
505+ sandbox_rlimit_parent_preauth
506+};
507+
508+#else /* !SANDBOX_RLIMIT */
509+
510+Sandbox ssh_sandbox_rlimit = {
511+ "rlimit",
512+ NULL,
513+ NULL,
514+ NULL,
515+ NULL,
516+ NULL
517+};
518+
519 #endif /* SANDBOX_RLIMIT */
520Index: b/sandbox-seccomp-filter.c
521===================================================================
522--- a/sandbox-seccomp-filter.c
523+++ b/sandbox-seccomp-filter.c
524@@ -35,11 +35,15 @@
525
526 #include "includes.h"
527
528+#include <sys/types.h>
529+
530+#include "ssh-sandbox.h"
531+
532 #ifdef SANDBOX_SECCOMP_FILTER
533
534-#include <sys/types.h>
535 #include <sys/resource.h>
536 #include <sys/prctl.h>
537+#include <sys/wait.h>
538
539 #include <linux/audit.h>
540 #include <linux/filter.h>
541@@ -57,7 +61,6 @@
542 #include <unistd.h>
543
544 #include "log.h"
545-#include "ssh-sandbox.h"
546 #include "xmalloc.h"
547
548 /* Linux seccomp_filter sandbox */
549@@ -122,8 +125,33 @@
550 pid_t child_pid;
551 };
552
553-struct ssh_sandbox *
554-ssh_sandbox_init(void)
555+static int
556+sandbox_seccomp_filter_probe(void)
557+{
558+ int status;
559+ pid_t pid;
560+
561+ pid = fork();
562+ if (pid == -1) {
563+ fatal("fork of seccomp_filter probe child failed");
564+ } else if (pid != 0) {
565+ /* parent */
566+ while (waitpid(pid, &status, 0) < 0) {
567+ if (errno == EINTR)
568+ continue;
569+ fatal("%s: waitpid: %s", __func__, strerror(errno));
570+ }
571+ return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
572+ } else {
573+ /* child */
574+ errno = 0;
575+ prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
576+ _exit(errno == EFAULT ? 0 : 1);
577+ }
578+}
579+
580+static void *
581+sandbox_seccomp_filter_init(void)
582 {
583 struct ssh_sandbox *box;
584
585@@ -143,7 +171,8 @@
586 void mm_log_handler(LogLevel level, const char *msg, void *ctx);
587
588 static void
589-ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context)
590+sandbox_seccomp_filter_violation(int signum, siginfo_t *info,
591+ void *void_context)
592 {
593 char msg[256];
594
595@@ -155,7 +184,7 @@
596 }
597
598 static void
599-ssh_sandbox_child_debugging(void)
600+sandbox_seccomp_filter_child_debugging(void)
601 {
602 struct sigaction act;
603 sigset_t mask;
604@@ -165,7 +194,7 @@
605 sigemptyset(&mask);
606 sigaddset(&mask, SIGSYS);
607
608- act.sa_sigaction = &ssh_sandbox_violation;
609+ act.sa_sigaction = &sandbox_seccomp_filter_violation;
610 act.sa_flags = SA_SIGINFO;
611 if (sigaction(SIGSYS, &act, NULL) == -1)
612 fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno));
613@@ -175,8 +204,8 @@
614 }
615 #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
616
617-void
618-ssh_sandbox_child(struct ssh_sandbox *box)
619+static void
620+sandbox_seccomp_filter_child(void *vbox)
621 {
622 struct rlimit rl_zero;
623
624@@ -193,7 +222,7 @@
625 __func__, strerror(errno));
626
627 #ifdef SANDBOX_SECCOMP_FILTER_DEBUG
628- ssh_sandbox_child_debugging();
629+ sandbox_seccomp_filter_child_debugging();
630 #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
631
632 debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__);
633@@ -206,17 +235,39 @@
634 __func__, strerror(errno));
635 }
636
637-void
638-ssh_sandbox_parent_finish(struct ssh_sandbox *box)
639+static void
640+sandbox_seccomp_filter_parent_finish(void *vbox)
641 {
642- free(box);
643+ free(vbox);
644 debug3("%s: finished", __func__);
645 }
646
647-void
648-ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
649+static void
650+sandbox_seccomp_filter_parent_preauth(void *vbox, pid_t child_pid)
651 {
652+ struct ssh_sandbox *box = vbox;
653+
654 box->child_pid = child_pid;
655 }
656
657+Sandbox ssh_sandbox_seccomp_filter = {
658+ "seccomp_filter",
659+ sandbox_seccomp_filter_probe,
660+ sandbox_seccomp_filter_init,
661+ sandbox_seccomp_filter_child,
662+ sandbox_seccomp_filter_parent_finish,
663+ sandbox_seccomp_filter_parent_preauth
664+};
665+
666+#else /* !SANDBOX_SECCOMP_FILTER */
667+
668+Sandbox ssh_sandbox_seccomp_filter = {
669+ "seccomp_filter",
670+ NULL,
671+ NULL,
672+ NULL,
673+ NULL,
674+ NULL
675+};
676+
677 #endif /* SANDBOX_SECCOMP_FILTER */
678Index: b/sandbox-systrace.c
679===================================================================
680--- a/sandbox-systrace.c
681+++ b/sandbox-systrace.c
682@@ -17,9 +17,12 @@
683
684 #include "includes.h"
685
686+#include <sys/types.h>
687+
688+#include "ssh-sandbox.h"
689+
690 #ifdef SANDBOX_SYSTRACE
691
692-#include <sys/types.h>
693 #include <sys/param.h>
694 #include <sys/ioctl.h>
695 #include <sys/syscall.h>
696@@ -38,7 +41,6 @@
697
698 #include "atomicio.h"
699 #include "log.h"
700-#include "ssh-sandbox.h"
701 #include "xmalloc.h"
702
703 struct sandbox_policy {
704@@ -74,8 +76,14 @@
705 pid_t child_pid;
706 };
707
708-struct ssh_sandbox *
709-ssh_sandbox_init(void)
710+static int
711+sandbox_systrace_probe(void)
712+{
713+ return 1;
714+}
715+
716+static void *
717+sandbox_systrace_init(void)
718 {
719 struct ssh_sandbox *box;
720 int s[2];
721@@ -92,9 +100,10 @@
722 return box;
723 }
724
725-void
726-ssh_sandbox_child(struct ssh_sandbox *box)
727+static void
728+sandbox_systrace_child(void *vbox)
729 {
730+ struct ssh_sandbox *box = vbox;
731 char whatever = 0;
732
733 close(box->parent_sock);
734@@ -110,7 +119,7 @@
735 }
736
737 static void
738-ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
739+sandbox_systrace_parent(struct ssh_sandbox *box, pid_t child_pid,
740 const struct sandbox_policy *allowed_syscalls)
741 {
742 int dev_systrace, i, j, found;
743@@ -179,9 +188,11 @@
744 close(box->parent_sock);
745 }
746
747-void
748-ssh_sandbox_parent_finish(struct ssh_sandbox *box)
749+static void
750+sandbox_systrace_parent_finish(void *vbox)
751 {
752+ struct ssh_sandbox *box = vbox;
753+
754 /* Closing this before the child exits will terminate it */
755 close(box->systrace_fd);
756
757@@ -189,10 +200,32 @@
758 debug3("%s: finished", __func__);
759 }
760
761-void
762-ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
763+static void
764+sandbox_systrace_parent_preauth(void *vbox, pid_t child_pid)
765 {
766+ struct ssh_sandbox *box = vbox;
767+
768 ssh_sandbox_parent(box, child_pid, preauth_policy);
769 }
770
771+Sandbox ssh_sandbox_systrace = {
772+ "systrace",
773+ sandbox_systrace_probe,
774+ sandbox_systrace_init,
775+ sandbox_systrace_child,
776+ sandbox_systrace_parent_finish,
777+ sandbox_systrace_parent_preauth
778+};
779+
780+#else /* !SANDBOX_SYSTRACE */
781+
782+Sandbox ssh_sandbox_systrace = {
783+ "systrace",
784+ NULL,
785+ NULL,
786+ NULL,
787+ NULL,
788+ NULL
789+};
790+
791 #endif /* SANDBOX_SYSTRACE */
792Index: b/sandbox.c
793===================================================================
794--- /dev/null
795+++ b/sandbox.c
796@@ -0,0 +1,82 @@
797+/* $Id$ */
798+/*
799+ * Copyright (c) 2012 Colin Watson <cjwatson@debian.org>
800+ *
801+ * Permission to use, copy, modify, and distribute this software for any
802+ * purpose with or without fee is hereby granted, provided that the above
803+ * copyright notice and this permission notice appear in all copies.
804+ *
805+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
806+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
807+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
808+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
809+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
810+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
811+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
812+ */
813+
814+#include <sys/types.h>
815+
816+#include <stdlib.h>
817+#include <stdarg.h>
818+
819+#include "log.h"
820+#include "ssh-sandbox.h"
821+
822+static Sandbox *sandboxes[] = {
823+ &ssh_sandbox_systrace,
824+ &ssh_sandbox_darwin,
825+ &ssh_sandbox_seccomp_filter,
826+ &ssh_sandbox_rlimit,
827+ &ssh_sandbox_null,
828+ NULL
829+};
830+
831+static Sandbox *selected;
832+
833+static void
834+sandbox_select(void)
835+{
836+ Sandbox **sandbox;
837+
838+ if (selected)
839+ return;
840+
841+ for (sandbox = sandboxes; sandbox; sandbox++) {
842+ if ((*sandbox)->probe && (*sandbox)->probe()) {
843+ selected = *sandbox;
844+ return;
845+ }
846+ }
847+
848+ /* should never happen, as ssh_sandbox_null always succeeds */
849+ fatal("no sandbox implementation found");
850+}
851+
852+void *
853+ssh_sandbox_init(void)
854+{
855+ sandbox_select();
856+ return selected->init();
857+}
858+
859+void
860+ssh_sandbox_child(void *box)
861+{
862+ sandbox_select();
863+ return selected->child(box);
864+}
865+
866+void
867+ssh_sandbox_parent_finish(void *box)
868+{
869+ sandbox_select();
870+ return selected->parent_finish(box);
871+}
872+
873+void
874+ssh_sandbox_parent_preauth(void *box, pid_t child_pid)
875+{
876+ sandbox_select();
877+ return selected->parent_preauth(box, child_pid);
878+}
879Index: b/ssh-sandbox.h
880===================================================================
881--- a/ssh-sandbox.h
882+++ b/ssh-sandbox.h
883@@ -15,9 +15,24 @@
884 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
885 */
886
887-struct ssh_sandbox;
888+typedef struct Sandbox Sandbox;
889
890-struct ssh_sandbox *ssh_sandbox_init(void);
891-void ssh_sandbox_child(struct ssh_sandbox *);
892-void ssh_sandbox_parent_finish(struct ssh_sandbox *);
893-void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t);
894+struct Sandbox {
895+ const char *name;
896+ int (*probe)(void);
897+ void *(*init)(void);
898+ void (*child)(void *);
899+ void (*parent_finish)(void *);
900+ void (*parent_preauth)(void *, pid_t);
901+};
902+
903+void *ssh_sandbox_init(void);
904+void ssh_sandbox_child(void *);
905+void ssh_sandbox_parent_finish(void *);
906+void ssh_sandbox_parent_preauth(void *, pid_t);
907+
908+extern Sandbox ssh_sandbox_systrace;
909+extern Sandbox ssh_sandbox_darwin;
910+extern Sandbox ssh_sandbox_seccomp_filter;
911+extern Sandbox ssh_sandbox_rlimit;
912+extern Sandbox ssh_sandbox_null;
913Index: b/sshd.c
914===================================================================
915--- a/sshd.c
916+++ b/sshd.c
917@@ -631,7 +631,7 @@
918 {
919 int status;
920 pid_t pid;
921- struct ssh_sandbox *box = NULL;
922+ void *box = NULL;
923
924 /* Set up unprivileged child process to deal with network data */
925 pmonitor = monitor_init();
diff --git a/debian/patches/series b/debian/patches/series
index 772dadb61..d6bae11a0 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -39,6 +39,7 @@ doc-hash-tab-completion.patch
39auth-log-verbosity.patch 39auth-log-verbosity.patch
40cross-pkg-config.patch 40cross-pkg-config.patch
41configure-bashism.patch 41configure-bashism.patch
42sandbox-fallback.patch
42 43
43# Debian-specific configuration 44# Debian-specific configuration
44gnome-ssh-askpass2-icon.patch 45gnome-ssh-askpass2-icon.patch
diff --git a/sandbox-darwin.c b/sandbox-darwin.c
index 69901ef14..49330642b 100644
--- a/sandbox-darwin.c
+++ b/sandbox-darwin.c
@@ -16,10 +16,12 @@
16 16
17#include "includes.h" 17#include "includes.h"
18 18
19#ifdef SANDBOX_DARWIN
20
21#include <sys/types.h> 19#include <sys/types.h>
22 20
21#include "ssh-sandbox.h"
22
23#ifdef SANDBOX_DARWIN
24
23#include <sandbox.h> 25#include <sandbox.h>
24 26
25#include <errno.h> 27#include <errno.h>
@@ -30,7 +32,6 @@
30#include <unistd.h> 32#include <unistd.h>
31 33
32#include "log.h" 34#include "log.h"
33#include "sandbox.h"
34#include "xmalloc.h" 35#include "xmalloc.h"
35 36
36/* Darwin/OS X sandbox */ 37/* Darwin/OS X sandbox */
@@ -39,8 +40,14 @@ struct ssh_sandbox {
39 pid_t child_pid; 40 pid_t child_pid;
40}; 41};
41 42
42struct ssh_sandbox * 43static int
43ssh_sandbox_init(void) 44sandbox_darwin_probe(void)
45{
46 return 1;
47}
48
49static void *
50sandbox_darwin_init(void)
44{ 51{
45 struct ssh_sandbox *box; 52 struct ssh_sandbox *box;
46 53
@@ -55,9 +62,10 @@ ssh_sandbox_init(void)
55 return box; 62 return box;
56} 63}
57 64
58void 65static void
59ssh_sandbox_child(struct ssh_sandbox *box) 66sandbox_darwin_child(void *vbox)
60{ 67{
68 struct ssh_sandbox *box = vbox;
61 char *errmsg; 69 char *errmsg;
62 struct rlimit rl_zero; 70 struct rlimit rl_zero;
63 71
@@ -82,17 +90,39 @@ ssh_sandbox_child(struct ssh_sandbox *box)
82 __func__, strerror(errno)); 90 __func__, strerror(errno));
83} 91}
84 92
85void 93static void
86ssh_sandbox_parent_finish(struct ssh_sandbox *box) 94sandbox_darwin_parent_finish(void *vbox)
87{ 95{
88 free(box); 96 free(vbox);
89 debug3("%s: finished", __func__); 97 debug3("%s: finished", __func__);
90} 98}
91 99
92void 100static void
93ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) 101sandbox_darwin_parent_preauth(void *box, pid_t child_pid)
94{ 102{
103 struct ssh_sandbox *box = vbox;
104
95 box->child_pid = child_pid; 105 box->child_pid = child_pid;
96} 106}
97 107
108Sandbox ssh_sandbox_darwin = {
109 "darwin",
110 sandbox_darwin_probe,
111 sandbox_darwin_init,
112 sandbox_darwin_child,
113 sandbox_darwin_parent_finish,
114 sandbox_darwin_parent_preauth
115};
116
117#else /* !SANDBOX_DARWIN */
118
119Sandbox ssh_sandbox_darwin = {
120 "darwin",
121 NULL,
122 NULL,
123 NULL,
124 NULL,
125 NULL
126};
127
98#endif /* SANDBOX_DARWIN */ 128#endif /* SANDBOX_DARWIN */
diff --git a/sandbox-null.c b/sandbox-null.c
index 29fa9669f..f62ac4b07 100644
--- a/sandbox-null.c
+++ b/sandbox-null.c
@@ -17,8 +17,6 @@
17 17
18#include "includes.h" 18#include "includes.h"
19 19
20#ifdef SANDBOX_NULL
21
22#include <sys/types.h> 20#include <sys/types.h>
23 21
24#include <errno.h> 22#include <errno.h>
@@ -38,8 +36,14 @@ struct ssh_sandbox {
38 int junk; 36 int junk;
39}; 37};
40 38
41struct ssh_sandbox * 39static int
42ssh_sandbox_init(void) 40sandbox_null_probe(void)
41{
42 return 1;
43}
44
45static void *
46sandbox_null_init(void)
43{ 47{
44 struct ssh_sandbox *box; 48 struct ssh_sandbox *box;
45 49
@@ -51,22 +55,29 @@ ssh_sandbox_init(void)
51 return box; 55 return box;
52} 56}
53 57
54void 58static void
55ssh_sandbox_child(struct ssh_sandbox *box) 59sandbox_null_child(void *vbox)
56{ 60{
57 /* Nothing to do here */ 61 /* Nothing to do here */
58} 62}
59 63
60void 64static void
61ssh_sandbox_parent_finish(struct ssh_sandbox *box) 65sandbox_null_parent_finish(void *vbox)
62{ 66{
63 free(box); 67 free(vbox);
64} 68}
65 69
66void 70static void
67ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) 71sandbox_null_parent_preauth(void *box, pid_t child_pid)
68{ 72{
69 /* Nothing to do here */ 73 /* Nothing to do here */
70} 74}
71 75
72#endif /* SANDBOX_NULL */ 76Sandbox ssh_sandbox_null = {
77 "null",
78 sandbox_null_probe,
79 sandbox_null_init,
80 sandbox_null_child,
81 sandbox_null_parent_finish,
82 sandbox_null_parent_preauth
83};
diff --git a/sandbox-rlimit.c b/sandbox-rlimit.c
index 761e9284f..bfd1d446e 100644
--- a/sandbox-rlimit.c
+++ b/sandbox-rlimit.c
@@ -17,9 +17,12 @@
17 17
18#include "includes.h" 18#include "includes.h"
19 19
20#include <sys/types.h>
21
22#include "ssh-sandbox.h"
23
20#ifdef SANDBOX_RLIMIT 24#ifdef SANDBOX_RLIMIT
21 25
22#include <sys/types.h>
23#include <sys/param.h> 26#include <sys/param.h>
24#include <sys/time.h> 27#include <sys/time.h>
25#include <sys/resource.h> 28#include <sys/resource.h>
@@ -32,7 +35,6 @@
32#include <unistd.h> 35#include <unistd.h>
33 36
34#include "log.h" 37#include "log.h"
35#include "ssh-sandbox.h"
36#include "xmalloc.h" 38#include "xmalloc.h"
37 39
38/* Minimal sandbox that sets zero nfiles, nprocs and filesize rlimits */ 40/* Minimal sandbox that sets zero nfiles, nprocs and filesize rlimits */
@@ -41,8 +43,14 @@ struct ssh_sandbox {
41 pid_t child_pid; 43 pid_t child_pid;
42}; 44};
43 45
44struct ssh_sandbox * 46static int
45ssh_sandbox_init(void) 47sandbox_rlimit_probe(void)
48{
49 return 1;
50}
51
52static void *
53sandbox_rlimit_init(void)
46{ 54{
47 struct ssh_sandbox *box; 55 struct ssh_sandbox *box;
48 56
@@ -57,8 +65,8 @@ ssh_sandbox_init(void)
57 return box; 65 return box;
58} 66}
59 67
60void 68static void
61ssh_sandbox_child(struct ssh_sandbox *box) 69sandbox_rlimit_child(void *vbox)
62{ 70{
63 struct rlimit rl_zero; 71 struct rlimit rl_zero;
64 72
@@ -77,17 +85,39 @@ ssh_sandbox_child(struct ssh_sandbox *box)
77#endif 85#endif
78} 86}
79 87
80void 88static void
81ssh_sandbox_parent_finish(struct ssh_sandbox *box) 89sandbox_rlimit_parent_finish(void *vbox)
82{ 90{
83 free(box); 91 free(vbox);
84 debug3("%s: finished", __func__); 92 debug3("%s: finished", __func__);
85} 93}
86 94
87void 95static void
88ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) 96sandbox_rlimit_parent_preauth(void *vbox, pid_t child_pid)
89{ 97{
98 struct ssh_sandbox *box = vbox;
99
90 box->child_pid = child_pid; 100 box->child_pid = child_pid;
91} 101}
92 102
103Sandbox ssh_sandbox_rlimit = {
104 "rlimit",
105 sandbox_rlimit_probe,
106 sandbox_rlimit_init,
107 sandbox_rlimit_child,
108 sandbox_rlimit_parent_finish,
109 sandbox_rlimit_parent_preauth
110};
111
112#else /* !SANDBOX_RLIMIT */
113
114Sandbox ssh_sandbox_rlimit = {
115 "rlimit",
116 NULL,
117 NULL,
118 NULL,
119 NULL,
120 NULL
121};
122
93#endif /* SANDBOX_RLIMIT */ 123#endif /* SANDBOX_RLIMIT */
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index 686812957..a564b1316 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -35,11 +35,15 @@
35 35
36#include "includes.h" 36#include "includes.h"
37 37
38#include <sys/types.h>
39
40#include "ssh-sandbox.h"
41
38#ifdef SANDBOX_SECCOMP_FILTER 42#ifdef SANDBOX_SECCOMP_FILTER
39 43
40#include <sys/types.h>
41#include <sys/resource.h> 44#include <sys/resource.h>
42#include <sys/prctl.h> 45#include <sys/prctl.h>
46#include <sys/wait.h>
43 47
44#include <linux/audit.h> 48#include <linux/audit.h>
45#include <linux/filter.h> 49#include <linux/filter.h>
@@ -57,7 +61,6 @@
57#include <unistd.h> 61#include <unistd.h>
58 62
59#include "log.h" 63#include "log.h"
60#include "ssh-sandbox.h"
61#include "xmalloc.h" 64#include "xmalloc.h"
62 65
63/* Linux seccomp_filter sandbox */ 66/* Linux seccomp_filter sandbox */
@@ -122,8 +125,33 @@ struct ssh_sandbox {
122 pid_t child_pid; 125 pid_t child_pid;
123}; 126};
124 127
125struct ssh_sandbox * 128static int
126ssh_sandbox_init(void) 129sandbox_seccomp_filter_probe(void)
130{
131 int status;
132 pid_t pid;
133
134 pid = fork();
135 if (pid == -1) {
136 fatal("fork of seccomp_filter probe child failed");
137 } else if (pid != 0) {
138 /* parent */
139 while (waitpid(pid, &status, 0) < 0) {
140 if (errno == EINTR)
141 continue;
142 fatal("%s: waitpid: %s", __func__, strerror(errno));
143 }
144 return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
145 } else {
146 /* child */
147 errno = 0;
148 prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
149 _exit(errno == EFAULT ? 0 : 1);
150 }
151}
152
153static void *
154sandbox_seccomp_filter_init(void)
127{ 155{
128 struct ssh_sandbox *box; 156 struct ssh_sandbox *box;
129 157
@@ -143,7 +171,8 @@ extern struct monitor *pmonitor;
143void mm_log_handler(LogLevel level, const char *msg, void *ctx); 171void mm_log_handler(LogLevel level, const char *msg, void *ctx);
144 172
145static void 173static void
146ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context) 174sandbox_seccomp_filter_violation(int signum, siginfo_t *info,
175 void *void_context)
147{ 176{
148 char msg[256]; 177 char msg[256];
149 178
@@ -155,7 +184,7 @@ ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context)
155} 184}
156 185
157static void 186static void
158ssh_sandbox_child_debugging(void) 187sandbox_seccomp_filter_child_debugging(void)
159{ 188{
160 struct sigaction act; 189 struct sigaction act;
161 sigset_t mask; 190 sigset_t mask;
@@ -165,7 +194,7 @@ ssh_sandbox_child_debugging(void)
165 sigemptyset(&mask); 194 sigemptyset(&mask);
166 sigaddset(&mask, SIGSYS); 195 sigaddset(&mask, SIGSYS);
167 196
168 act.sa_sigaction = &ssh_sandbox_violation; 197 act.sa_sigaction = &sandbox_seccomp_filter_violation;
169 act.sa_flags = SA_SIGINFO; 198 act.sa_flags = SA_SIGINFO;
170 if (sigaction(SIGSYS, &act, NULL) == -1) 199 if (sigaction(SIGSYS, &act, NULL) == -1)
171 fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno)); 200 fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno));
@@ -175,8 +204,8 @@ ssh_sandbox_child_debugging(void)
175} 204}
176#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 205#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
177 206
178void 207static void
179ssh_sandbox_child(struct ssh_sandbox *box) 208sandbox_seccomp_filter_child(void *vbox)
180{ 209{
181 struct rlimit rl_zero; 210 struct rlimit rl_zero;
182 211
@@ -193,7 +222,7 @@ ssh_sandbox_child(struct ssh_sandbox *box)
193 __func__, strerror(errno)); 222 __func__, strerror(errno));
194 223
195#ifdef SANDBOX_SECCOMP_FILTER_DEBUG 224#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
196 ssh_sandbox_child_debugging(); 225 sandbox_seccomp_filter_child_debugging();
197#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 226#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
198 227
199 debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); 228 debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__);
@@ -206,17 +235,39 @@ ssh_sandbox_child(struct ssh_sandbox *box)
206 __func__, strerror(errno)); 235 __func__, strerror(errno));
207} 236}
208 237
209void 238static void
210ssh_sandbox_parent_finish(struct ssh_sandbox *box) 239sandbox_seccomp_filter_parent_finish(void *vbox)
211{ 240{
212 free(box); 241 free(vbox);
213 debug3("%s: finished", __func__); 242 debug3("%s: finished", __func__);
214} 243}
215 244
216void 245static void
217ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) 246sandbox_seccomp_filter_parent_preauth(void *vbox, pid_t child_pid)
218{ 247{
248 struct ssh_sandbox *box = vbox;
249
219 box->child_pid = child_pid; 250 box->child_pid = child_pid;
220} 251}
221 252
253Sandbox ssh_sandbox_seccomp_filter = {
254 "seccomp_filter",
255 sandbox_seccomp_filter_probe,
256 sandbox_seccomp_filter_init,
257 sandbox_seccomp_filter_child,
258 sandbox_seccomp_filter_parent_finish,
259 sandbox_seccomp_filter_parent_preauth
260};
261
262#else /* !SANDBOX_SECCOMP_FILTER */
263
264Sandbox ssh_sandbox_seccomp_filter = {
265 "seccomp_filter",
266 NULL,
267 NULL,
268 NULL,
269 NULL,
270 NULL
271};
272
222#endif /* SANDBOX_SECCOMP_FILTER */ 273#endif /* SANDBOX_SECCOMP_FILTER */
diff --git a/sandbox-systrace.c b/sandbox-systrace.c
index 5a39f4fe1..04f54a3b6 100644
--- a/sandbox-systrace.c
+++ b/sandbox-systrace.c
@@ -17,9 +17,12 @@
17 17
18#include "includes.h" 18#include "includes.h"
19 19
20#include <sys/types.h>
21
22#include "ssh-sandbox.h"
23
20#ifdef SANDBOX_SYSTRACE 24#ifdef SANDBOX_SYSTRACE
21 25
22#include <sys/types.h>
23#include <sys/param.h> 26#include <sys/param.h>
24#include <sys/ioctl.h> 27#include <sys/ioctl.h>
25#include <sys/syscall.h> 28#include <sys/syscall.h>
@@ -38,7 +41,6 @@
38 41
39#include "atomicio.h" 42#include "atomicio.h"
40#include "log.h" 43#include "log.h"
41#include "ssh-sandbox.h"
42#include "xmalloc.h" 44#include "xmalloc.h"
43 45
44struct sandbox_policy { 46struct sandbox_policy {
@@ -74,8 +76,14 @@ struct ssh_sandbox {
74 pid_t child_pid; 76 pid_t child_pid;
75}; 77};
76 78
77struct ssh_sandbox * 79static int
78ssh_sandbox_init(void) 80sandbox_systrace_probe(void)
81{
82 return 1;
83}
84
85static void *
86sandbox_systrace_init(void)
79{ 87{
80 struct ssh_sandbox *box; 88 struct ssh_sandbox *box;
81 int s[2]; 89 int s[2];
@@ -92,9 +100,10 @@ ssh_sandbox_init(void)
92 return box; 100 return box;
93} 101}
94 102
95void 103static void
96ssh_sandbox_child(struct ssh_sandbox *box) 104sandbox_systrace_child(void *vbox)
97{ 105{
106 struct ssh_sandbox *box = vbox;
98 char whatever = 0; 107 char whatever = 0;
99 108
100 close(box->parent_sock); 109 close(box->parent_sock);
@@ -110,7 +119,7 @@ ssh_sandbox_child(struct ssh_sandbox *box)
110} 119}
111 120
112static void 121static void
113ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, 122sandbox_systrace_parent(struct ssh_sandbox *box, pid_t child_pid,
114 const struct sandbox_policy *allowed_syscalls) 123 const struct sandbox_policy *allowed_syscalls)
115{ 124{
116 int dev_systrace, i, j, found; 125 int dev_systrace, i, j, found;
@@ -179,9 +188,11 @@ ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
179 close(box->parent_sock); 188 close(box->parent_sock);
180} 189}
181 190
182void 191static void
183ssh_sandbox_parent_finish(struct ssh_sandbox *box) 192sandbox_systrace_parent_finish(void *vbox)
184{ 193{
194 struct ssh_sandbox *box = vbox;
195
185 /* Closing this before the child exits will terminate it */ 196 /* Closing this before the child exits will terminate it */
186 close(box->systrace_fd); 197 close(box->systrace_fd);
187 198
@@ -189,10 +200,32 @@ ssh_sandbox_parent_finish(struct ssh_sandbox *box)
189 debug3("%s: finished", __func__); 200 debug3("%s: finished", __func__);
190} 201}
191 202
192void 203static void
193ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) 204sandbox_systrace_parent_preauth(void *vbox, pid_t child_pid)
194{ 205{
206 struct ssh_sandbox *box = vbox;
207
195 ssh_sandbox_parent(box, child_pid, preauth_policy); 208 ssh_sandbox_parent(box, child_pid, preauth_policy);
196} 209}
197 210
211Sandbox ssh_sandbox_systrace = {
212 "systrace",
213 sandbox_systrace_probe,
214 sandbox_systrace_init,
215 sandbox_systrace_child,
216 sandbox_systrace_parent_finish,
217 sandbox_systrace_parent_preauth
218};
219
220#else /* !SANDBOX_SYSTRACE */
221
222Sandbox ssh_sandbox_systrace = {
223 "systrace",
224 NULL,
225 NULL,
226 NULL,
227 NULL,
228 NULL
229};
230
198#endif /* SANDBOX_SYSTRACE */ 231#endif /* SANDBOX_SYSTRACE */
diff --git a/sandbox.c b/sandbox.c
new file mode 100644
index 000000000..20fd57d16
--- /dev/null
+++ b/sandbox.c
@@ -0,0 +1,82 @@
1/* $Id$ */
2/*
3 * Copyright (c) 2012 Colin Watson <cjwatson@debian.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19
20#include <stdlib.h>
21#include <stdarg.h>
22
23#include "log.h"
24#include "ssh-sandbox.h"
25
26static Sandbox *sandboxes[] = {
27 &ssh_sandbox_systrace,
28 &ssh_sandbox_darwin,
29 &ssh_sandbox_seccomp_filter,
30 &ssh_sandbox_rlimit,
31 &ssh_sandbox_null,
32 NULL
33};
34
35static Sandbox *selected;
36
37static void
38sandbox_select(void)
39{
40 Sandbox **sandbox;
41
42 if (selected)
43 return;
44
45 for (sandbox = sandboxes; sandbox; sandbox++) {
46 if ((*sandbox)->probe && (*sandbox)->probe()) {
47 selected = *sandbox;
48 return;
49 }
50 }
51
52 /* should never happen, as ssh_sandbox_null always succeeds */
53 fatal("no sandbox implementation found");
54}
55
56void *
57ssh_sandbox_init(void)
58{
59 sandbox_select();
60 return selected->init();
61}
62
63void
64ssh_sandbox_child(void *box)
65{
66 sandbox_select();
67 return selected->child(box);
68}
69
70void
71ssh_sandbox_parent_finish(void *box)
72{
73 sandbox_select();
74 return selected->parent_finish(box);
75}
76
77void
78ssh_sandbox_parent_preauth(void *box, pid_t child_pid)
79{
80 sandbox_select();
81 return selected->parent_preauth(box, child_pid);
82}
diff --git a/ssh-sandbox.h b/ssh-sandbox.h
index dfecd5aa0..7ee4460d8 100644
--- a/ssh-sandbox.h
+++ b/ssh-sandbox.h
@@ -15,9 +15,24 @@
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17 17
18struct ssh_sandbox; 18typedef struct Sandbox Sandbox;
19 19
20struct ssh_sandbox *ssh_sandbox_init(void); 20struct Sandbox {
21void ssh_sandbox_child(struct ssh_sandbox *); 21 const char *name;
22void ssh_sandbox_parent_finish(struct ssh_sandbox *); 22 int (*probe)(void);
23void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t); 23 void *(*init)(void);
24 void (*child)(void *);
25 void (*parent_finish)(void *);
26 void (*parent_preauth)(void *, pid_t);
27};
28
29void *ssh_sandbox_init(void);
30void ssh_sandbox_child(void *);
31void ssh_sandbox_parent_finish(void *);
32void ssh_sandbox_parent_preauth(void *, pid_t);
33
34extern Sandbox ssh_sandbox_systrace;
35extern Sandbox ssh_sandbox_darwin;
36extern Sandbox ssh_sandbox_seccomp_filter;
37extern Sandbox ssh_sandbox_rlimit;
38extern Sandbox ssh_sandbox_null;
diff --git a/sshd.c b/sshd.c
index e032c1720..038fb2a56 100644
--- a/sshd.c
+++ b/sshd.c
@@ -631,7 +631,7 @@ privsep_preauth(Authctxt *authctxt)
631{ 631{
632 int status; 632 int status;
633 pid_t pid; 633 pid_t pid;
634 struct ssh_sandbox *box = NULL; 634 void *box = NULL;
635 635
636 /* Set up unprivileged child process to deal with network data */ 636 /* Set up unprivileged child process to deal with network data */
637 pmonitor = monitor_init(); 637 pmonitor = monitor_init();