ksgi

Форк
0
/
sandbox-capsicum.c 
210 строк · 4.9 Кб
1
/*	$Id$ */
2
/*
3
 * Copyright (c) 2014 Baptiste Daroussin <bapt@freebsd.org>
4
 * Copyright (c) 2015--2016 Kristaps Dzonsons <kristaps@bsd.lv>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
#include "config.h"
19

20
#if HAVE_CAPSICUM
21

22
#include <sys/resource.h>
23
#include <sys/capsicum.h>
24

25
#include <assert.h>
26
#include <unistd.h>
27
#include <errno.h>
28
#include <stdarg.h>
29
#include <stdlib.h>
30

31
#include "kcgi.h"
32
#include "extern.h"
33

34
static int
35
ksandbox_capsicum_init_control(int worker, int fdfiled, int fdaccept)
36
{
37
	int		 rc;
38
	struct rlimit	 rl_zero;
39
	cap_rights_t	 rights;
40

41
	cap_rights_init(&rights);
42

43
	/*
44
	 * If we have old-style accept FastCGI sockets, then mark us as
45
	 * accepting on it.
46
	 * XXX: the CAP_READ and CAP_WRITE are necessary because they're
47
	 * required by descriptors we create from the accept().
48
	 * The new-style passing of descriptors is easier.
49
	 */
50

51
	if (fdaccept != -1) {
52
		cap_rights_init(&rights, 
53
			CAP_EVENT, CAP_FCNTL, CAP_ACCEPT, 
54
			CAP_READ, CAP_WRITE);
55
		if (cap_rights_limit(fdaccept, &rights) < 0 && 
56
			 errno != ENOSYS) {
57
			kutil_warn(NULL, NULL, "cap_rights_limit");
58
			return 0;
59
		}
60
	} else {
61
		assert(fdfiled != -1);
62
		cap_rights_init(&rights, CAP_EVENT, 
63
			CAP_FCNTL, CAP_READ, CAP_WRITE);
64
		if (cap_rights_limit(fdfiled, &rights) < 0 && 
65
			 errno != ENOSYS) {
66
			kutil_warn(NULL, NULL, "cap_rights_limit");
67
			return 0;
68
		}
69
	}
70

71
	/* Always pass through write-only stderr. */
72

73
	cap_rights_init(&rights, CAP_WRITE, CAP_FSTAT);
74
	if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && 
75
		 errno != ENOSYS) {
76
		kutil_warn(NULL, NULL, "cap_rights_limit");
77
		return 0;
78
	}
79

80
	/* Interface to worker. */
81

82
	cap_rights_init(&rights, CAP_EVENT, 
83
		CAP_FCNTL, CAP_READ, CAP_WRITE);
84
	if (cap_rights_limit(worker, &rights) < 0 && 
85
		 errno != ENOSYS) {
86
		kutil_warn(NULL, NULL, "cap_rights_limit");
87
		return 0;
88
	}
89

90
	rl_zero.rlim_cur = rl_zero.rlim_max = 0;
91
	if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) {
92
		kutil_warn(NULL, NULL, "setrlimit");
93
		return 0;
94
	} else if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) {
95
		kutil_warn(NULL, NULL, "setrlimit");
96
		return 0;
97
	}
98

99
	rc = cap_enter();
100
	if (rc && errno != ENOSYS) {
101
		kutil_warn(NULL, NULL, "cap_enter");
102
		rc = 0;
103
	} else
104
		rc = 1;
105

106
	return rc;
107
}
108

109
static int
110
ksandbox_capsicum_init_worker(int fd1, int fd2)
111
{
112
	int rc;
113
	struct rlimit	 rl_zero;
114
	cap_rights_t	 rights;
115

116
	cap_rights_init(&rights);
117

118
	/* 
119
	 * Test for EBADF because STDIN_FILENO is usually closed by the
120
	 * caller.
121
	 */
122

123
	cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_FSTAT);
124
	if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && 
125
		 errno != ENOSYS && errno != EBADF) {
126
 		kutil_warn(NULL, NULL, "cap_rights_limit");
127
		return 0;
128
	}
129

130
	cap_rights_init(&rights, CAP_EVENT, CAP_WRITE, CAP_FSTAT);
131
	if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && 
132
		 errno != ENOSYS) {
133
		kutil_warn(NULL, NULL, "cap_rights_limit");
134
		return 0;
135
	}
136

137
	/* Only do thesee if the descriptors are valid. */
138

139
	cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE, CAP_FSTAT);
140
	if (fd1 != -1 && cap_rights_limit(fd1, &rights) < 0 && 
141
		 errno != ENOSYS) {
142
		kutil_warn(NULL, NULL, "cap_rights_limit");
143
		return 0;
144
	}
145
	if (fd2 != -1 && cap_rights_limit(fd2, &rights) < 0 && 
146
		 errno != ENOSYS) {
147
		kutil_warn(NULL, NULL, "cap_rights_limit");
148
		return 0;
149
	}
150

151
	rl_zero.rlim_cur = rl_zero.rlim_max = 0;
152

153
#if 0
154
	/* Don't run this: if we use openlog, it will fail. */
155

156
	if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) {
157
		kutil_warn(NULL, NULL, "setrlimit");
158
		return 0;
159
	}
160
#endif
161

162
	if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) {
163
		kutil_warn(NULL, NULL, "setrlimit");
164
		return 0;
165
	} else if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) {
166
		kutil_warn(NULL, NULL, "setrlimit");
167
		return 0;
168
	}
169

170
	rc = cap_enter();
171
	if (rc && errno != ENOSYS) {
172
		kutil_warn(NULL, NULL, "cap_enter");
173
		rc = 0;
174
	} else
175
		rc = 1;
176

177
	return rc;
178
}
179

180
int
181
ksandbox_capsicum_init_child(enum sandtype type, 
182
	int fd1, int fd2, int fdfiled, int fdaccept)
183
{
184
	int	 rc;
185

186
	switch (type) {
187
	case SAND_WORKER:
188
		rc = ksandbox_capsicum_init_worker(fd1, fd2);
189
		break;
190
	case SAND_CONTROL_OLD:
191
		assert(fd2 == -1);
192
		rc = ksandbox_capsicum_init_control
193
			(fd1, fdfiled, fdaccept);
194
		break;
195
	case SAND_CONTROL_NEW:
196
		assert(fd2 == -1);
197
		rc = ksandbox_capsicum_init_control
198
			(fd1, fdfiled, fdaccept);
199
		break;
200
	default:
201
		abort();
202
	}
203

204
	if (!rc) 
205
		kutil_warnx(NULL, NULL, "capsicum sandbox failure");
206

207
	return rc;
208
}
209

210
#endif
211

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.