[packages/openssh] - default seccomp sandbox is broken, use patch by Steven Noonan adding libseccomp-sandbox to unbreak

baggins baggins at pld-linux.org
Thu Mar 19 01:56:56 CET 2015


commit 5a5e6771dcca2946a470f4642e5810ab358aaa86
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Thu Mar 19 01:55:50 2015 +0100

    - default seccomp sandbox is broken, use patch by Steven Noonan adding libseccomp-sandbox to unbreak it
    - rel2

 libseccomp-sandbox.patch | 239 +++++++++++++++++++++++++++++++++++++++++++++++
 openssh.spec             |  10 +-
 2 files changed, 246 insertions(+), 3 deletions(-)
---
diff --git a/openssh.spec b/openssh.spec
index d66b2b1..381b83c 100644
--- a/openssh.spec
+++ b/openssh.spec
@@ -34,7 +34,7 @@ Summary(ru.UTF-8):	OpenSSH - свободная реализация прото
 Summary(uk.UTF-8):	OpenSSH - вільна реалізація протоколу Secure Shell (SSH)
 Name:		openssh
 Version:	6.8p1
-Release:	1
+Release:	2
 Epoch:		2
 License:	BSD
 Group:		Applications/Networking
@@ -70,6 +70,7 @@ Patch11:	%{name}-chroot.patch
 
 Patch14:	%{name}-bind.patch
 Patch15:	%{name}-disable_ldap.patch
+Patch16:	libseccomp-sandbox.patch
 URL:		http://www.openssh.com/portable.html
 BuildRequires:	%{__perl}
 %{?with_tests:BuildRequires:	%{name}-server}
@@ -80,6 +81,7 @@ BuildRequires:	automake
 %{?with_gtk:BuildRequires:	gtk+2-devel}
 %{?with_kerberos5:BuildRequires:	heimdal-devel >= 0.7}
 %{?with_libedit:BuildRequires:	libedit-devel}
+BuildRequires:	libseccomp-devel
 %{?with_selinux:BuildRequires:	libselinux-devel}
 %{?with_ldap:BuildRequires:	openldap-devel}
 BuildRequires:	openssl-devel >= 0.9.8f
@@ -539,6 +541,7 @@ openldap-a.
 
 %patch14 -p1
 %{!?with_ldap:%patch15 -p1}
+%patch16 -p1
 
 %if "%{pld_release}" == "ac"
 # fix for missing x11.pc
@@ -556,7 +559,8 @@ cp /usr/share/automake/config.sub .
 %{__aclocal}
 %{__autoconf}
 %{__autoheader}
-CPPFLAGS="%{rpmcppflags} -DCHROOT -std=gnu99"
+CPPFLAGS="%{rpmcppflags} -DCHROOT -std=gnu99 -fno-tree-dominator-opts"
+CFLAGS="%{rpmcflags} -fno-tree-dominator-opts"
 %configure \
 	PERL=%{__perl} \
 	--disable-strip \
@@ -574,7 +578,7 @@ CPPFLAGS="%{rpmcppflags} -DCHROOT -std=gnu99"
 	--with-pid-dir=%{_localstatedir}/run \
 	--with-privsep-path=%{_privsepdir} \
 %if "%{pld_release}" != "ac"
-	--with-sandbox=seccomp_filter \
+	--with-sandbox=libseccomp_filter \
 %endif
 	%{?with_selinux:--with-selinux} \
 %if "%{pld_release}" == "ac"
diff --git a/libseccomp-sandbox.patch b/libseccomp-sandbox.patch
new file mode 100644
index 0000000..abed09f
--- /dev/null
+++ b/libseccomp-sandbox.patch
@@ -0,0 +1,239 @@
+https://bugzilla.mindrot.org/show_bug.cgi?id=2142
+
+--- a/Makefile.in	
++++ a/Makefile.in	
+@@ -106,7 +106,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
+ 	sftp-server.o sftp-common.o \
+ 	roaming_common.o roaming_serv.o \
+ 	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
+-	sandbox-seccomp-filter.o sandbox-capsicum.o
++	sandbox-seccomp-filter.o sandbox-libseccomp-filter.o sandbox-capsicum.o
+ 
+ MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
+ MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
+--- a/configure.ac	
++++ a/configure.ac	
+@@ -2867,11 +2867,22 @@ else
+ fi
+ AC_SUBST([SSH_PRIVSEP_USER])
+ 
++AC_CHECK_DECL([SCMP_ARCH_NATIVE], [have_libseccomp_filter=1], , [
++	#include <sys/types.h>
++	#include <seccomp.h>
++])
++if test "x$have_libseccomp_filter" = "x1" ; then
++	AC_CHECK_LIB([seccomp], [seccomp_init],
++				 [LIBS="$LIBS -lseccomp"],
++				 [have_libseccomp_filter=0])
++fi
++
+ if test "x$have_linux_no_new_privs" = "x1" ; then
+ AC_CHECK_DECL([SECCOMP_MODE_FILTER], [have_seccomp_filter=1], , [
+ 	#include <sys/types.h>
+ 	#include <linux/seccomp.h>
+ ])
++
+ fi
+ if test "x$have_seccomp_filter" = "x1" ; then
+ AC_MSG_CHECKING([kernel for seccomp_filter support])
+@@ -2898,7 +2909,7 @@ fi
+ # Decide which sandbox style to use
+ sandbox_arg=""
+ AC_ARG_WITH([sandbox],
+-	[  --with-sandbox=style    Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum)],
++	[  --with-sandbox=style    Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, libseccomp_filter, capsicum)],
+ 	[
+ 		if test "x$withval" = "xyes" ; then
+ 			sandbox_arg=""
+@@ -3008,6 +3019,13 @@ elif test "x$sandbox_arg" = "xdarwin" || \
+ 		AC_MSG_ERROR([Darwin seatbelt sandbox requires sandbox.h and sandbox_init function])
+ 	SANDBOX_STYLE="darwin"
+ 	AC_DEFINE([SANDBOX_DARWIN], [1], [Sandbox using Darwin sandbox_init(3)])
++elif test "x$sandbox_arg" = "xlibseccomp_filter" || \
++     ( test -z "$sandbox_arg" && \
++       test "x$have_libseccomp_filter" = "x1" ) ; then
++	test "x$have_libseccomp_filter" != "x1" && \
++		AC_MSG_ERROR([libseccomp_filter sandbox not supported on $host])
++        SANDBOX_STYLE="libseccomp_filter"
++        AC_DEFINE([SANDBOX_LIBSECCOMP_FILTER], [1], [Sandbox using libseccomp filter])
+ elif test "x$sandbox_arg" = "xseccomp_filter" || \
+      ( test -z "$sandbox_arg" && \
+        test "x$have_seccomp_filter" = "x1" && \
+--- a/sandbox-libseccomp-filter.c	
++++ a/sandbox-libseccomp-filter.c	
+@@ -0,0 +1,175 @@ 
++/*
++ * Copyright (c) 2012 Will Drewry <wad at dataspill.org>
++ *
++ * 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_LIBSECCOMP_FILTER
++
++#include <sys/types.h>
++#include <sys/resource.h>
++#include <seccomp.h>
++
++#include <errno.h>
++#include <signal.h>
++#include <stdarg.h>
++#include <stddef.h>  /* for offsetof */
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "log.h"
++#include "ssh-sandbox.h"
++#include "xmalloc.h"
++
++struct ssh_sandbox {
++	pid_t child_pid;
++};
++
++struct ssh_sandbox *
++ssh_sandbox_init(struct monitor *monitor)
++{
++	struct ssh_sandbox *box;
++
++	/*
++	 * Strictly, we don't need to maintain any state here but we need
++	 * to return non-NULL to satisfy the API.
++	 */
++	debug3("%s: preparing libseccomp filter sandbox", __func__);
++	box = xcalloc(1, sizeof(*box));
++	box->child_pid = 0;
++
++	return box;
++}
++
++static int
++seccomp_add_secondary_archs(scmp_filter_ctx *c)
++{
++#if defined(__i386__) || defined(__x86_64__)
++	int r;
++	r = seccomp_arch_add(c, SCMP_ARCH_X86);
++	if (r < 0 && r != -EEXIST)
++		return r;
++	r = seccomp_arch_add(c, SCMP_ARCH_X86_64);
++	if (r < 0 && r != -EEXIST)
++		return r;
++	r = seccomp_arch_add(c, SCMP_ARCH_X32);
++	if (r < 0 && r != -EEXIST)
++		return r;
++#endif
++	return 0;
++}
++
++struct scmp_action_def {
++	uint32_t action;
++	int syscall;
++};
++
++static const struct scmp_action_def preauth_insns[] = {
++	{SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open)},
++	{SCMP_ACT_ERRNO(EACCES), SCMP_SYS(stat)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(getpid)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(getpid)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(gettimeofday)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(clock_gettime)},
++#ifdef __NR_time /* not defined on EABI ARM */
++	{SCMP_ACT_ALLOW, SCMP_SYS(time)},
++#endif
++	{SCMP_ACT_ALLOW, SCMP_SYS(read)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(write)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(close)},
++#ifdef __NR_shutdown /* not defined on archs that go via socketcall(2) */
++	{SCMP_ACT_ALLOW, SCMP_SYS(shutdown)},
++#endif
++	{SCMP_ACT_ALLOW, SCMP_SYS(brk)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(poll)},
++#ifdef __NR__newselect
++	{SCMP_ACT_ALLOW, SCMP_SYS(_newselect)},
++#endif
++	{SCMP_ACT_ALLOW, SCMP_SYS(select)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(madvise)},
++#ifdef __NR_mmap2 /* EABI ARM only has mmap2() */
++	{SCMP_ACT_ALLOW, SCMP_SYS(mmap2)},
++#endif
++#ifdef __NR_mmap
++	{SCMP_ACT_ALLOW, SCMP_SYS(mmap)},
++#endif
++#ifdef __dietlibc__
++	{SCMP_ACT_ALLOW, SCMP_SYS(mremap)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(exit)},
++#endif
++	{SCMP_ACT_ALLOW, SCMP_SYS(munmap)},
++	{SCMP_ACT_ALLOW, SCMP_SYS(exit_group)},
++#ifdef __NR_rt_sigprocmask
++	{SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask)},
++#else
++	{SCMP_ACT_ALLOW, SCMP_SYS(sigprocmask)},
++#endif
++	{0, 0}
++};
++
++
++void
++ssh_sandbox_child(struct ssh_sandbox *box)
++{
++	scmp_filter_ctx *seccomp;
++	struct rlimit rl_zero;
++	const struct scmp_action_def *insn;
++	int r;
++
++	/* Set rlimits for completeness if possible. */
++	rl_zero.rlim_cur = rl_zero.rlim_max = 0;
++	if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1)
++		fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s",
++			__func__, strerror(errno));
++	if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1)
++		fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s",
++			__func__, strerror(errno));
++	if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1)
++		fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s",
++			__func__, strerror(errno));
++
++	seccomp = seccomp_init(SCMP_ACT_KILL);
++	if (!seccomp)
++		fatal("%s:libseccomp activation failed", __func__);
++	if (seccomp_add_secondary_archs(seccomp))
++		fatal("%s:libseccomp secondary arch setup failed", __func__);
++
++	for (insn = preauth_insns; insn->action; insn++) {
++		if (seccomp_rule_add(seccomp, insn->action, insn->syscall, 0) < 0)
++			fatal("%s:libseccomp rule failed", __func__);
++	}
++
++	if ((r = seccomp_load(seccomp)) < 0)
++		fatal("%s:libseccomp unable to load filter %d", __func__, r);
++
++	seccomp_release(seccomp);
++}
++
++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 = child_pid;
++}
++
++#endif /* SANDBOX_LIBSECCOMP_FILTER */
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/openssh.git/commitdiff/5a5e6771dcca2946a470f4642e5810ab358aaa86



More information about the pld-cvs-commit mailing list