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

Collapse All | Expand All

(-)a/monitor_wrap.c (-18 / +47 lines)
Lines 80-112 Link Here
80
extern struct monitor *pmonitor;
80
extern struct monitor *pmonitor;
81
extern struct sshbuf *loginmsg;
81
extern struct sshbuf *loginmsg;
82
extern ServerOptions options;
82
extern ServerOptions options;
83
static sig_atomic_t in_logsend;
83
84
85
/*
86
 * Just like atomicio(vwrite, ...) but simpler.
87
 * We can't use atomicio() in signal handlers as it calls poll(3) in the
88
 * fallback path, and the replacement implementation in libopenbsd-compat
89
 * calls malloc(3), which isn't signal handler safe.
90
 */
91
static int
92
awrite(int fd, const void *m, size_t len)
93
{
94
	ssize_t r;
95
	size_t o;
96
	const u_char *buf = (const u_char *)m;
97
98
	for (o = 0; o < len;) {
99
		r = write(fd, buf + o, len - o);
100
		if (r <= 0) {
101
			if (r == EINTR || r == EAGAIN || r == EWOULDBLOCK)
102
				continue;
103
			return -1;
104
		}
105
		o += r;
106
	}
107
	return 0;
108
}
109
110
/*
111
 * NB. portable OpenSSH uses a signal handler-safe version of this function
112
 * as we need to be able to log sandbox violations that we receive in
113
 * signal handler context.
114
 */
84
void
115
void
85
mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx)
116
mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx)
86
{
117
{
87
	struct sshbuf *log_msg;
118
	u_char hdr[4 + 4 + 4 + 4];
88
	struct monitor *mon = (struct monitor *)ctx;
119
	struct monitor *mon = (struct monitor *)ctx;
89
	int r;
90
	size_t len;
120
	size_t len;
91
121
92
	if (mon->m_log_sendfd == -1)
122
	len = strlen(msg);
93
		fatal_f("no log channel");
94
123
95
	if ((log_msg = sshbuf_new()) == NULL)
124
	/* avoid reentrance */
96
		fatal_f("sshbuf_new failed");
125
	if (in_logsend || len > INT_MAX)
126
		_exit(0); /* can't recover */
97
127
98
	if ((r = sshbuf_put_u32(log_msg, 0)) != 0 || /* length; filled below */
128
	/* u32 len, u32 level, u32 forced, string msg */
99
	    (r = sshbuf_put_u32(log_msg, level)) != 0 ||
129
	POKE_U32(hdr, 4 + 4 + 4 + len);
100
	    (r = sshbuf_put_u32(log_msg, forced)) != 0 ||
130
	POKE_U32(hdr + 4, level);
101
	    (r = sshbuf_put_cstring(log_msg, msg)) != 0)
131
	POKE_U32(hdr + 8, forced);
102
		fatal_fr(r, "assemble");
132
	POKE_U32(hdr + 12, len);
103
	if ((len = sshbuf_len(log_msg)) < 4 || len > 0xffffffff)
133
104
		fatal_f("bad length %zu", len);
134
	in_logsend = 1;
105
	POKE_U32(sshbuf_mutable_ptr(log_msg), len - 4);
135
	if (awrite(mon->m_log_sendfd, hdr, sizeof(hdr)) != 0 ||
106
	if (atomicio(vwrite, mon->m_log_sendfd,
136
	    awrite(mon->m_log_sendfd, msg, len) != 0)
107
	    sshbuf_mutable_ptr(log_msg), len) != len)
137
		_exit(0); /* can't recover */
108
		fatal_f("write: %s", strerror(errno));
138
	in_logsend = 0;
109
	sshbuf_free(log_msg);
110
}
139
}
111
140
112
int
141
int
(-)a/sandbox-seccomp-filter.c (-12 / +44 lines)
Lines 15-29 Link Here
15
 */
15
 */
16
16
17
/*
17
/*
18
 * Uncomment the SANDBOX_SECCOMP_FILTER_DEBUG macro below to help diagnose
18
 * Uncomment the SANDBOX_SECCOMP_FILTER_DEBUG macro below and run sshd with
19
 * filter breakage during development. *Do not* use this in production,
19
 * stderr attached (sshd -De ... or sshd -d ...) to receive notifications of
20
 * as it relies on making library calls that are unsafe in signal context.
20
 * sandbox violations to stderr. E.g.
21
 *
21
 *
22
 * Instead, live systems the auditctl(8) may be used to monitor failures.
22
 * Alternately, live systems the auditctl(8) may be used to monitor
23
 * E.g.
23
 * failures. E.g.
24
 *   auditctl -a task,always -F uid=<privsep uid>
24
 *   auditctl -a task,always -F uid=<privsep uid>
25
 */
25
 */
26
/* #define SANDBOX_SECCOMP_FILTER_DEBUG 1 */
26
#define SANDBOX_SECCOMP_FILTER_DEBUG 1
27
27
28
#if 0
28
#if 0
29
/*
29
/*
Lines 79-84 Link Here
79
#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
79
#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
80
# undef SECCOMP_FILTER_FAIL
80
# undef SECCOMP_FILTER_FAIL
81
# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP
81
# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP
82
# ifdef WITH_OPENSSL
83
#  include <openssl/dh.h>
84
# endif /* WITH_OPENSSL */
85
# ifdef GSSAPI
86
#  include "ssh-gss.h"
87
# endif /* GSSAPI */
88
# include "monitor_wrap.h"
82
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
89
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
83
90
84
#if __BYTE_ORDER == __LITTLE_ENDIAN
91
#if __BYTE_ORDER == __LITTLE_ENDIAN
Lines 364-380 ssh_sandbox_init(struct monitor *monitor) Link Here
364
}
371
}
365
372
366
#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
373
#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
367
extern struct monitor *pmonitor;
374
/* convert an integer to a hex string; for use in signal handler */
368
void mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx);
375
static const char *
376
ntoh(long unsigned int n)
377
{
378
	static char ret[sizeof(long unsigned int) * 2 + 2 + 1];
379
	int i = sizeof(ret) - 2;
380
381
	if (n == 0)
382
		return "0";
383
	while (n > 0) {
384
		ret[i--] = "0123456789abcdef"[n & 0xf];
385
		n >>= 4;
386
	}
387
	ret[i--] = 'x';
388
	ret[i--] = '0';
389
	ret[sizeof(ret) - 1] = '\0';
390
	return &(ret[i + 1]);
391
}
369
392
370
static void
393
static void
371
ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context)
394
ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context)
372
{
395
{
373
	char msg[256];
396
	char msg[256];
397
	extern struct monitor *pmonitor;
398
399
	if (pmonitor == NULL)
400
		_exit(1);
401
402
	strlcpy(msg, __func__, sizeof(msg));
403
	strlcat(msg, ": unexpected system call: arch:", sizeof(msg));
404
	strlcat(msg, ntoh(info->si_arch), sizeof(msg));
405
	strlcat(msg, " syscall:", sizeof(msg));
406
	strlcat(msg, ntoh(info->si_syscall), sizeof(msg));
407
	strlcat(msg, " addr:", sizeof(msg));
408
	strlcat(msg, ntoh((unsigned long)info->si_call_addr), sizeof(msg));
374
409
375
	snprintf(msg, sizeof(msg),
376
	    "%s: unexpected system call (arch:0x%x,syscall:%d @ %p)",
377
	    __func__, info->si_arch, info->si_syscall, info->si_call_addr);
378
	mm_log_handler(SYSLOG_LEVEL_FATAL, 0, msg, pmonitor);
410
	mm_log_handler(SYSLOG_LEVEL_FATAL, 0, msg, pmonitor);
379
	_exit(1);
411
	_exit(1);
380
}
412
}
Lines 391-397 ssh_sandbox_child_debugging(void) Link Here
391
	sigaddset(&mask, SIGSYS);
423
	sigaddset(&mask, SIGSYS);
392
424
393
	act.sa_sigaction = &ssh_sandbox_violation;
425
	act.sa_sigaction = &ssh_sandbox_violation;
394
	act.sa_flags = SA_SIGINFO;
426
	act.sa_flags = SA_SIGINFO | SA_RESETHAND;
395
	if (sigaction(SIGSYS, &act, NULL) == -1)
427
	if (sigaction(SIGSYS, &act, NULL) == -1)
396
		fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno));
428
		fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno));
397
	if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
429
	if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)

Return to bug 3478