Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 May 2013 17:03:05 +0200
From:      =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
To:        Pawel Jakub Dawidek <pjd@FreeBSD.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, bdrewery@freebsd.org
Subject:   Re: svn commit: r251088 - head/crypto/openssh
Message-ID:  <867gih4ymu.fsf@nine.des.no>
In-Reply-To: <20130529125052.GA1383@garage.freebsd.pl> (Pawel Jakub Dawidek's message of "Wed, 29 May 2013 14:50:52 %2B0200")
References:  <201305290019.r4T0JxLE011755@svn.freebsd.org> <20130529070952.GA1400@garage.freebsd.pl> <86zjve3qv2.fsf@nine.des.no> <20130529125052.GA1383@garage.freebsd.pl>

next in thread | previous in thread | raw e-mail | index | archive | help
--=-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Pawel Jakub Dawidek <pjd@FreeBSD.org> writes:
> AES-NI doesn't have to go through kernel at all and doing so is much
> slower. Not sure if our OpenSSL version already has native AES-NI
> support. If not it would be best to upgrade it.  This would fix AES-NI
> at least. Other crypto HW that do need kernel driver would still need
> something here. I wonder if CRIOGET can't be done before setting rlimit.

The CRIOGET ioctl call happens deep inside OpenSSL.  There may be a way
to pre-initialize the AES engine, but the unprivileged child doesn't
know which engine to use until after it's sandboxed.

> How does it work on OpenBSD then?

IIUC, they have sandboxing facilities in the base system and use those
instead of the extremely rudimentary rlimit-based implementation that we
use.

> > > Also what is the exact difference between "sandbox" and "yes" setting=
s?
> > "sandbox" enables sandboxing (no surprise) which in FreeBSD's case means
> > a bunch of rlimit settings.
> I thought that simple "yes" setting does chroot to /var/empty, drops
> privileges to sshd user/group and sets rlimit? I'm trying to figure out
> the difference between those two settings.

In our case, the only difference is that "sandbox" uses setrlimit() to
prevent the unprivileged child from forking, opening files or appending
to open files.

> > > The reason I ask is because I plan to experiment with OpenSSH
> > > sandboxing to use Capsicum and Casper.
> > You still have the patches I sent you?
> Probably somewhere in my INBOX. If you have them handy can you please
> resend them?

Attached.

DES
--=20
Dag-Erling Sm=C3=B8rgrav - des@des.no


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment; filename=openssh-capsicum.diff
Content-Transfer-Encoding: quoted-printable

Index: crypto/openssh/servconf.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/servconf.c	(revision 237273)
+++ crypto/openssh/servconf.c	(working copy)
@@ -320,7 +320,7 @@
=20
 	/* Turn privilege separation on by default */
 	if (use_privsep =3D=3D -1)
-		use_privsep =3D PRIVSEP_ON;
+		use_privsep =3D PRIVSEP_SANDBOX;
=20
 #ifndef HAVE_MMAP
 	if (use_privsep && options->compression =3D=3D 1) {
Index: crypto/openssh/sandbox-rlimit.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/sandbox-rlimit.c	(revision 237273)
+++ crypto/openssh/sandbox-rlimit.c	(working copy)
@@ -32,17 +32,19 @@
 #include <unistd.h>
=20
 #include "log.h"
+#include "monitor.h"
 #include "ssh-sandbox.h"
 #include "xmalloc.h"
=20
 /* Minimal sandbox that sets zero nfiles, nprocs and filesize rlimits */
=20
 struct ssh_sandbox {
+	struct monitor *monitor;
 	pid_t child_pid;
 };
=20
 struct ssh_sandbox *
-ssh_sandbox_init(void)
+ssh_sandbox_init(struct monitor *monitor)
 {
 	struct ssh_sandbox *box;
=20
@@ -52,6 +54,7 @@
 	 */
 	debug3("%s: preparing rlimit sandbox", __func__);
 	box =3D xcalloc(1, sizeof(*box));
+	box->monitor =3D monitor;
 	box->child_pid =3D 0;
=20
 	return box;
Index: crypto/openssh/sshd.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/sshd.c	(revision 237273)
+++ crypto/openssh/sshd.c	(working copy)
@@ -632,6 +632,14 @@
 #endif
 }
=20
+#if 1
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/uio.h>
+#include <sys/ktrace.h>
+#endif
+
 static int
 privsep_preauth(Authctxt *authctxt)
 {
@@ -645,7 +653,7 @@
 	pmonitor->m_pkex =3D &xxx_kex;
=20
 	if (use_privsep =3D=3D PRIVSEP_SANDBOX)
-		box =3D ssh_sandbox_init();
+		box =3D ssh_sandbox_init(pmonitor);
 	pid =3D fork();
 	if (pid =3D=3D -1) {
 		fatal("fork of unprivileged child failed");
@@ -677,6 +685,27 @@
 			ssh_sandbox_parent_finish(box);
 		return 1;
 	} else {
+#if 1
+		do {
+			struct rlimit rlim_infinity =3D { RLIM_INFINITY, RLIM_INFINITY };
+			char ktfn[1024];
+			int ktfd, ret;
+			snprintf(ktfn, sizeof ktfn, "/tmp/sshd.ktrace", (unsigned long)getpid()=
);
+			ktfd =3D open(ktfn, O_RDWR|O_CREAT|O_TRUNC, 0640);
+			if (ktfd =3D=3D -1) {
+				error("%s: truncate(): %s", __func__, strerror(errno));
+			} else {
+				close(ktfd);
+				ktrace(ktfn, KTROP_SET, KTRFAC_SYSCALL, getpid());
+				ret =3D ktrace(ktfn, KTROP_SET,
+				    KTRFAC_SYSCALL|KTRFAC_SYSRET|KTRFAC_NAMEI|KTRFAC_PSIG|KTRFAC_STRUC=
T|KTRFAC_CAPFAIL,
+				    getpid());
+				if (ret =3D=3D -1)
+					error("%s: ktrace(): %s", __func__, strerror(errno));
+			}
+			setrlimit(RLIMIT_CORE, &rlim_infinity);
+		} while (0);
+#endif
 		/* child */
 		close(pmonitor->m_sendfd);
 		close(pmonitor->m_log_recvfd);
Index: crypto/openssh/sandbox-darwin.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/sandbox-darwin.c	(revision 237273)
+++ crypto/openssh/sandbox-darwin.c	(working copy)
@@ -30,17 +30,19 @@
 #include <unistd.h>
=20
 #include "log.h"
+#include "monitor.h"
 #include "sandbox.h"
 #include "xmalloc.h"
=20
 /* Darwin/OS X sandbox */
=20
 struct ssh_sandbox {
+	struct monitor *monitor;
 	pid_t child_pid;
 };
=20
 struct ssh_sandbox *
-ssh_sandbox_init(void)
+ssh_sandbox_init(struct monitor *monitor)
 {
 	struct ssh_sandbox *box;
=20
@@ -50,6 +52,7 @@
 	 */
 	debug3("%s: preparing Darwin sandbox", __func__);
 	box =3D xcalloc(1, sizeof(*box));
+	box->monitor =3D monitor;
 	box->child_pid =3D 0;
=20
 	return box;
Index: crypto/openssh/sshd_config.5
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/sshd_config.5	(revision 237273)
+++ crypto/openssh/sshd_config.5	(working copy)
@@ -1083,14 +1083,14 @@
 the privilege of the authenticated user.
 The goal of privilege separation is to prevent privilege
 escalation by containing any corruption within the unprivileged processes.
-The default is
-.Dq yes .
 If
 .Cm UsePrivilegeSeparation
 is set to
 .Dq sandbox
 then the pre-authentication unprivileged process is subject to additional
 restrictions.
+The default is
+.Dq sandbox .
 .It Cm VersionAddendum
 Specifies a string to append to the regular version string to identify
 OS- or site-specific modifications.
Index: crypto/openssh/sshd_config
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/sshd_config	(revision 237273)
+++ crypto/openssh/sshd_config	(working copy)
@@ -103,7 +103,7 @@
 #PrintLastLog yes
 #TCPKeepAlive yes
 #UseLogin no
-#UsePrivilegeSeparation yes
+#UsePrivilegeSeparation sandbox
 #PermitUserEnvironment no
 #Compression delayed
 #ClientAliveInterval 0
Index: crypto/openssh/sandbox-capsicum.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/sandbox-capsicum.c	(revision 0)
+++ crypto/openssh/sandbox-capsicum.c	(working copy)
@@ -0,0 +1,96 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2011 Dag-Erling Sm=C3=B8rgrav
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#ifdef SANDBOX_CAPSICUM
+
+#include <sys/types.h>
+#include <sys/capability.h>
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "monitor.h"
+#include "ssh-sandbox.h"
+#include "xmalloc.h"
+
+/* Capsicum-based sandbox */
+
+struct ssh_sandbox {
+	struct monitor *monitor;
+	pid_t child_pid;
+};
+
+struct ssh_sandbox *
+ssh_sandbox_init(struct monitor *monitor)
+{
+	struct ssh_sandbox *box;
+
+	debug3("%s: preparing Capsicum sandbox", __func__);
+	box =3D xcalloc(1, sizeof(*box));
+	box->monitor =3D monitor;
+	box->child_pid =3D 0;
+
+	return box;
+}
+
+static int
+ssh_child_limitfd(int fd, cap_rights_t rights)
+{
+	int cd, serrno;
+
+	if ((cd =3D cap_new(fd, rights)) =3D=3D -1)
+		return -1;
+	if (dup2(cd, fd) =3D=3D -1) {
+		serrno =3D errno;
+		close(cd);
+		errno =3D serrno;
+		return -1;
+	}
+	close(cd);
+	return 0;
+}
+
+void
+ssh_sandbox_child(struct ssh_sandbox *box)
+{
+	int cd;
+
+	if (ssh_child_limitfd(box->monitor->m_recvfd, CAP_READ|CAP_WRITE|CAP_SEEK=
) =3D=3D -1)
+		fatal("%s: failed to wrap the network socket", __func__);
+	if (ssh_child_limitfd(box->monitor->m_log_sendfd, CAP_WRITE|CAP_SEEK) =3D=
=3D -1)
+		fatal("%s: failed to wrap the logging socket", __func__);
+	cap_enter();
+}
+
+void
+ssh_sandbox_parent_finish(struct ssh_sandbox *box)
+{
+	free(box);
+	debug3("%s: finished", __func__);
+}
+
+void
+ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
+{
+	box->child_pid =3D child_pid;
+}
+
+#endif /* SANDBOX_CAPSICUM */
Index: crypto/openssh/sandbox-null.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/sandbox-null.c	(revision 237273)
+++ crypto/openssh/sandbox-null.c	(working copy)
@@ -29,6 +29,7 @@
 #include <unistd.h>
=20
 #include "log.h"
+#include "monitor.h"
 #include "ssh-sandbox.h"
 #include "xmalloc.h"
=20
@@ -39,7 +40,7 @@
 };
=20
 struct ssh_sandbox *
-ssh_sandbox_init(void)
+ssh_sandbox_init(struct monitor *monitor)
 {
 	struct ssh_sandbox *box;
=20
@@ -48,6 +49,7 @@
 	 * to return non-NULL to satisfy the API.
 	 */
 	box =3D xcalloc(1, sizeof(*box));
+	(void)monitor;
 	return box;
 }
=20
Index: crypto/openssh/ssh-sandbox.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/ssh-sandbox.h	(revision 237273)
+++ crypto/openssh/ssh-sandbox.h	(working copy)
@@ -15,9 +15,10 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
=20
+struct monitor;
 struct ssh_sandbox;
=20
-struct ssh_sandbox *ssh_sandbox_init(void);
+struct ssh_sandbox *ssh_sandbox_init(struct monitor *);
 void ssh_sandbox_child(struct ssh_sandbox *);
 void ssh_sandbox_parent_finish(struct ssh_sandbox *);
 void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t);
Index: crypto/openssh/config.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/config.h	(revision 237273)
+++ crypto/openssh/config.h	(working copy)
@@ -219,6 +219,12 @@
 /* Define to 1 if you have the <bstring.h> header file. */
 /* #undef HAVE_BSTRING_H */
=20
+/* Define to 1 if you have the `cap_enter' function. */
+#define HAVE_CAP_ENTER 1
+
+/* Capsicum Capability Mode */
+#define HAVE_CAP_MODE 1
+
 /* Define to 1 if you have the `clock' function. */
 #define HAVE_CLOCK 1
=20
@@ -1342,6 +1348,9 @@
 /* read(1) can return 0 for a non-closed fd */
 /* #undef PTY_ZEROREAD */
=20
+/* Sandbox using Capsicum */
+#define SANDBOX_CAPSICUM 1
+
 /* Sandbox using Darwin sandbox_init(3) */
 /* #undef SANDBOX_DARWIN */
=20
@@ -1349,11 +1358,14 @@
 /* #undef SANDBOX_NULL */
=20
 /* Sandbox using setrlimit(2) */
-#define SANDBOX_RLIMIT 1
+/* #undef SANDBOX_RLIMIT */
=20
 /* Sandbox using systrace(4) */
 /* #undef SANDBOX_SYSTRACE */
=20
+/* Sandbox using Capsicum */
+#define SANDBOX_CAPSICUM 1
+
 /* Define if your platform breaks doing a seteuid before a setuid */
 /* #undef SETEUID_BREAKS_SETUID */
=20
Index: crypto/openssh/sandbox-systrace.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- crypto/openssh/sandbox-systrace.c	(revision 237273)
+++ crypto/openssh/sandbox-systrace.c	(working copy)
@@ -38,6 +38,7 @@
=20
 #include "atomicio.h"
 #include "log.h"
+#include "monitor.h"
 #include "ssh-sandbox.h"
 #include "xmalloc.h"
=20
@@ -75,7 +76,7 @@
 };
=20
 struct ssh_sandbox *
-ssh_sandbox_init(void)
+ssh_sandbox_init(struct monitor *monitor)
 {
 	struct ssh_sandbox *box;
 	int s[2];
@@ -88,6 +89,7 @@
 	box->parent_sock =3D s[1];
 	box->systrace_fd =3D -1;
 	box->child_pid =3D 0;
+	(void)monitor;
=20
 	return box;
 }
Index: secure/usr.sbin/sshd/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- secure/usr.sbin/sshd/Makefile	(revision 237273)
+++ secure/usr.sbin/sshd/Makefile	(working copy)
@@ -17,7 +17,8 @@
 	loginrec.c auth-pam.c auth-shadow.c auth-sia.c md5crypt.c \
 	sftp-server.c sftp-common.c \
 	roaming_common.c roaming_serv.c \
-	sandbox-null.c sandbox-rlimit.c sandbox-systrace.c sandbox-darwin.c
+	sandbox-null.c sandbox-rlimit.c sandbox-systrace.c sandbox-darwin.c \
+	sandbox-capsicum.c
=20
 # gss-genr.c really belongs in libssh; see src/secure/lib/libssh/Makefile
 SRCS+=3D	gss-genr.c

--=-=-=--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?867gih4ymu.fsf>