# HG changeset patch
# Parent  77f039b8f058b66deeb544998a17154af0083629
Remove preauth compression support for security reasons and cleanup unused
code.

CVE-2016-10012 - part 1
bsc#1016370

backported upstream commit 0082fba4efdd492f765ed4c53f0d0fbd3bdbdf7f
backported upstream commit 1cfd5c06efb121e58e8b6671548fda77ef4b4455
backported upstream commit 4577adead6a7d600c8e764619d99477a08192c8f
backported upstream commit b7689155f3f5c4999846c07a852b1c7a43b09cec

diff --git a/openssh-7.2p2/Makefile.in b/openssh-7.2p2/Makefile.in
--- a/openssh-7.2p2/Makefile.in
+++ b/openssh-7.2p2/Makefile.in
@@ -111,17 +111,17 @@ SSHOBJS= ssh.o readconf.o clientloop.o s
 
 SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
 	audit.o audit-bsm.o audit-linux.o platform.o \
 	sshpty.o sshlogin.o servconf.o serverloop.o \
 	auth.o auth1.o auth2.o auth-options.o session.o \
 	auth-chall.o auth2-chall.o groupaccess.o \
 	auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
 	auth2-none.o auth2-passwd.o auth2-pubkey.o \
-	monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \
+	monitor.o monitor_wrap.o auth-krb5.o \
 	auth2-gss.o gss-serv.o gss-serv-krb5.o \
 	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
 	sftp-server.o sftp-common.o \
 	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
 	sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \
 	sandbox-solaris.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 ssh-ldap-helper.8.out ssh-ldap.conf.5.out
diff --git a/openssh-7.2p2/README.privsep b/openssh-7.2p2/README.privsep
--- a/openssh-7.2p2/README.privsep
+++ b/openssh-7.2p2/README.privsep
@@ -3,20 +3,16 @@ operations that require root privilege a
 privileged monitor process.  Its purpose is to prevent privilege
 escalation by containing corruption to an unprivileged process.
 More information is available at:
 	http://www.citi.umich.edu/u/provos/ssh/privsep.html
 
 Privilege separation is now enabled by default; see the
 UsePrivilegeSeparation option in sshd_config(5).
 
-On systems which lack mmap or anonymous (MAP_ANON) memory mapping,
-compression must be disabled in order for privilege separation to
-function.
-
 When privsep is enabled, during the pre-authentication phase sshd will
 chroot(2) to "/var/empty" and change its privileges to the "sshd" user
 and its primary group.  sshd is a pseudo-account that should not be
 used by other daemons, and must be locked and should contain a
 "nologin" or invalid shell.
 
 You should do something like the following to prepare the privsep
 preauth environment:
@@ -30,19 +26,16 @@ preauth environment:
 /var/empty should not contain any files.
 
 configure supports the following options to change the default
 privsep user and chroot directory:
 
   --with-privsep-path=xxx Path for privilege separation chroot
   --with-privsep-user=user Specify non-privileged user for privilege separation
 
-Privsep requires operating system support for file descriptor passing.
-Compression will be disabled on systems without a working mmap MAP_ANON.
-
 PAM-enabled OpenSSH is known to function with privsep on AIX, FreeBSD, 
 HP-UX (including Trusted Mode), Linux, NetBSD and Solaris.
 
 On Cygwin, Tru64 Unix, OpenServer, and Unicos only the pre-authentication
 part of privsep is supported.  Post-authentication privsep is disabled
 automatically (so you won't see the additional process mentioned below).
 
 Note that for a normal interactive login with a shell, enabling privsep
diff --git a/openssh-7.2p2/TODO b/openssh-7.2p2/TODO
--- a/openssh-7.2p2/TODO
+++ b/openssh-7.2p2/TODO
@@ -64,20 +64,16 @@ Clean up configure/makefiles:
   similar tests. E.g move all the type detection stuff into one file,
   entropy related stuff into another.
 
 Packaging:
 - HP-UX: Provide DEPOT package scripts.
   (gilbert.r.loomis@saic.com)
 
 PrivSep Issues:
-- mmap() issues.
-  + /dev/zero solution (Solaris)
-  + No/broken MAP_ANON (Irix)
-  + broken /dev/zero parse (Linux)
 - PAM
   + See above PAM notes
 - AIX
   + usrinfo() does not set TTY, but only required for legacy systems.  Works
     with PrivSep.
 - OSF
   + SIA is broken
 - Cygwin
diff --git a/openssh-7.2p2/configure.ac b/openssh-7.2p2/configure.ac
--- a/openssh-7.2p2/configure.ac
+++ b/openssh-7.2p2/configure.ac
@@ -1176,17 +1176,16 @@ mips-sony-bsd|mips-sony-newsos4)
 	*-*-nto-qnx6*)
 		AC_DEFINE([DISABLE_FD_PASSING])
 		;;
 	esac
 	;;
 
 *-*-ultrix*)
 	AC_DEFINE([BROKEN_GETGROUPS], [1], [getgroups(0,NULL) will return -1])
-	AC_DEFINE([BROKEN_MMAP], [1], [Ultrix mmap can't map files])
 	AC_DEFINE([NEED_SETPGRP])
 	AC_DEFINE([HAVE_SYS_SYSLOG_H], [1], [Force use of sys/syslog.h on Ultrix])
 	;;
 
 *-*-lynxos)
         CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__"
         AC_DEFINE([BROKEN_SETVBUF], [1], [LynxOS has broken setvbuf() implementation])
         ;;
@@ -1842,17 +1841,16 @@ AC_CHECK_FUNCS([ \
 	inet_ntop \
 	innetgr \
 	login_getcapbool \
 	mblen \
 	md5_crypt \
 	memmove \
 	memset_s \
 	mkdtemp \
-	mmap \
 	ngetaddrinfo \
 	nsleep \
 	ogetaddrinfo \
 	openlog_r \
 	pledge \
 	poll \
 	prctl \
 	pstat \
diff --git a/openssh-7.2p2/monitor.c b/openssh-7.2p2/monitor.c
--- a/openssh-7.2p2/monitor.c
+++ b/openssh-7.2p2/monitor.c
@@ -87,17 +87,16 @@
 #include "channels.h"
 #include "session.h"
 #include "sshlogin.h"
 #include "canohost.h"
 #include "log.h"
 #include "misc.h"
 #include "servconf.h"
 #include "monitor.h"
-#include "monitor_mm.h"
 #ifdef GSSAPI
 #include "ssh-gss.h"
 #endif
 #include "monitor_wrap.h"
 #include "monitor_fdpass.h"
 #include "compat.h"
 #include "ssh2.h"
 #include "authfd.h"
@@ -511,41 +510,16 @@ monitor_child_postauth(struct monitor *p
 		monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
 		monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
 	}
 
 	for (;;)
 		monitor_read(pmonitor, mon_dispatch, NULL);
 }
 
-void
-monitor_sync(struct monitor *pmonitor)
-{
-	if (options.compression) {
-		/* The member allocation is not visible, so sync it */
-		mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback);
-	}
-}
-
-/* Allocation functions for zlib */
-static void *
-mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
-{
-	if (size == 0 || ncount == 0 || ncount > SIZE_MAX / size)
-		fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);
-
-	return mm_malloc(mm, size * ncount);
-}
-
-static void
-mm_zfree(struct mm_master *mm, void *address)
-{
-	mm_free(mm, address);
-}
-
 static int
 monitor_read_log(struct monitor *pmonitor)
 {
 	Buffer logmsg;
 	u_int len, level;
 	char *msg;
 
 	buffer_init(&logmsg);
@@ -1965,23 +1939,16 @@ monitor_apply_keystate(struct monitor *p
 			kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
 		}
 #endif
 		kex->load_host_public_key=&get_hostkey_public_by_type;
 		kex->load_host_private_key=&get_hostkey_private_by_type;
 		kex->host_key_index=&get_hostkey_index;
 		kex->sign = sshd_hostkey_sign;
 	}
-
-	/* Update with new address */
-	if (options.compression) {
-		ssh_packet_set_compress_hooks(ssh, pmonitor->m_zlib,
-		    (ssh_packet_comp_alloc_func *)mm_zalloc,
-		    (ssh_packet_comp_free_func *)mm_zfree);
-	}
 }
 
 /* This function requries careful sanity checking */
 
 void
 mm_get_keystate(struct monitor *pmonitor)
 {
 	Buffer m;
@@ -2040,34 +2007,21 @@ monitor_openfds(struct monitor *mon, int
 		mon->m_log_recvfd = mon->m_log_sendfd = -1;
 }
 
 #define MM_MEMSIZE	65536
 
 struct monitor *
 monitor_init(void)
 {
-	struct ssh *ssh = active_state;			/* XXX */
 	struct monitor *mon;
 
 	mon = xcalloc(1, sizeof(*mon));
-
 	monitor_openfds(mon, 1);
 
-	/* Used to share zlib space across processes */
-	if (options.compression) {
-		mon->m_zback = mm_create(NULL, MM_MEMSIZE);
-		mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);
-
-		/* Compression needs to share state across borders */
-		ssh_packet_set_compress_hooks(ssh, mon->m_zlib,
-		    (ssh_packet_comp_alloc_func *)mm_zalloc,
-		    (ssh_packet_comp_free_func *)mm_zfree);
-	}
-
 	return mon;
 }
 
 void
 monitor_reinit(struct monitor *mon)
 {
 	monitor_openfds(mon, 0);
 }
diff --git a/openssh-7.2p2/monitor.h b/openssh-7.2p2/monitor.h
--- a/openssh-7.2p2/monitor.h
+++ b/openssh-7.2p2/monitor.h
@@ -1,9 +1,9 @@
-/* $OpenBSD: monitor.h,v 1.19 2015/01/19 19:52:16 markus Exp $ */
+/* $OpenBSD: monitor.h,v 1.20 2016/09/28 16:33:07 djm Exp $ */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -71,31 +71,27 @@ enum monitor_reqtype {
 	MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123,
 	MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124,
 
 	MONITOR_REQ_GSSSIGN = 201, MONITOR_ANS_GSSSIGN = 202,
 	MONITOR_REQ_GSSUPCREDS = 203, MONITOR_ANS_GSSUPCREDS = 204,
 
 };
 
-struct mm_master;
 struct monitor {
 	int			 m_recvfd;
 	int			 m_sendfd;
 	int			 m_log_recvfd;
 	int			 m_log_sendfd;
-	struct mm_master	*m_zback;
-	struct mm_master	*m_zlib;
 	struct kex		**m_pkex;
 	pid_t			 m_pid;
 };
 
 struct monitor *monitor_init(void);
 void monitor_reinit(struct monitor *);
-void monitor_sync(struct monitor *);
 
 struct Authctxt;
 void monitor_child_preauth(struct Authctxt *, struct monitor *);
 void monitor_child_postauth(struct monitor *);
 
 struct mon_table;
 int monitor_read(struct monitor*, struct mon_table *, struct mon_table **);
 
diff --git a/openssh-7.2p2/monitor_mm.c b/openssh-7.2p2/monitor_mm.c
deleted file mode 100644
--- a/openssh-7.2p2/monitor_mm.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/* $OpenBSD: monitor_mm.c,v 1.21 2015/02/06 23:21:59 millert Exp $ */
-/*
- * Copyright 2002 Niels Provos <provos@citi.umich.edu>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "includes.h"
-
-#include <sys/types.h>
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include "openbsd-compat/sys-tree.h"
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stddef.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <stdlib.h>
-#include <string.h>
-
-#include "xmalloc.h"
-#include "ssh.h"
-#include "log.h"
-#include "monitor_mm.h"
-
-static int
-mm_compare(struct mm_share *a, struct mm_share *b)
-{
-	ptrdiff_t diff = (char *)a->address - (char *)b->address;
-
-	if (diff == 0)
-		return (0);
-	else if (diff < 0)
-		return (-1);
-	else
-		return (1);
-}
-
-RB_GENERATE(mmtree, mm_share, next, mm_compare)
-
-static struct mm_share *
-mm_make_entry(struct mm_master *mm, struct mmtree *head,
-    void *address, size_t size)
-{
-	struct mm_share *tmp, *tmp2;
-
-	if (mm->mmalloc == NULL)
-		tmp = xcalloc(1, sizeof(struct mm_share));
-	else
-		tmp = mm_xmalloc(mm->mmalloc, sizeof(struct mm_share));
-	tmp->address = address;
-	tmp->size = size;
-
-	tmp2 = RB_INSERT(mmtree, head, tmp);
-	if (tmp2 != NULL)
-		fatal("mm_make_entry(%p): double address %p->%p(%zu)",
-		    mm, tmp2, address, size);
-
-	return (tmp);
-}
-
-/* Creates a shared memory area of a certain size */
-
-struct mm_master *
-mm_create(struct mm_master *mmalloc, size_t size)
-{
-	void *address;
-	struct mm_master *mm;
-
-	if (mmalloc == NULL)
-		mm = xcalloc(1, sizeof(struct mm_master));
-	else
-		mm = mm_xmalloc(mmalloc, sizeof(struct mm_master));
-
-	/*
-	 * If the memory map has a mm_master it can be completely
-	 * shared including authentication between the child
-	 * and the client.
-	 */
-	mm->mmalloc = mmalloc;
-
-	address = xmmap(size);
-	if (address == (void *)MAP_FAILED)
-		fatal("mmap(%zu): %s", size, strerror(errno));
-
-	mm->address = address;
-	mm->size = size;
-
-	RB_INIT(&mm->rb_free);
-	RB_INIT(&mm->rb_allocated);
-
-	mm_make_entry(mm, &mm->rb_free, address, size);
-
-	return (mm);
-}
-
-/* Frees either the allocated or the free list */
-
-static void
-mm_freelist(struct mm_master *mmalloc, struct mmtree *head)
-{
-	struct mm_share *mms, *next;
-
-	for (mms = RB_ROOT(head); mms; mms = next) {
-		next = RB_NEXT(mmtree, head, mms);
-		RB_REMOVE(mmtree, head, mms);
-		if (mmalloc == NULL)
-			free(mms);
-		else
-			mm_free(mmalloc, mms);
-	}
-}
-
-/* Destroys a memory mapped area */
-
-void
-mm_destroy(struct mm_master *mm)
-{
-	mm_freelist(mm->mmalloc, &mm->rb_free);
-	mm_freelist(mm->mmalloc, &mm->rb_allocated);
-
-#ifdef HAVE_MMAP
-	if (munmap(mm->address, mm->size) == -1)
-		fatal("munmap(%p, %zu): %s", mm->address, mm->size,
-		    strerror(errno));
-#else
-	fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported",
-	    __func__);
-#endif
-	if (mm->mmalloc == NULL)
-		free(mm);
-	else
-		mm_free(mm->mmalloc, mm);
-}
-
-void *
-mm_xmalloc(struct mm_master *mm, size_t size)
-{
-	void *address;
-
-	address = mm_malloc(mm, size);
-	if (address == NULL)
-		fatal("%s: mm_malloc(%zu)", __func__, size);
-	memset(address, 0, size);
-	return (address);
-}
-
-
-/* Allocates data from a memory mapped area */
-
-void *
-mm_malloc(struct mm_master *mm, size_t size)
-{
-	struct mm_share *mms, *tmp;
-
-	if (size == 0)
-		fatal("mm_malloc: try to allocate 0 space");
-	if (size > SIZE_MAX - MM_MINSIZE + 1)
-		fatal("mm_malloc: size too big");
-
-	size = ((size + (MM_MINSIZE - 1)) / MM_MINSIZE) * MM_MINSIZE;
-
-	RB_FOREACH(mms, mmtree, &mm->rb_free) {
-		if (mms->size >= size)
-			break;
-	}
-
-	if (mms == NULL)
-		return (NULL);
-
-	/* Debug */
-	memset(mms->address, 0xd0, size);
-
-	tmp = mm_make_entry(mm, &mm->rb_allocated, mms->address, size);
-
-	/* Does not change order in RB tree */
-	mms->size -= size;
-	mms->address = (char *)mms->address + size;
-
-	if (mms->size == 0) {
-		RB_REMOVE(mmtree, &mm->rb_free, mms);
-		if (mm->mmalloc == NULL)
-			free(mms);
-		else
-			mm_free(mm->mmalloc, mms);
-	}
-
-	return (tmp->address);
-}
-
-/* Frees memory in a memory mapped area */
-
-void
-mm_free(struct mm_master *mm, void *address)
-{
-	struct mm_share *mms, *prev, tmp;
-
-	tmp.address = address;
-	mms = RB_FIND(mmtree, &mm->rb_allocated, &tmp);
-	if (mms == NULL)
-		fatal("mm_free(%p): can not find %p", mm, address);
-
-	/* Debug */
-	memset(mms->address, 0xd0, mms->size);
-
-	/* Remove from allocated list and insert in free list */
-	RB_REMOVE(mmtree, &mm->rb_allocated, mms);
-	if (RB_INSERT(mmtree, &mm->rb_free, mms) != NULL)
-		fatal("mm_free(%p): double address %p", mm, address);
-
-	/* Find previous entry */
-	prev = mms;
-	if (RB_LEFT(prev, next)) {
-		prev = RB_LEFT(prev, next);
-		while (RB_RIGHT(prev, next))
-			prev = RB_RIGHT(prev, next);
-	} else {
-		if (RB_PARENT(prev, next) &&
-		    (prev == RB_RIGHT(RB_PARENT(prev, next), next)))
-			prev = RB_PARENT(prev, next);
-		else {
-			while (RB_PARENT(prev, next) &&
-			    (prev == RB_LEFT(RB_PARENT(prev, next), next)))
-				prev = RB_PARENT(prev, next);
-			prev = RB_PARENT(prev, next);
-		}
-	}
-
-	/* Check if range does not overlap */
-	if (prev != NULL && MM_ADDRESS_END(prev) > address)
-		fatal("mm_free: memory corruption: %p(%zu) > %p",
-		    prev->address, prev->size, address);
-
-	/* See if we can merge backwards */
-	if (prev != NULL && MM_ADDRESS_END(prev) == address) {
-		prev->size += mms->size;
-		RB_REMOVE(mmtree, &mm->rb_free, mms);
-		if (mm->mmalloc == NULL)
-			free(mms);
-		else
-			mm_free(mm->mmalloc, mms);
-	} else
-		prev = mms;
-
-	if (prev == NULL)
-		return;
-
-	/* Check if we can merge forwards */
-	mms = RB_NEXT(mmtree, &mm->rb_free, prev);
-	if (mms == NULL)
-		return;
-
-	if (MM_ADDRESS_END(prev) > mms->address)
-		fatal("mm_free: memory corruption: %p < %p(%zu)",
-		    mms->address, prev->address, prev->size);
-	if (MM_ADDRESS_END(prev) != mms->address)
-		return;
-
-	prev->size += mms->size;
-	RB_REMOVE(mmtree, &mm->rb_free, mms);
-
-	if (mm->mmalloc == NULL)
-		free(mms);
-	else
-		mm_free(mm->mmalloc, mms);
-}
-
-static void
-mm_sync_list(struct mmtree *oldtree, struct mmtree *newtree,
-    struct mm_master *mm, struct mm_master *mmold)
-{
-	struct mm_master *mmalloc = mm->mmalloc;
-	struct mm_share *mms, *new;
-
-	/* Sync free list */
-	RB_FOREACH(mms, mmtree, oldtree) {
-		/* Check the values */
-		mm_memvalid(mmold, mms, sizeof(struct mm_share));
-		mm_memvalid(mm, mms->address, mms->size);
-
-		new = mm_xmalloc(mmalloc, sizeof(struct mm_share));
-		memcpy(new, mms, sizeof(struct mm_share));
-		RB_INSERT(mmtree, newtree, new);
-	}
-}
-
-void
-mm_share_sync(struct mm_master **pmm, struct mm_master **pmmalloc)
-{
-	struct mm_master *mm;
-	struct mm_master *mmalloc;
-	struct mm_master *mmold;
-	struct mmtree rb_free, rb_allocated;
-
-	debug3("%s: Share sync", __func__);
-
-	mm = *pmm;
-	mmold = mm->mmalloc;
-	mm_memvalid(mmold, mm, sizeof(*mm));
-
-	mmalloc = mm_create(NULL, mm->size);
-	mm = mm_xmalloc(mmalloc, sizeof(struct mm_master));
-	memcpy(mm, *pmm, sizeof(struct mm_master));
-	mm->mmalloc = mmalloc;
-
-	rb_free = mm->rb_free;
-	rb_allocated = mm->rb_allocated;
-
-	RB_INIT(&mm->rb_free);
-	RB_INIT(&mm->rb_allocated);
-
-	mm_sync_list(&rb_free, &mm->rb_free, mm, mmold);
-	mm_sync_list(&rb_allocated, &mm->rb_allocated, mm, mmold);
-
-	mm_destroy(mmold);
-
-	*pmm = mm;
-	*pmmalloc = mmalloc;
-
-	debug3("%s: Share sync end", __func__);
-}
-
-void
-mm_memvalid(struct mm_master *mm, void *address, size_t size)
-{
-	void *end = (char *)address + size;
-
-	if (address < mm->address)
-		fatal("mm_memvalid: address too small: %p", address);
-	if (end < address)
-		fatal("mm_memvalid: end < address: %p < %p", end, address);
-	if (end > MM_ADDRESS_END(mm))
-		fatal("mm_memvalid: address too large: %p", address);
-}
diff --git a/openssh-7.2p2/monitor_mm.h b/openssh-7.2p2/monitor_mm.h
deleted file mode 100644
--- a/openssh-7.2p2/monitor_mm.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $OpenBSD: monitor_mm.h,v 1.6 2014/01/04 17:50:55 tedu Exp $ */
-
-/*
- * Copyright 2002 Niels Provos <provos@citi.umich.edu>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MM_H_
-#define _MM_H_
-
-struct mm_share {
-	RB_ENTRY(mm_share) next;
-	void *address;
-	size_t size;
-};
-
-struct mm_master {
-	RB_HEAD(mmtree, mm_share) rb_free;
-	struct mmtree rb_allocated;
-	void *address;
-	size_t size;
-
-	struct mm_master *mmalloc;	/* Used to completely share */
-};
-
-RB_PROTOTYPE(mmtree, mm_share, next, mm_compare)
-
-#define MM_MINSIZE		128
-
-#define MM_ADDRESS_END(x)	(void *)((char *)(x)->address + (x)->size)
-
-struct mm_master *mm_create(struct mm_master *, size_t);
-void mm_destroy(struct mm_master *);
-
-void mm_share_sync(struct mm_master **, struct mm_master **);
-
-void *mm_malloc(struct mm_master *, size_t);
-void *mm_xmalloc(struct mm_master *, size_t);
-void mm_free(struct mm_master *, void *);
-
-void mm_memvalid(struct mm_master *, void *, size_t);
-#endif /* _MM_H_ */
diff --git a/openssh-7.2p2/monitor_wrap.h b/openssh-7.2p2/monitor_wrap.h
--- a/openssh-7.2p2/monitor_wrap.h
+++ b/openssh-7.2p2/monitor_wrap.h
@@ -107,12 +107,9 @@ void mm_send_keystate(struct monitor*);
 /* bsdauth */
 int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
 int mm_bsdauth_respond(void *, u_int, char **);
 
 /* skey */
 int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
 int mm_skey_respond(void *, u_int, char **);
 
-/* zlib allocation hooks */
-void mm_init_compression(struct mm_master *);
-
 #endif /* _MM_WRAP_H_ */
diff --git a/openssh-7.2p2/myproposal.h b/openssh-7.2p2/myproposal.h
--- a/openssh-7.2p2/myproposal.h
+++ b/openssh-7.2p2/myproposal.h
@@ -156,17 +156,17 @@
 	"hmac-sha1"
 
 #define KEX_CLIENT_KEX KEX_SERVER_KEX
 #define	KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT
 #define KEX_CLIENT_MAC KEX_SERVER_MAC
 
 #endif /* WITH_OPENSSL */
 
-#define	KEX_DEFAULT_COMP	"none,zlib@openssh.com,zlib"
+#define	KEX_DEFAULT_COMP	"none,zlib@openssh.com"
 #define	KEX_DEFAULT_LANG	""
 
 #define KEX_CLIENT \
 	KEX_CLIENT_KEX, \
 	KEX_DEFAULT_PK_ALG, \
 	KEX_CLIENT_ENCRYPT, \
 	KEX_CLIENT_ENCRYPT, \
 	KEX_CLIENT_MAC, \
diff --git a/openssh-7.2p2/opacket.h b/openssh-7.2p2/opacket.h
--- a/openssh-7.2p2/opacket.h
+++ b/openssh-7.2p2/opacket.h
@@ -128,19 +128,16 @@ void	packet_disconnect(const char *, ...
 #define packet_set_server() \
 	ssh_packet_set_server(active_state)
 #define packet_set_authenticated() \
 	ssh_packet_set_authenticated(active_state)
 #define packet_get_input() \
 	ssh_packet_get_input(active_state)
 #define packet_get_output() \
 	ssh_packet_get_output(active_state)
-#define packet_set_compress_hooks(ctx, allocfunc, freefunc) \
-	ssh_packet_set_compress_hooks(active_state, ctx, \
-	    allocfunc, freefunc);
 #define packet_check_eom() \
 	ssh_packet_check_eom(active_state)
 #define set_newkeys(mode) \
 	ssh_set_newkeys(active_state, (mode))
 #define packet_get_state(m) \
 	ssh_packet_get_state(active_state, m)
 #define packet_set_state(m) \
 	ssh_packet_set_state(active_state, m)
diff --git a/openssh-7.2p2/openbsd-compat/Makefile.in b/openssh-7.2p2/openbsd-compat/Makefile.in
--- a/openssh-7.2p2/openbsd-compat/Makefile.in
+++ b/openssh-7.2p2/openbsd-compat/Makefile.in
@@ -13,17 +13,17 @@ CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir
 LIBS=@LIBS@
 AR=@AR@
 RANLIB=@RANLIB@
 INSTALL=@INSTALL@
 LDFLAGS=-L. @LDFLAGS@
 
 OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o
 
-COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o
+COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
 
 PORTS=port-aix.o port-irix.o port-linux.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o
 
 .c.o:
 	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
 
 all: libopenbsd-compat.a
 
diff --git a/openssh-7.2p2/openbsd-compat/openbsd-compat.h b/openssh-7.2p2/openbsd-compat/openbsd-compat.h
--- a/openssh-7.2p2/openbsd-compat/openbsd-compat.h
+++ b/openssh-7.2p2/openbsd-compat/openbsd-compat.h
@@ -259,17 +259,16 @@ int timingsafe_bcmp(const void *, const 
 int	bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t,
     u_int8_t *, size_t, unsigned int);
 #endif
 
 #ifndef HAVE_EXPLICIT_BZERO
 void explicit_bzero(void *p, size_t n);
 #endif
 
-void *xmmap(size_t size);
 char *xcrypt(const char *password, const char *salt);
 char *shadow_pw(struct passwd *pw);
 
 /* rfc2553 socket API replacements */
 #include "fake-rfc2553.h"
 
 /* Routines for a single OS platform */
 #include "bsd-cray.h"
diff --git a/openssh-7.2p2/openbsd-compat/xmmap.c b/openssh-7.2p2/openbsd-compat/xmmap.c
deleted file mode 100644
--- a/openssh-7.2p2/openbsd-compat/xmmap.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2002 Tim Rice.  All rights reserved.
- * MAP_FAILED code by Solar Designer.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* $Id: xmmap.c,v 1.15 2009/02/16 04:21:40 djm Exp $ */
-
-#include "includes.h"
-
-#include <sys/types.h>
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include <sys/stat.h>
-
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "log.h"
-
-void *
-xmmap(size_t size)
-{
-#ifdef HAVE_MMAP
-	void *address;
-
-# ifdef MAP_ANON
-	address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED,
-	    -1, (off_t)0);
-# else
-	address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
-	    open("/dev/zero", O_RDWR), (off_t)0);
-# endif
-
-#define MM_SWAP_TEMPLATE "/var/run/sshd.mm.XXXXXXXX"
-	if (address == (void *)MAP_FAILED) {
-		char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE;
-		int tmpfd;
-		mode_t old_umask;
-
-		old_umask = umask(0177);
-		tmpfd = mkstemp(tmpname);
-		umask(old_umask);
-		if (tmpfd == -1)
-			fatal("mkstemp(\"%s\"): %s",
-			    MM_SWAP_TEMPLATE, strerror(errno));
-		unlink(tmpname);
-		if (ftruncate(tmpfd, size) != 0)
-			fatal("%s: ftruncate: %s", __func__, strerror(errno));
-		address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
-		    tmpfd, (off_t)0);
-		close(tmpfd);
-	}
-
-	return (address);
-#else
-	fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported",
-	    __func__);
-#endif /* HAVE_MMAP */
-
-}
-
diff --git a/openssh-7.2p2/packet.c b/openssh-7.2p2/packet.c
--- a/openssh-7.2p2/packet.c
+++ b/openssh-7.2p2/packet.c
@@ -734,96 +734,16 @@ uncompress_buffer(struct ssh *ssh, struc
 		default:
 			ssh->state->compression_in_failures++;
 			return SSH_ERR_INTERNAL_ERROR;
 		}
 	}
 	/* NOTREACHED */
 }
 
-/* Serialise compression state into a blob for privsep */
-static int
-ssh_packet_get_compress_state(struct sshbuf *m, struct ssh *ssh)
-{
-	struct session_state *state = ssh->state;
-	struct sshbuf *b;
-	int r;
-
-	if ((b = sshbuf_new()) == NULL)
-		return SSH_ERR_ALLOC_FAIL;
-	if (state->compression_in_started) {
-		if ((r = sshbuf_put_string(b, &state->compression_in_stream,
-		    sizeof(state->compression_in_stream))) != 0)
-			goto out;
-	} else if ((r = sshbuf_put_string(b, NULL, 0)) != 0)
-		goto out;
-	if (state->compression_out_started) {
-		if ((r = sshbuf_put_string(b, &state->compression_out_stream,
-		    sizeof(state->compression_out_stream))) != 0)
-			goto out;
-	} else if ((r = sshbuf_put_string(b, NULL, 0)) != 0)
-		goto out;
-	r = sshbuf_put_stringb(m, b);
- out:
-	sshbuf_free(b);
-	return r;
-}
-
-/* Deserialise compression state from a blob for privsep */
-static int
-ssh_packet_set_compress_state(struct ssh *ssh, struct sshbuf *m)
-{
-	struct session_state *state = ssh->state;
-	struct sshbuf *b = NULL;
-	int r;
-	const u_char *inblob, *outblob;
-	size_t inl, outl;
-
-	if ((r = sshbuf_froms(m, &b)) != 0)
-		goto out;
-	if ((r = sshbuf_get_string_direct(b, &inblob, &inl)) != 0 ||
-	    (r = sshbuf_get_string_direct(b, &outblob, &outl)) != 0)
-		goto out;
-	if (inl == 0)
-		state->compression_in_started = 0;
-	else if (inl != sizeof(state->compression_in_stream)) {
-		r = SSH_ERR_INTERNAL_ERROR;
-		goto out;
-	} else {
-		state->compression_in_started = 1;
-		memcpy(&state->compression_in_stream, inblob, inl);
-	}
-	if (outl == 0)
-		state->compression_out_started = 0;
-	else if (outl != sizeof(state->compression_out_stream)) {
-		r = SSH_ERR_INTERNAL_ERROR;
-		goto out;
-	} else {
-		state->compression_out_started = 1;
-		memcpy(&state->compression_out_stream, outblob, outl);
-	}
-	r = 0;
- out:
-	sshbuf_free(b);
-	return r;
-}
-
-void
-ssh_packet_set_compress_hooks(struct ssh *ssh, void *ctx,
-    void *(*allocfunc)(void *, u_int, u_int),
-    void (*freefunc)(void *, void *))
-{
-	ssh->state->compression_out_stream.zalloc = (alloc_func)allocfunc;
-	ssh->state->compression_out_stream.zfree = (free_func)freefunc;
-	ssh->state->compression_out_stream.opaque = ctx;
-	ssh->state->compression_in_stream.zalloc = (alloc_func)allocfunc;
-	ssh->state->compression_in_stream.zfree = (free_func)freefunc;
-	ssh->state->compression_in_stream.opaque = ctx;
-}
-
 /*
  * Causes any further packets to be encrypted using the given key.  The same
  * key is used for both sending and reception.  However, both directions are
  * encrypted independently of each other.
  */
 
 void
 ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number)
@@ -2489,31 +2409,24 @@ packet_destroy_all(int audit_it, int pri
 #endif
 	}
 }
 
 /* Reset after_authentication and reset compression in post-auth privsep */
 static int
 ssh_packet_set_postauth(struct ssh *ssh)
 {
-	struct sshcomp *comp;
-	int r, mode;
+	int r;
 
 	debug("%s: called", __func__);
 	/* This was set in net child, but is not visible in user child */
 	ssh->state->after_authentication = 1;
 	ssh->state->rekeying = 0;
-	for (mode = 0; mode < MODE_MAX; mode++) {
-		if (ssh->state->newkeys[mode] == NULL)
-			continue;
-		comp = &ssh->state->newkeys[mode]->comp;
-		if (comp && comp->enabled &&
-		    (r = ssh_packet_init_compression(ssh)) != 0)
-			return r;
-	}
+	if ((r = ssh_packet_enable_delayed_compress(ssh)) != 0)
+		return r;
 	return 0;
 }
 
 /* Packet state (de-)serialization for privsep */
 
 /* turn kex into a blob for packet state serialization */
 static int
 kex_to_blob(struct sshbuf *m, struct kex *kex)
@@ -2567,17 +2480,16 @@ newkeys_to_blob(struct sshbuf *m, struct
 		goto out;
 	if (cipher_authlen(enc->cipher) == 0) {
 		if ((r = sshbuf_put_cstring(b, mac->name)) != 0 ||
 		    (r = sshbuf_put_u32(b, mac->enabled)) != 0 ||
 		    (r = sshbuf_put_string(b, mac->key, mac->key_len)) != 0)
 			goto out;
 	}
 	if ((r = sshbuf_put_u32(b, comp->type)) != 0 ||
-	    (r = sshbuf_put_u32(b, comp->enabled)) != 0 ||
 	    (r = sshbuf_put_cstring(b, comp->name)) != 0)
 		goto out;
 	r = sshbuf_put_stringb(m, b);
  out:
 	sshbuf_free(b);
 	return r;
 }
 
@@ -2628,19 +2540,17 @@ ssh_packet_get_state(struct ssh *ssh, st
 		return r;
 	if (cipher_get_keycontext(&state->send_context, p) != (int)slen)
 		return SSH_ERR_INTERNAL_ERROR;
 	if ((r = sshbuf_put_u32(m, rlen)) != 0 ||
 	    (r = sshbuf_reserve(m, rlen, &p)) != 0)
 		return r;
 	if (cipher_get_keycontext(&state->receive_context, p) != (int)rlen)
 		return SSH_ERR_INTERNAL_ERROR;
-
-	if ((r = ssh_packet_get_compress_state(m, ssh)) != 0 ||
-	    (r = sshbuf_put_stringb(m, state->input)) != 0 ||
+	if ((r = sshbuf_put_stringb(m, state->input)) != 0 ||
 	    (r = sshbuf_put_stringb(m, state->output)) != 0)
 		return r;
 
 	return 0;
 }
 
 /* restore key exchange results from blob for packet state de-serialization */
 static int
@@ -2684,17 +2594,16 @@ newkeys_from_blob(struct sshbuf *m, stru
 			goto out;
 		if (maclen > mac->key_len) {
 			r = SSH_ERR_INVALID_FORMAT;
 			goto out;
 		}
 		mac->key_len = maclen;
 	}
 	if ((r = sshbuf_get_u32(b, &comp->type)) != 0 ||
-	    (r = sshbuf_get_u32(b, (u_int *)&comp->enabled)) != 0 ||
 	    (r = sshbuf_get_cstring(b, &comp->name, NULL)) != 0)
 		goto out;
 	if (enc->name == NULL ||
 	    cipher_by_name(enc->name) != enc->cipher) {
 		r = SSH_ERR_INVALID_FORMAT;
 		goto out;
 	}
 	if (sshbuf_len(b) != 0) {
@@ -2812,18 +2721,17 @@ ssh_packet_set_state(struct ssh *ssh, st
 	    (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0)
 		return r;
 	if (cipher_get_keycontext(&state->send_context, NULL) != (int)slen ||
 	    cipher_get_keycontext(&state->receive_context, NULL) != (int)rlen)
 		return SSH_ERR_INVALID_FORMAT;
 	cipher_set_keycontext(&state->send_context, keyout);
 	cipher_set_keycontext(&state->receive_context, keyin);
 
-	if ((r = ssh_packet_set_compress_state(ssh, m)) != 0 ||
-	    (r = ssh_packet_set_postauth(ssh)) != 0)
+	if ((r = ssh_packet_set_postauth(ssh)) != 0)
 		return r;
 
 	sshbuf_reset(state->input);
 	sshbuf_reset(state->output);
 	if ((r = sshbuf_get_string_direct(m, &input, &ilen)) != 0 ||
 	    (r = sshbuf_get_string_direct(m, &output, &olen)) != 0 ||
 	    (r = sshbuf_put(state->input, input, ilen)) != 0 ||
 	    (r = sshbuf_put(state->output, output, olen)) != 0)
diff --git a/openssh-7.2p2/packet.h b/openssh-7.2p2/packet.h
--- a/openssh-7.2p2/packet.h
+++ b/openssh-7.2p2/packet.h
@@ -113,21 +113,16 @@ const void *ssh_packet_get_string_ptr(st
 void     ssh_packet_disconnect(struct ssh *, const char *fmt, ...)
 	__attribute__((format(printf, 2, 3)))
 	__attribute__((noreturn));
 void     ssh_packet_send_debug(struct ssh *, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
 
 int	 ssh_set_newkeys(struct ssh *, int mode);
 void	 ssh_packet_get_bytes(struct ssh *, u_int64_t *, u_int64_t *);
 
-typedef void *(ssh_packet_comp_alloc_func)(void *, u_int, u_int);
-typedef void (ssh_packet_comp_free_func)(void *, void *);
-void	 ssh_packet_set_compress_hooks(struct ssh *, void *,
-    ssh_packet_comp_alloc_func *, ssh_packet_comp_free_func *);
-
 int	 ssh_packet_write_poll(struct ssh *);
 int	 ssh_packet_write_wait(struct ssh *);
 int      ssh_packet_have_data_to_write(struct ssh *);
 int      ssh_packet_not_very_much_data_to_write(struct ssh *);
 
 int	 ssh_packet_connection_is_on_socket(struct ssh *);
 int	 ssh_packet_remaining(struct ssh *);
 void	 ssh_packet_send_ignore(struct ssh *, int);
diff --git a/openssh-7.2p2/servconf.c b/openssh-7.2p2/servconf.c
--- a/openssh-7.2p2/servconf.c
+++ b/openssh-7.2p2/servconf.c
@@ -984,18 +984,18 @@ static const struct multistate multistat
 	{ "without-password",		PERMIT_NO_PASSWD },
 	{ "prohibit-password",		PERMIT_NO_PASSWD },
 	{ "forced-commands-only",	PERMIT_FORCED_ONLY },
 	{ "yes",			PERMIT_YES },
 	{ "no",				PERMIT_NO },
 	{ NULL, -1 }
 };
 static const struct multistate multistate_compression[] = {
+	{ "yes",			COMP_DELAYED },
 	{ "delayed",			COMP_DELAYED },
-	{ "yes",			COMP_ZLIB },
 	{ "no",				COMP_NONE },
 	{ NULL, -1 }
 };
 static const struct multistate multistate_gatewayports[] = {
 	{ "clientspecified",		2 },
 	{ "yes",			1 },
 	{ "no",				0 },
 	{ NULL, -1 }
diff --git a/openssh-7.2p2/sshconnect2.c b/openssh-7.2p2/sshconnect2.c
--- a/openssh-7.2p2/sshconnect2.c
+++ b/openssh-7.2p2/sshconnect2.c
@@ -192,20 +192,20 @@ ssh_kex2(char *host, struct sockaddr *ho
 		fatal("%s: kex_names_cat", __func__);
 	myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s);
 	myproposal[PROPOSAL_ENC_ALGS_CTOS] =
 	    compat_cipher_proposal(options.ciphers);
 	myproposal[PROPOSAL_ENC_ALGS_STOC] =
 	    compat_cipher_proposal(options.ciphers);
 	if (options.compression) {
 		myproposal[PROPOSAL_COMP_ALGS_CTOS] =
-		myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none";
+		myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,none";
 	} else {
 		myproposal[PROPOSAL_COMP_ALGS_CTOS] =
-		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib";
+		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com";
 	}
 	myproposal[PROPOSAL_MAC_ALGS_CTOS] =
 	    myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
 	if (options.hostkeyalgorithms != NULL) {
 		if (kex_assemble_names(KEX_DEFAULT_PK_ALG,
 		    &options.hostkeyalgorithms) != 0)
 			fatal("%s: kex_assemble_namelist", __func__);
 		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
diff --git a/openssh-7.2p2/sshd.c b/openssh-7.2p2/sshd.c
--- a/openssh-7.2p2/sshd.c
+++ b/openssh-7.2p2/sshd.c
@@ -112,17 +112,16 @@
 #include "canohost.h"
 #include "hostfile.h"
 #include "auth.h"
 #include "authfd.h"
 #include "msg.h"
 #include "dispatch.h"
 #include "channels.h"
 #include "session.h"
-#include "monitor_mm.h"
 #include "monitor.h"
 #ifdef GSSAPI
 #include "ssh-gss.h"
 #endif
 #include "monitor_wrap.h"
 #include "audit.h"
 #include "ssh-sandbox.h"
 #include "version.h"
@@ -748,19 +747,16 @@ privsep_preauth(Authctxt *authctxt)
 				    ssh_err(r));
 				have_agent = 0;
 			}
 		}
 		if (box != NULL)
 			ssh_sandbox_parent_preauth(box, pid);
 		monitor_child_preauth(authctxt, pmonitor);
 
-		/* Sync memory */
-		monitor_sync(pmonitor);
-
 		/* Wait for the child's exit status */
 		while (waitpid(pid, &status, 0) < 0) {
 			if (errno == EINTR)
 				continue;
 			pmonitor->m_pid = -1;
 			fatal("%s: waitpid: %s", __func__, strerror(errno));
 		}
 		privsep_is_preauth = 0;
@@ -2761,19 +2757,16 @@ do_ssh2_kex(void)
 	myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(
 	    options.ciphers);
 	myproposal[PROPOSAL_MAC_ALGS_CTOS] =
 	    myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
 
 	if (options.compression == COMP_NONE) {
 		myproposal[PROPOSAL_COMP_ALGS_CTOS] =
 		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
-	} else if (options.compression == COMP_DELAYED) {
-		myproposal[PROPOSAL_COMP_ALGS_CTOS] =
-		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com";
 	}
 
 	if (options.rekey_limit || options.rekey_interval)
 		packet_set_rekey_limits(options.rekey_limit,
 		    (time_t)options.rekey_interval);
 
 	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
 	    list_hostkey_types());
diff --git a/openssh-7.2p2/sshd_config.5 b/openssh-7.2p2/sshd_config.5
--- a/openssh-7.2p2/sshd_config.5
+++ b/openssh-7.2p2/sshd_config.5
@@ -530,25 +530,27 @@ will be disconnected after approximately
 Sets a timeout interval in seconds after which if no data has been received
 from the client,
 .Xr sshd 8
 will send a message through the encrypted
 channel to request a response from the client.
 The default
 is 0, indicating that these messages will not be sent to the client.
 .It Cm Compression
-Specifies whether compression is allowed, or delayed until
+Specifies whether compression is enabled after
 the user has authenticated successfully.
 The argument must be
 .Dq yes ,
-.Dq delayed ,
+.Dq delayed
+(a legacy synonym for
+.Dq yes )
 or
 .Dq no .
 The default is
-.Dq delayed .
+.Dq yes .
 .It Cm DenyGroups
 This keyword can be followed by a list of group name patterns, separated
 by spaces.
 Login is disallowed for users whose primary group or supplementary
 group list matches one of the patterns.
 Only group names are valid; a numerical group ID is not recognized.
 By default, login is allowed for all groups.
 The allow/deny directives are processed in the following order:
