View | Details | Raw Unified | Return to bug 2142 | Differences between
and this patch

Collapse All | Expand All

(-)a/Makefile.in (-1 / +1 lines)
Lines 106-112 SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ Link Here
106
	sftp-server.o sftp-common.o \
106
	sftp-server.o sftp-common.o \
107
	roaming_common.o roaming_serv.o \
107
	roaming_common.o roaming_serv.o \
108
	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
108
	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
109
	sandbox-seccomp-filter.o sandbox-capsicum.o
109
	sandbox-seccomp-filter.o sandbox-libseccomp-filter.o sandbox-capsicum.o
110
110
111
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
111
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
112
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
112
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
(-)a/configure.ac (-1 / +19 lines)
Lines 2867-2877 else Link Here
2867
fi
2867
fi
2868
AC_SUBST([SSH_PRIVSEP_USER])
2868
AC_SUBST([SSH_PRIVSEP_USER])
2869
2869
2870
AC_CHECK_DECL([SCMP_ARCH_NATIVE], [have_libseccomp_filter=1], , [
2871
	#include <sys/types.h>
2872
	#include <seccomp.h>
2873
])
2874
if test "x$have_libseccomp_filter" = "x1" ; then
2875
	AC_CHECK_LIB([seccomp], [seccomp_init],
2876
				 [LIBS="$LIBS -lseccomp"],
2877
				 [have_libseccomp_filter=0])
2878
fi
2879
2870
if test "x$have_linux_no_new_privs" = "x1" ; then
2880
if test "x$have_linux_no_new_privs" = "x1" ; then
2871
AC_CHECK_DECL([SECCOMP_MODE_FILTER], [have_seccomp_filter=1], , [
2881
AC_CHECK_DECL([SECCOMP_MODE_FILTER], [have_seccomp_filter=1], , [
2872
	#include <sys/types.h>
2882
	#include <sys/types.h>
2873
	#include <linux/seccomp.h>
2883
	#include <linux/seccomp.h>
2874
])
2884
])
2885
2875
fi
2886
fi
2876
if test "x$have_seccomp_filter" = "x1" ; then
2887
if test "x$have_seccomp_filter" = "x1" ; then
2877
AC_MSG_CHECKING([kernel for seccomp_filter support])
2888
AC_MSG_CHECKING([kernel for seccomp_filter support])
Lines 2898-2904 fi Link Here
2898
# Decide which sandbox style to use
2909
# Decide which sandbox style to use
2899
sandbox_arg=""
2910
sandbox_arg=""
2900
AC_ARG_WITH([sandbox],
2911
AC_ARG_WITH([sandbox],
2901
	[  --with-sandbox=style    Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum)],
2912
	[  --with-sandbox=style    Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, libseccomp_filter, capsicum)],
2902
	[
2913
	[
2903
		if test "x$withval" = "xyes" ; then
2914
		if test "x$withval" = "xyes" ; then
2904
			sandbox_arg=""
2915
			sandbox_arg=""
Lines 3008-3013 elif test "x$sandbox_arg" = "xdarwin" || \ Link Here
3008
		AC_MSG_ERROR([Darwin seatbelt sandbox requires sandbox.h and sandbox_init function])
3019
		AC_MSG_ERROR([Darwin seatbelt sandbox requires sandbox.h and sandbox_init function])
3009
	SANDBOX_STYLE="darwin"
3020
	SANDBOX_STYLE="darwin"
3010
	AC_DEFINE([SANDBOX_DARWIN], [1], [Sandbox using Darwin sandbox_init(3)])
3021
	AC_DEFINE([SANDBOX_DARWIN], [1], [Sandbox using Darwin sandbox_init(3)])
3022
elif test "x$sandbox_arg" = "xlibseccomp_filter" || \
3023
     ( test -z "$sandbox_arg" && \
3024
       test "x$have_libseccomp_filter" = "x1" ) ; then
3025
	test "x$have_libseccomp_filter" != "x1" && \
3026
		AC_MSG_ERROR([libseccomp_filter sandbox not supported on $host])
3027
        SANDBOX_STYLE="libseccomp_filter"
3028
        AC_DEFINE([SANDBOX_LIBSECCOMP_FILTER], [1], [Sandbox using libseccomp filter])
3011
elif test "x$sandbox_arg" = "xseccomp_filter" || \
3029
elif test "x$sandbox_arg" = "xseccomp_filter" || \
3012
     ( test -z "$sandbox_arg" && \
3030
     ( test -z "$sandbox_arg" && \
3013
       test "x$have_seccomp_filter" = "x1" && \
3031
       test "x$have_seccomp_filter" = "x1" && \
(-)a/sandbox-libseccomp-filter.c (+175 lines)
Line 0 Link Here
1
/*
2
 * Copyright (c) 2012 Will Drewry <wad@dataspill.org>
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_LIBSECCOMP_FILTER
20
21
#include <sys/types.h>
22
#include <sys/resource.h>
23
#include <seccomp.h>
24
25
#include <errno.h>
26
#include <signal.h>
27
#include <stdarg.h>
28
#include <stddef.h>  /* for offsetof */
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include <unistd.h>
33
34
#include "log.h"
35
#include "ssh-sandbox.h"
36
#include "xmalloc.h"
37
38
struct ssh_sandbox {
39
	pid_t child_pid;
40
};
41
42
struct ssh_sandbox *
43
ssh_sandbox_init(struct monitor *monitor)
44
{
45
	struct ssh_sandbox *box;
46
47
	/*
48
	 * Strictly, we don't need to maintain any state here but we need
49
	 * to return non-NULL to satisfy the API.
50
	 */
51
	debug3("%s: preparing libseccomp filter sandbox", __func__);
52
	box = xcalloc(1, sizeof(*box));
53
	box->child_pid = 0;
54
55
	return box;
56
}
57
58
static int
59
seccomp_add_secondary_archs(scmp_filter_ctx *c)
60
{
61
#if defined(__i386__) || defined(__x86_64__)
62
	int r;
63
	r = seccomp_arch_add(c, SCMP_ARCH_X86);
64
	if (r < 0 && r != -EEXIST)
65
		return r;
66
	r = seccomp_arch_add(c, SCMP_ARCH_X86_64);
67
	if (r < 0 && r != -EEXIST)
68
		return r;
69
	r = seccomp_arch_add(c, SCMP_ARCH_X32);
70
	if (r < 0 && r != -EEXIST)
71
		return r;
72
#endif
73
	return 0;
74
}
75
76
struct scmp_action_def {
77
	uint32_t action;
78
	int syscall;
79
};
80
81
static const struct scmp_action_def preauth_insns[] = {
82
	{SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open)},
83
	{SCMP_ACT_ERRNO(EACCES), SCMP_SYS(stat)},
84
	{SCMP_ACT_ALLOW, SCMP_SYS(getpid)},
85
	{SCMP_ACT_ALLOW, SCMP_SYS(getpid)},
86
	{SCMP_ACT_ALLOW, SCMP_SYS(gettimeofday)},
87
	{SCMP_ACT_ALLOW, SCMP_SYS(clock_gettime)},
88
#ifdef __NR_time /* not defined on EABI ARM */
89
	{SCMP_ACT_ALLOW, SCMP_SYS(time)},
90
#endif
91
	{SCMP_ACT_ALLOW, SCMP_SYS(read)},
92
	{SCMP_ACT_ALLOW, SCMP_SYS(write)},
93
	{SCMP_ACT_ALLOW, SCMP_SYS(close)},
94
#ifdef __NR_shutdown /* not defined on archs that go via socketcall(2) */
95
	{SCMP_ACT_ALLOW, SCMP_SYS(shutdown)},
96
#endif
97
	{SCMP_ACT_ALLOW, SCMP_SYS(brk)},
98
	{SCMP_ACT_ALLOW, SCMP_SYS(poll)},
99
#ifdef __NR__newselect
100
	{SCMP_ACT_ALLOW, SCMP_SYS(_newselect)},
101
#endif
102
	{SCMP_ACT_ALLOW, SCMP_SYS(select)},
103
	{SCMP_ACT_ALLOW, SCMP_SYS(madvise)},
104
#ifdef __NR_mmap2 /* EABI ARM only has mmap2() */
105
	{SCMP_ACT_ALLOW, SCMP_SYS(mmap2)},
106
#endif
107
#ifdef __NR_mmap
108
	{SCMP_ACT_ALLOW, SCMP_SYS(mmap)},
109
#endif
110
#ifdef __dietlibc__
111
	{SCMP_ACT_ALLOW, SCMP_SYS(mremap)},
112
	{SCMP_ACT_ALLOW, SCMP_SYS(exit)},
113
#endif
114
	{SCMP_ACT_ALLOW, SCMP_SYS(munmap)},
115
	{SCMP_ACT_ALLOW, SCMP_SYS(exit_group)},
116
#ifdef __NR_rt_sigprocmask
117
	{SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask)},
118
#else
119
	{SCMP_ACT_ALLOW, SCMP_SYS(sigprocmask)},
120
#endif
121
	{0, 0}
122
};
123
124
125
void
126
ssh_sandbox_child(struct ssh_sandbox *box)
127
{
128
	scmp_filter_ctx *seccomp;
129
	struct rlimit rl_zero;
130
	const struct scmp_action_def *insn;
131
	int r;
132
133
	/* Set rlimits for completeness if possible. */
134
	rl_zero.rlim_cur = rl_zero.rlim_max = 0;
135
	if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1)
136
		fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s",
137
			__func__, strerror(errno));
138
	if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1)
139
		fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s",
140
			__func__, strerror(errno));
141
	if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1)
142
		fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s",
143
			__func__, strerror(errno));
144
145
	seccomp = seccomp_init(SCMP_ACT_KILL);
146
	if (!seccomp)
147
		fatal("%s:libseccomp activation failed", __func__);
148
	if (seccomp_add_secondary_archs(seccomp))
149
		fatal("%s:libseccomp secondary arch setup failed", __func__);
150
151
	for (insn = preauth_insns; insn->action; insn++) {
152
		if (seccomp_rule_add(seccomp, insn->action, insn->syscall, 0) < 0)
153
			fatal("%s:libseccomp rule failed", __func__);
154
	}
155
156
	if ((r = seccomp_load(seccomp)) < 0)
157
		fatal("%s:libseccomp unable to load filter %d", __func__, r);
158
159
	seccomp_release(seccomp);
160
}
161
162
void
163
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
164
{
165
	free(box);
166
	debug3("%s: finished", __func__);
167
}
168
169
void
170
ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
171
{
172
	box->child_pid = child_pid;
173
}
174
175
#endif /* SANDBOX_LIBSECCOMP_FILTER */

Return to bug 2142