diff options
author | Damien Miller <djm@mindrot.org> | 2014-01-17 16:47:04 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-01-17 16:47:04 +1100 |
commit | 868ea1ea1c1bfdbee5dbad78f81999c5983ecf31 (patch) | |
tree | cd0d26dd73bc147951ef9a3aeb967448912e9c4f | |
parent | a9d186a8b50d18869a10e9203abf71c83ddb1f79 (diff) |
- (djm) [Makefile.in configure.ac sandbox-capsicum.c sandbox-darwin.c]
[sandbox-null.c sandbox-rlimit.c sandbox-seccomp-filter.c]
[sandbox-systrace.c ssh-sandbox.h sshd.c] Support preauth sandboxing
using the Capsicum API introduced in FreeBSD 10. Patch by Dag-Erling
Smorgrav, updated by Loganaden Velvindron @ AfriNIC; ok dtucker@
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Makefile.in | 5 | ||||
-rw-r--r-- | configure.ac | 17 | ||||
-rw-r--r-- | sandbox-capsicum.c | 118 | ||||
-rw-r--r-- | sandbox-darwin.c | 2 | ||||
-rw-r--r-- | sandbox-null.c | 2 | ||||
-rw-r--r-- | sandbox-rlimit.c | 2 | ||||
-rw-r--r-- | sandbox-seccomp-filter.c | 2 | ||||
-rw-r--r-- | sandbox-systrace.c | 2 | ||||
-rw-r--r-- | ssh-sandbox.h | 3 | ||||
-rw-r--r-- | sshd.c | 2 |
11 files changed, 147 insertions, 13 deletions
@@ -23,6 +23,11 @@ | |||
23 | - dtucker@cvs.openbsd.org 2014/01/17 05:26:41 | 23 | - dtucker@cvs.openbsd.org 2014/01/17 05:26:41 |
24 | [digest.c] | 24 | [digest.c] |
25 | remove unused includes. ok djm@ | 25 | remove unused includes. ok djm@ |
26 | - (djm) [Makefile.in configure.ac sandbox-capsicum.c sandbox-darwin.c] | ||
27 | [sandbox-null.c sandbox-rlimit.c sandbox-seccomp-filter.c] | ||
28 | [sandbox-systrace.c ssh-sandbox.h sshd.c] Support preauth sandboxing | ||
29 | using the Capsicum API introduced in FreeBSD 10. Patch by Dag-Erling | ||
30 | Smorgrav, updated by Loganaden Velvindron @ AfriNIC; ok dtucker@ | ||
26 | 31 | ||
27 | 20140118 | 32 | 20140118 |
28 | - (djm) OpenBSD CVS Sync | 33 | - (djm) OpenBSD CVS Sync |
diff --git a/Makefile.in b/Makefile.in index 4a930c665..f5dd3b834 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile.in,v 1.349 2014/01/09 23:58:53 djm Exp $ | 1 | # $Id: Makefile.in,v 1.350 2014/01/17 05:47:04 djm Exp $ |
2 | 2 | ||
3 | # uncomment if you run a non bourne compatable shell. Ie. csh | 3 | # uncomment if you run a non bourne compatable shell. Ie. csh |
4 | #SHELL = @SH@ | 4 | #SHELL = @SH@ |
@@ -96,7 +96,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ | |||
96 | sftp-server.o sftp-common.o \ | 96 | sftp-server.o sftp-common.o \ |
97 | roaming_common.o roaming_serv.o \ | 97 | roaming_common.o roaming_serv.o \ |
98 | sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ | 98 | sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ |
99 | sandbox-seccomp-filter.o | 99 | sandbox-seccomp-filter.o sandbox-capsicum.o |
100 | 100 | ||
101 | 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 sshd_config.5.out ssh_config.5.out | 101 | 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 sshd_config.5.out ssh_config.5.out |
102 | 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 sshd_config.5 ssh_config.5 | 102 | 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 sshd_config.5 ssh_config.5 |
@@ -472,4 +472,3 @@ package: $(CONFIGFILES) $(MANPAGES) $(TARGETS) | |||
472 | if [ "@MAKE_PACKAGE_SUPPORTED@" = yes ]; then \ | 472 | if [ "@MAKE_PACKAGE_SUPPORTED@" = yes ]; then \ |
473 | sh buildpkg.sh; \ | 473 | sh buildpkg.sh; \ |
474 | fi | 474 | fi |
475 | |||
diff --git a/configure.ac b/configure.ac index abd912f5a..f14e177fc 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: configure.ac,v 1.549 2014/01/17 04:12:16 dtucker Exp $ | 1 | # $Id: configure.ac,v 1.550 2014/01/17 05:47:04 djm Exp $ |
2 | # | 2 | # |
3 | # Copyright (c) 1999-2004 Damien Miller | 3 | # Copyright (c) 1999-2004 Damien Miller |
4 | # | 4 | # |
@@ -15,7 +15,7 @@ | |||
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 | AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) | 17 | AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) |
18 | AC_REVISION($Revision: 1.549 $) | 18 | AC_REVISION($Revision: 1.550 $) |
19 | AC_CONFIG_SRCDIR([ssh.c]) | 19 | AC_CONFIG_SRCDIR([ssh.c]) |
20 | AC_LANG([C]) | 20 | AC_LANG([C]) |
21 | 21 | ||
@@ -120,6 +120,10 @@ AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [ | |||
120 | #include <sys/types.h> | 120 | #include <sys/types.h> |
121 | #include <linux/prctl.h> | 121 | #include <linux/prctl.h> |
122 | ]) | 122 | ]) |
123 | AC_CHECK_DECL([cap_enter], [have_cap_enter=1], , [ | ||
124 | #include <sys/capability.h> | ||
125 | ]) | ||
126 | |||
123 | use_stack_protector=1 | 127 | use_stack_protector=1 |
124 | use_toolchain_hardening=1 | 128 | use_toolchain_hardening=1 |
125 | AC_ARG_WITH([stackprotect], | 129 | AC_ARG_WITH([stackprotect], |
@@ -2835,7 +2839,7 @@ fi | |||
2835 | # Decide which sandbox style to use | 2839 | # Decide which sandbox style to use |
2836 | sandbox_arg="" | 2840 | sandbox_arg="" |
2837 | AC_ARG_WITH([sandbox], | 2841 | AC_ARG_WITH([sandbox], |
2838 | [ --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter)], | 2842 | [ --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum)], |
2839 | [ | 2843 | [ |
2840 | if test "x$withval" = "xyes" ; then | 2844 | if test "x$withval" = "xyes" ; then |
2841 | sandbox_arg="" | 2845 | sandbox_arg="" |
@@ -2974,6 +2978,13 @@ elif test "x$sandbox_arg" = "xrlimit" || \ | |||
2974 | AC_MSG_ERROR([rlimit sandbox requires select to work with rlimit]) | 2978 | AC_MSG_ERROR([rlimit sandbox requires select to work with rlimit]) |
2975 | SANDBOX_STYLE="rlimit" | 2979 | SANDBOX_STYLE="rlimit" |
2976 | AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)]) | 2980 | AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)]) |
2981 | elif test "x$sandbox_arg" = "xcapsicum" || \ | ||
2982 | ( test -z "$sandbox_arg" && \ | ||
2983 | test "x$have_cap_enter" = "x1") ; then | ||
2984 | test "x$have_cap_enter" != "x1" && \ | ||
2985 | AC_MSG_ERROR([capsicum sandbox requires cap_enter function]) | ||
2986 | SANDBOX_STYLE="capsicum" | ||
2987 | AC_DEFINE([SANDBOX_CAPSICUM], [1], [Sandbox using capsicum]) | ||
2977 | elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ | 2988 | elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ |
2978 | test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then | 2989 | test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then |
2979 | SANDBOX_STYLE="none" | 2990 | SANDBOX_STYLE="none" |
diff --git a/sandbox-capsicum.c b/sandbox-capsicum.c new file mode 100644 index 000000000..5853a13ef --- /dev/null +++ b/sandbox-capsicum.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Dag-Erling Smorgrav | ||
3 | * | ||
4 | * Permission to use, copy, modify, and distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "includes.h" | ||
18 | |||
19 | #ifdef SANDBOX_CAPSICUM | ||
20 | |||
21 | #include <sys/types.h> | ||
22 | #include <sys/param.h> | ||
23 | #include <sys/time.h> | ||
24 | #include <sys/resource.h> | ||
25 | #include <sys/capability.h> | ||
26 | |||
27 | #include <errno.h> | ||
28 | #include <stdarg.h> | ||
29 | #include <stdio.h> | ||
30 | #include <stdlib.h> | ||
31 | #include <string.h> | ||
32 | #include <unistd.h> | ||
33 | |||
34 | #include "log.h" | ||
35 | #include "monitor.h" | ||
36 | #include "ssh-sandbox.h" | ||
37 | #include "xmalloc.h" | ||
38 | |||
39 | /* | ||
40 | * Capsicum sandbox that sets zero nfiles, nprocs and filesize rlimits, | ||
41 | * limits rights on stdout, stdin, stderr, monitor and switches to | ||
42 | * capability mode. | ||
43 | */ | ||
44 | |||
45 | struct ssh_sandbox { | ||
46 | struct monitor *monitor; | ||
47 | pid_t child_pid; | ||
48 | }; | ||
49 | |||
50 | struct ssh_sandbox * | ||
51 | ssh_sandbox_init(struct monitor *monitor) | ||
52 | { | ||
53 | struct ssh_sandbox *box; | ||
54 | |||
55 | /* | ||
56 | * Strictly, we don't need to maintain any state here but we need | ||
57 | * to return non-NULL to satisfy the API. | ||
58 | */ | ||
59 | debug3("%s: preparing capsicum sandbox", __func__); | ||
60 | box = xcalloc(1, sizeof(*box)); | ||
61 | box->monitor = monitor; | ||
62 | box->child_pid = 0; | ||
63 | |||
64 | return box; | ||
65 | } | ||
66 | |||
67 | void | ||
68 | ssh_sandbox_child(struct ssh_sandbox *box) | ||
69 | { | ||
70 | struct rlimit rl_zero; | ||
71 | cap_rights_t rights; | ||
72 | |||
73 | rl_zero.rlim_cur = rl_zero.rlim_max = 0; | ||
74 | |||
75 | if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) | ||
76 | fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", | ||
77 | __func__, strerror(errno)); | ||
78 | if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) | ||
79 | fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", | ||
80 | __func__, strerror(errno)); | ||
81 | if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) | ||
82 | fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", | ||
83 | __func__, strerror(errno)); | ||
84 | |||
85 | cap_rights_init(&rights); | ||
86 | |||
87 | if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) | ||
88 | fatal("can't limit stdin: %m"); | ||
89 | if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) | ||
90 | fatal("can't limit stdin: %m"); | ||
91 | if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) | ||
92 | fatal("can't limit stdin: %m"); | ||
93 | |||
94 | cap_rights_init(&rights, CAP_READ, CAP_WRITE); | ||
95 | if (cap_rights_limit(box->monitor->m_recvfd, &rights) == -1) | ||
96 | fatal("%s: failed to limit the network socket", __func__); | ||
97 | cap_rights_init(&rights, CAP_WRITE); | ||
98 | if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) == -1) | ||
99 | fatal("%s: failed to limit the logging socket", __func__); | ||
100 | if (cap_enter() != 0 && errno != ENOSYS) | ||
101 | fatal("%s: failed to enter capability mode", __func__); | ||
102 | |||
103 | } | ||
104 | |||
105 | void | ||
106 | ssh_sandbox_parent_finish(struct ssh_sandbox *box) | ||
107 | { | ||
108 | free(box); | ||
109 | debug3("%s: finished", __func__); | ||
110 | } | ||
111 | |||
112 | void | ||
113 | ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) | ||
114 | { | ||
115 | box->child_pid = child_pid; | ||
116 | } | ||
117 | |||
118 | #endif /* SANDBOX_CAPSICUM */ | ||
diff --git a/sandbox-darwin.c b/sandbox-darwin.c index 69901ef14..35f0c4d1a 100644 --- a/sandbox-darwin.c +++ b/sandbox-darwin.c | |||
@@ -40,7 +40,7 @@ struct ssh_sandbox { | |||
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct ssh_sandbox * | 42 | struct ssh_sandbox * |
43 | ssh_sandbox_init(void) | 43 | ssh_sandbox_init(struct monitor *monitor) |
44 | { | 44 | { |
45 | struct ssh_sandbox *box; | 45 | struct ssh_sandbox *box; |
46 | 46 | ||
diff --git a/sandbox-null.c b/sandbox-null.c index 29fa9669f..d4cb9188b 100644 --- a/sandbox-null.c +++ b/sandbox-null.c | |||
@@ -39,7 +39,7 @@ struct ssh_sandbox { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | struct ssh_sandbox * | 41 | struct ssh_sandbox * |
42 | ssh_sandbox_init(void) | 42 | ssh_sandbox_init(struct monitor *monitor) |
43 | { | 43 | { |
44 | struct ssh_sandbox *box; | 44 | struct ssh_sandbox *box; |
45 | 45 | ||
diff --git a/sandbox-rlimit.c b/sandbox-rlimit.c index a00386337..da91eb1b9 100644 --- a/sandbox-rlimit.c +++ b/sandbox-rlimit.c | |||
@@ -42,7 +42,7 @@ struct ssh_sandbox { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct ssh_sandbox * | 44 | struct ssh_sandbox * |
45 | ssh_sandbox_init(void) | 45 | ssh_sandbox_init(struct monitor *monitor) |
46 | { | 46 | { |
47 | struct ssh_sandbox *box; | 47 | struct ssh_sandbox *box; |
48 | 48 | ||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c index cc1465305..2f73067e1 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c | |||
@@ -132,7 +132,7 @@ struct ssh_sandbox { | |||
132 | }; | 132 | }; |
133 | 133 | ||
134 | struct ssh_sandbox * | 134 | struct ssh_sandbox * |
135 | ssh_sandbox_init(void) | 135 | ssh_sandbox_init(struct monitor *monitor) |
136 | { | 136 | { |
137 | struct ssh_sandbox *box; | 137 | struct ssh_sandbox *box; |
138 | 138 | ||
diff --git a/sandbox-systrace.c b/sandbox-systrace.c index cc0db46c4..53fbd47cb 100644 --- a/sandbox-systrace.c +++ b/sandbox-systrace.c | |||
@@ -78,7 +78,7 @@ struct ssh_sandbox { | |||
78 | }; | 78 | }; |
79 | 79 | ||
80 | struct ssh_sandbox * | 80 | struct ssh_sandbox * |
81 | ssh_sandbox_init(void) | 81 | ssh_sandbox_init(struct monitor *monitor) |
82 | { | 82 | { |
83 | struct ssh_sandbox *box; | 83 | struct ssh_sandbox *box; |
84 | 84 | ||
diff --git a/ssh-sandbox.h b/ssh-sandbox.h index dfecd5aa0..bd5fd8372 100644 --- a/ssh-sandbox.h +++ b/ssh-sandbox.h | |||
@@ -15,9 +15,10 @@ | |||
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 | ||
18 | struct monitor; | ||
18 | struct ssh_sandbox; | 19 | struct ssh_sandbox; |
19 | 20 | ||
20 | struct ssh_sandbox *ssh_sandbox_init(void); | 21 | struct ssh_sandbox *ssh_sandbox_init(struct monitor *); |
21 | void ssh_sandbox_child(struct ssh_sandbox *); | 22 | void ssh_sandbox_child(struct ssh_sandbox *); |
22 | void ssh_sandbox_parent_finish(struct ssh_sandbox *); | 23 | void ssh_sandbox_parent_finish(struct ssh_sandbox *); |
23 | void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t); | 24 | void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t); |
@@ -660,7 +660,7 @@ privsep_preauth(Authctxt *authctxt) | |||
660 | pmonitor->m_pkex = &xxx_kex; | 660 | pmonitor->m_pkex = &xxx_kex; |
661 | 661 | ||
662 | if (use_privsep == PRIVSEP_ON) | 662 | if (use_privsep == PRIVSEP_ON) |
663 | box = ssh_sandbox_init(); | 663 | box = ssh_sandbox_init(pmonitor); |
664 | pid = fork(); | 664 | pid = fork(); |
665 | if (pid == -1) { | 665 | if (pid == -1) { |
666 | fatal("fork of unprivileged child failed"); | 666 | fatal("fork of unprivileged child failed"); |