diff -ur openssh-3.4p1.orig/monitor_mm.c openssh-3.4p1/monitor_mm.c
--- openssh-3.4p1.orig/monitor_mm.c	Tue Jun 25 17:29:03 2002
+++ openssh-3.4p1/monitor_mm.c	Fri Jun 28 13:46:54 2002
@@ -30,6 +30,10 @@
 #include <sys/mman.h>
 #endif
 
+#ifndef HAVE_MMAP_ANON_SHARED
+#include <sys/shm.h>
+#endif
+
 #include "ssh.h"
 #include "xmalloc.h"
 #include "log.h"
@@ -90,8 +94,39 @@
 	if (address == MAP_FAILED)
 		fatal("mmap(%lu): %s", (u_long)size, strerror(errno));
 #else
-	fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported",
-	    __func__);
+	mm->shm_not_mmap = 0;
+
+	{	
+               int shmid;
+
+               shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|S_IRUSR|S_IWUSR);
+               if (shmid != -1) {
+                       address = shmat(shmid, NULL, 0);
+                       shmctl(shmid, IPC_RMID, NULL);
+                       if (address != MAP_FAILED)
+                               mm->shm_not_mmap = 1;
+               }
+       }
+       if (address == MAP_FAILED) {
+               char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE;
+               int tmpfd;
+               int save_errno;
+
+               tmpfd = mkstemp(tmpname);
+               if (tmpfd == -1)
+                       fatal("mkstemp(\"%s\"): %s",
+                           MM_SWAP_TEMPLATE, strerror(errno));
+               unlink(tmpname);
+               ftruncate(tmpfd, size);
+               address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
+                   tmpfd, 0);
+               save_errno = errno;
+               close(tmpfd);
+               errno = save_errno;
+       }
+	if (address == MAP_FAILED)
+		fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported",
+		    __func__);
 #endif
 
 	mm->address = address;
@@ -122,6 +157,28 @@
 	}
 }
 
+/* Zeroes out the written-to pages in an address space area */
+
+static void
+mm_clean(void *address, size_t size)
+{
+	u_char *ptr = (u_char *)address;
+	u_char *end = (u_char *)address + size;
+	u_long *ptr_l;
+	u_long *end_l;
+
+	while (((u_long)ptr % sizeof(u_long)) && ptr < end)
+		if (*ptr++) *(ptr - 1) = 0;
+	ptr_l = (u_long *)ptr;
+	end_l = (u_long *)end - 1;
+	while (ptr_l <= end_l) {
+		if (*ptr_l++) *(ptr_l - 1) = 0;
+	}
+	ptr = (u_char *)ptr_l;
+	while (ptr < end)
+		if (*ptr++) *(ptr - 1) = 0;
+}
+
 /* Destroys a memory mapped area */
 
 void
@@ -135,8 +192,14 @@
 		fatal("munmap(%p, %lu): %s", mm->address, (u_long)mm->size,
 		    strerror(errno));
 #else
-	fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported",
-	    __func__);
+	mm_clean(mm->address, mm->size);
+	if (mm->shm_not_mmap) {
+		if (shmdt(mm->address) == -1)
+			fatal("shmdt(%p): %s", mm->address, strerror(errno));
+        } else
+	if (munmap(mm->address, mm->size) == -1)
+		fatal("munmap(%p, %lu): %s", mm->address, (u_long)mm->size,
+		    strerror(errno));
 #endif
 	if (mm->mmalloc == NULL)
 		xfree(mm);
@@ -176,8 +239,12 @@
 	if (mms == NULL)
 		return (NULL);
 
+#if 0
 	/* Debug */
 	memset(mms->address, 0xd0, size);
+#else
+	mm_clean(mms->address, size);
+#endif
 
 	tmp = mm_make_entry(mm, &mm->rb_allocated, mms->address, size);
 
@@ -208,8 +275,12 @@
 	if (mms == NULL)
 		fatal("mm_free(%p): can not find %p", mm, address);
 
+#if 0
 	/* Debug */
 	memset(mms->address, 0xd0, mms->size);
+#else
+	mm_clean(mms->address, mms->size);
+#endif
 
 	/* Remove from allocated list and insert in free list */
 	RB_REMOVE(mmtree, &mm->rb_allocated, mms);
@@ -339,4 +410,7 @@
 		fatal("mm_memvalid: end < address: %p < %p", end, address);
 	if (end > (void *)((u_char *)mm->address + mm->size))
 		fatal("mm_memvalid: address too large: %p", address);
+	/* Redundant on most platforms */
+	if (size > mm->size)
+		fatal("mm_memvalid: size too large: %lu", (u_long)size);
 }
diff -ur openssh-3.4p1.orig/monitor_mm.h openssh-3.4p1/monitor_mm.h
--- openssh-3.4p1.orig/monitor_mm.h	Tue Jun 25 16:01:37 2002
+++ openssh-3.4p1/monitor_mm.h	Fri Jun 28 13:38:59 2002
@@ -40,6 +40,9 @@
 	struct mmtree rb_allocated;
 	void *address;
 	size_t size;
+#ifndef HAVE_MMAP_ANON_SHARED
+	int shm_not_mmap;
+#endif
 
 	struct mm_master *mmalloc;	/* Used to completely share */
 
@@ -52,6 +55,10 @@
 #define MM_MINSIZE		128
 
 #define MM_ADDRESS_END(x)	(void *)((u_char *)(x)->address + (x)->size)
+
+#ifndef HAVE_MMAP_ANON_SHARED
+#define MM_SWAP_TEMPLATE       "/var/run/sshd.mm.XXXXXXXX"
+#endif
 
 struct mm_master *mm_create(struct mm_master *, size_t);
 void mm_destroy(struct mm_master *);
diff -ur openssh-3.4p1.orig/servconf.c openssh-3.4p1/servconf.c
--- openssh-3.4p1.orig/servconf.c	Mon Jun 24 20:22:04 2002
+++ openssh-3.4p1/servconf.c	Fri Jun 28 13:38:59 2002
@@ -259,10 +259,9 @@
 
 #if !defined(HAVE_MMAP_ANON_SHARED)
 	if (use_privsep && options->compression == 1) {
-		error("This platform does not support both privilege "
-		    "separation and compression");
-		error("Compression disabled");
-		options->compression = 0;
+		verbose("This platform does not support anonymous "
+		    "shared mmap");
+		verbose("Using the Openwall workaround instead.");
 	}
 #endif
 
