Synopsis: mp(2) of append-only files may result in corrupted data.map(2) 
NetBSD versions: 1.0, 1.1, 1.2, and 1.2.1, 1.3 and 1.3.1.
Thanks to: Luke Mewburn, Darren Reed and Matthew Green.
Reported in NetBSD Advisory: NetBSD-SA1998-003

Index: vm_mmap.c
===================================================================
RCS file: /cvsroot/src/sys/vm/vm_mmap.c,v
retrieving revision 1.56
diff -c -r1.56 vm_mmap.c
*** vm_mmap.c	1998/03/28 16:58:30	1.56
--- vm_mmap.c	1998/05/10 11:44:40
***************
*** 55,60 ****
--- 55,61 ----
  #include <sys/file.h>
  #include <sys/mman.h>
  #include <sys/conf.h>
+ #include <sys/stat.h>
  
  #include <sys/mount.h>
  #include <sys/syscallargs.h>
***************
*** 130,135 ****
--- 131,137 ----
  		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;
***************
*** 263,270 ****
  		else if (prot & PROT_READ)
  			return (EACCES);
  		if (flags & MAP_SHARED) {
! 			if (fp->f_flag & FWRITE)
! 				maxprot |= VM_PROT_WRITE;
  			else if (prot & PROT_WRITE)
  				return (EACCES);
  		} else
--- 265,285 ----
  		else if (prot & PROT_READ)
  			return (EACCES);
  		if (flags & MAP_SHARED) {
! 			/*
! 			 * if the file is writable, only add PROT_WRITE to
! 			 * maxprot if the file is not immutable, append-only.
! 			 * otherwise, if we have asked for PROT_WRITE, return
! 			 * EPERM.
! 			 */
! 			if (fp->f_flag & FWRITE) {
! 				if ((error =
! 				    VOP_GETATTR(vp, &va, p->p_ucred, p)))
! 					return (error);
! 				if ((va.va_flags & (IMMUTABLE|APPEND)) == 0)
! 					maxprot |= VM_PROT_WRITE;
! 				else if (prot & PROT_WRITE)
! 					return (EPERM);
! 			}
  			else if (prot & PROT_WRITE)
  				return (EACCES);
  		} else