summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-01-17 16:47:04 +1100
committerDamien Miller <djm@mindrot.org>2014-01-17 16:47:04 +1100
commit868ea1ea1c1bfdbee5dbad78f81999c5983ecf31 (patch)
treecd0d26dd73bc147951ef9a3aeb967448912e9c4f
parenta9d186a8b50d18869a10e9203abf71c83ddb1f79 (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--ChangeLog5
-rw-r--r--Makefile.in5
-rw-r--r--configure.ac17
-rw-r--r--sandbox-capsicum.c118
-rw-r--r--sandbox-darwin.c2
-rw-r--r--sandbox-null.c2
-rw-r--r--sandbox-rlimit.c2
-rw-r--r--sandbox-seccomp-filter.c2
-rw-r--r--sandbox-systrace.c2
-rw-r--r--ssh-sandbox.h3
-rw-r--r--sshd.c2
11 files changed, 147 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 257a36ba2..1bf7e0dca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
2720140118 3220140118
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
101MANPAGES = 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 101MANPAGES = 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
102MANPAGES_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 102MANPAGES_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
17AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) 17AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org])
18AC_REVISION($Revision: 1.549 $) 18AC_REVISION($Revision: 1.550 $)
19AC_CONFIG_SRCDIR([ssh.c]) 19AC_CONFIG_SRCDIR([ssh.c])
20AC_LANG([C]) 20AC_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])
123AC_CHECK_DECL([cap_enter], [have_cap_enter=1], , [
124 #include <sys/capability.h>
125])
126
123use_stack_protector=1 127use_stack_protector=1
124use_toolchain_hardening=1 128use_toolchain_hardening=1
125AC_ARG_WITH([stackprotect], 129AC_ARG_WITH([stackprotect],
@@ -2835,7 +2839,7 @@ fi
2835# Decide which sandbox style to use 2839# Decide which sandbox style to use
2836sandbox_arg="" 2840sandbox_arg=""
2837AC_ARG_WITH([sandbox], 2841AC_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)])
2981elif 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])
2977elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ 2988elif 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
45struct ssh_sandbox {
46 struct monitor *monitor;
47 pid_t child_pid;
48};
49
50struct ssh_sandbox *
51ssh_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
67void
68ssh_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
105void
106ssh_sandbox_parent_finish(struct ssh_sandbox *box)
107{
108 free(box);
109 debug3("%s: finished", __func__);
110}
111
112void
113ssh_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
42struct ssh_sandbox * 42struct ssh_sandbox *
43ssh_sandbox_init(void) 43ssh_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
41struct ssh_sandbox * 41struct ssh_sandbox *
42ssh_sandbox_init(void) 42ssh_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
44struct ssh_sandbox * 44struct ssh_sandbox *
45ssh_sandbox_init(void) 45ssh_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
134struct ssh_sandbox * 134struct ssh_sandbox *
135ssh_sandbox_init(void) 135ssh_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
80struct ssh_sandbox * 80struct ssh_sandbox *
81ssh_sandbox_init(void) 81ssh_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
18struct monitor;
18struct ssh_sandbox; 19struct ssh_sandbox;
19 20
20struct ssh_sandbox *ssh_sandbox_init(void); 21struct ssh_sandbox *ssh_sandbox_init(struct monitor *);
21void ssh_sandbox_child(struct ssh_sandbox *); 22void ssh_sandbox_child(struct ssh_sandbox *);
22void ssh_sandbox_parent_finish(struct ssh_sandbox *); 23void ssh_sandbox_parent_finish(struct ssh_sandbox *);
23void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t); 24void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t);
diff --git a/sshd.c b/sshd.c
index 60b416e30..a5d4218b3 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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");