- markus@cvs.openbsd.org 2012/06/30 14:35:09
[sandbox-systrace.c sshd.c] fix a during the load of the sandbox policies (child can still make the read-syscall and wait forever for systrace-answers) by replacing the read/write synchronisation with SIGSTOP/SIGCONT; report and help hshoexer@; ok djm@, dtucker@
This commit is contained in:
parent
ecbf14aa53
commit
3b4b2d3021
|
@ -4,6 +4,12 @@
|
||||||
[ssh_config.5 sshd_config.5]
|
[ssh_config.5 sshd_config.5]
|
||||||
match the documented MAC order of preference to the actual one;
|
match the documented MAC order of preference to the actual one;
|
||||||
ok dtucker@
|
ok dtucker@
|
||||||
|
- markus@cvs.openbsd.org 2012/06/30 14:35:09
|
||||||
|
[sandbox-systrace.c sshd.c]
|
||||||
|
fix a during the load of the sandbox policies (child can still make
|
||||||
|
the read-syscall and wait forever for systrace-answers) by replacing
|
||||||
|
the read/write synchronisation with SIGSTOP/SIGCONT;
|
||||||
|
report and help hshoexer@; ok djm@, dtucker@
|
||||||
|
|
||||||
20120629
|
20120629
|
||||||
- OpenBSD CVS Sync
|
- OpenBSD CVS Sync
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sandbox-systrace.c,v 1.5 2012/06/26 11:02:30 dtucker Exp $ */
|
/* $OpenBSD: sandbox-systrace.c,v 1.6 2012/06/30 14:35:09 markus Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
|
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
|
||||||
*
|
*
|
||||||
|
@ -24,12 +24,14 @@
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <dev/systrace.h>
|
#include <dev/systrace.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -69,26 +71,21 @@ static const struct sandbox_policy preauth_policy[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_sandbox {
|
struct ssh_sandbox {
|
||||||
int child_sock;
|
|
||||||
int parent_sock;
|
|
||||||
int systrace_fd;
|
int systrace_fd;
|
||||||
pid_t child_pid;
|
pid_t child_pid;
|
||||||
|
void (*osigchld)(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_sandbox *
|
struct ssh_sandbox *
|
||||||
ssh_sandbox_init(void)
|
ssh_sandbox_init(void)
|
||||||
{
|
{
|
||||||
struct ssh_sandbox *box;
|
struct ssh_sandbox *box;
|
||||||
int s[2];
|
|
||||||
|
|
||||||
debug3("%s: preparing systrace sandbox", __func__);
|
debug3("%s: preparing systrace sandbox", __func__);
|
||||||
box = xcalloc(1, sizeof(*box));
|
box = xcalloc(1, sizeof(*box));
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == -1)
|
|
||||||
fatal("%s: socketpair: %s", __func__, strerror(errno));
|
|
||||||
box->child_sock = s[0];
|
|
||||||
box->parent_sock = s[1];
|
|
||||||
box->systrace_fd = -1;
|
box->systrace_fd = -1;
|
||||||
box->child_pid = 0;
|
box->child_pid = 0;
|
||||||
|
box->osigchld = signal(SIGCHLD, SIG_IGN);
|
||||||
|
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
@ -96,35 +93,38 @@ ssh_sandbox_init(void)
|
||||||
void
|
void
|
||||||
ssh_sandbox_child(struct ssh_sandbox *box)
|
ssh_sandbox_child(struct ssh_sandbox *box)
|
||||||
{
|
{
|
||||||
char whatever = 0;
|
|
||||||
|
|
||||||
close(box->parent_sock);
|
|
||||||
/* Signal parent that we are ready */
|
|
||||||
debug3("%s: ready", __func__);
|
debug3("%s: ready", __func__);
|
||||||
if (atomicio(vwrite, box->child_sock, &whatever, 1) != 1)
|
signal(SIGCHLD, box->osigchld);
|
||||||
fatal("%s: write: %s", __func__, strerror(errno));
|
if (kill(getpid(), SIGSTOP) != 0)
|
||||||
/* Wait for parent to signal for us to go */
|
fatal("%s: kill(%d, SIGSTOP)", __func__, getpid());
|
||||||
if (atomicio(read, box->child_sock, &whatever, 1) != 1)
|
|
||||||
fatal("%s: read: %s", __func__, strerror(errno));
|
|
||||||
debug3("%s: started", __func__);
|
debug3("%s: started", __func__);
|
||||||
close(box->child_sock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
|
ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
|
||||||
const struct sandbox_policy *allowed_syscalls)
|
const struct sandbox_policy *allowed_syscalls)
|
||||||
{
|
{
|
||||||
int dev_systrace, i, j, found;
|
int dev_systrace, i, j, found, status;
|
||||||
char whatever = 0;
|
pid_t pid;
|
||||||
struct systrace_policy policy;
|
struct systrace_policy policy;
|
||||||
|
|
||||||
|
/* Wait for the child to send itself a SIGSTOP */
|
||||||
debug3("%s: wait for child %ld", __func__, (long)child_pid);
|
debug3("%s: wait for child %ld", __func__, (long)child_pid);
|
||||||
|
do {
|
||||||
|
pid = waitpid(child_pid, &status, WUNTRACED);
|
||||||
|
} while (pid == -1 && errno == EINTR);
|
||||||
|
signal(SIGCHLD, box->osigchld);
|
||||||
|
if (!WIFSTOPPED(status)) {
|
||||||
|
if (WIFSIGNALED(status))
|
||||||
|
fatal("%s: child terminated with signal %d",
|
||||||
|
__func__, WTERMSIG(status));
|
||||||
|
if (WIFEXITED(status))
|
||||||
|
fatal("%s: child exited with status %d",
|
||||||
|
__func__, WEXITSTATUS(status));
|
||||||
|
fatal("%s: child not stopped", __func__);
|
||||||
|
}
|
||||||
|
debug3("%s: child %ld stopped", __func__, (long)child_pid);
|
||||||
box->child_pid = child_pid;
|
box->child_pid = child_pid;
|
||||||
close(box->child_sock);
|
|
||||||
/* Wait for child to signal that it is ready */
|
|
||||||
if (atomicio(read, box->parent_sock, &whatever, 1) != 1)
|
|
||||||
fatal("%s: read: %s", __func__, strerror(errno));
|
|
||||||
debug3("%s: child %ld ready", __func__, (long)child_pid);
|
|
||||||
|
|
||||||
/* Set up systracing of child */
|
/* Set up systracing of child */
|
||||||
if ((dev_systrace = open("/dev/systrace", O_RDONLY)) == -1)
|
if ((dev_systrace = open("/dev/systrace", O_RDONLY)) == -1)
|
||||||
|
@ -175,9 +175,8 @@ ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
|
||||||
|
|
||||||
/* Signal the child to start running */
|
/* Signal the child to start running */
|
||||||
debug3("%s: start child %ld", __func__, (long)child_pid);
|
debug3("%s: start child %ld", __func__, (long)child_pid);
|
||||||
if (atomicio(vwrite, box->parent_sock, &whatever, 1) != 1)
|
if (kill(box->child_pid, SIGCONT) != 0)
|
||||||
fatal("%s: write: %s", __func__, strerror(errno));
|
fatal("%s: kill(%d, SIGCONT)", __func__, box->child_pid);
|
||||||
close(box->parent_sock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
4
sshd.c
4
sshd.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sshd.c,v 1.391 2012/05/13 01:42:32 dtucker Exp $ */
|
/* $OpenBSD: sshd.c,v 1.392 2012/06/30 14:35:09 markus Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -643,9 +643,9 @@ privsep_preauth(Authctxt *authctxt)
|
||||||
} else if (pid != 0) {
|
} else if (pid != 0) {
|
||||||
debug2("Network child is on pid %ld", (long)pid);
|
debug2("Network child is on pid %ld", (long)pid);
|
||||||
|
|
||||||
|
pmonitor->m_pid = pid;
|
||||||
if (box != NULL)
|
if (box != NULL)
|
||||||
ssh_sandbox_parent_preauth(box, pid);
|
ssh_sandbox_parent_preauth(box, pid);
|
||||||
pmonitor->m_pid = pid;
|
|
||||||
monitor_child_preauth(authctxt, pmonitor);
|
monitor_child_preauth(authctxt, pmonitor);
|
||||||
|
|
||||||
/* Sync memory */
|
/* Sync memory */
|
||||||
|
|
Loading…
Reference in New Issue