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 /sandbox-capsicum.c | |
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@
Diffstat (limited to 'sandbox-capsicum.c')
-rw-r--r-- | sandbox-capsicum.c | 118 |
1 files changed, 118 insertions, 0 deletions
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 */ | ||