Apply by doing
	cd /usr/src/sys/vm
	patch -p0 < immutable.patch

And then rebuild your kernel.

Index: vm_mmap.c
===================================================================
RCS file: /cvs/src/sys/vm/vm_mmap.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- vm_mmap.c	1998/02/25 22:13:46	1.13
+++ vm_mmap.c	1998/05/11 19:43:11	1.14
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vm_mmap.c,v 1.13 1998/02/25 22:13:46 deraadt Exp $	*/
+/*	$OpenBSD: vm_mmap.c,v 1.14 1998/05/11 19:43:11 niklas Exp $	*/
 /*	$NetBSD: vm_mmap.c,v 1.47 1996/03/16 23:15:23 christos Exp $	*/
 
 /*
@@ -56,6 +56,7 @@
 #include <sys/file.h>
 #include <sys/mman.h>
 #include <sys/conf.h>
+#include <sys/stat.h>
 
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
@@ -131,6 +132,7 @@
 		syscallarg(long) pad;
 		syscallarg(off_t) pos;
 	} */ *uap = v;
+	struct vattr va;
 	register struct filedesc *fdp = p->p_fd;
 	register struct file *fp;
 	struct vnode *vp;
@@ -248,13 +250,37 @@
 		/*
 		 * If we are sharing potential changes (either via MAP_SHARED
 		 * or via the implicit sharing of character device mappings),
-		 * and we are trying to get write permission although we
-		 * opened it without asking for it, bail out.
+		 * there are security issues with giving out PROT_WRITE
 		 */
-		if (((flags & MAP_SHARED) != 0 || vp->v_type == VCHR) &&
-		    (fp->f_flag & FWRITE) == 0 && (prot & PROT_WRITE) != 0)
-			return (EACCES);
-		else
+		if ((flags & MAP_SHARED) || vp->v_type == VCHR) {
+
+			/* In case we opened the thing readonly... */
+			if (!(fp->f_flag & FWRITE)) {
+				/*
+				 * If we are trying to get write permission
+				 * bail out, otherwise go ahead but don't
+				 * raise maxprot to contain VM_PROT_WRITE, as
+				 * we have not asked for write permission at
+				 * all.
+				 */
+				if (prot & PROT_WRITE)
+					return (EACCES);
+
+			/*
+			 * If the file is writable, only add PROT_WRITE to
+			 * maxprot if the file is not immutable, append-only.
+			 * If it is, and if we are going for PROT_WRITE right
+			 * away, return EPERM.
+			 */
+			} else if ((error =
+			    VOP_GETATTR(vp, &va, p->p_ucred, p)))
+				return (error);
+			else if (va.va_flags & (IMMUTABLE|APPEND)) {
+				if (prot & PROT_WRITE)
+					return (EPERM);
+			} else
+				maxprot |= VM_PROT_WRITE;
+		} else
 			maxprot |= VM_PROT_WRITE;
 		handle = (caddr_t)vp;
 	} else {