Subject: kern/13201: malicious user can get a copy of partial kernel memory
To: None <gnats-bugs@gnats.netbsd.org>
From: Atsushi Onoe <onoe@sm.sony.co.jp>
List: netbsd-bugs
Date: 06/14/2001 11:11:35
>Number:         13201
>Category:       kern
>Synopsis:       malicious user can get a copy of partial kernel memory
>Confidential:   yes
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 13 19:10:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Atsushi Onoe
>Release:        NetBSD-current 010607
>Organization:
	Sony Corporation
>Environment:
System: NetBSD duplo.sm.sony.co.jp 1.5W NetBSD 1.5W (DUPLO) #422: Wed Jun 13 01:41:29 JST 2001 onoe@duplo.sm.sony.co.jp:/work/netbsd/obj/DUPLO i386
Architecture: i386
Machine: i386
>Description:
	When a program write a data to a mmapped page whose corresponding
	file system block is not assigned yet (i.e. hole), other pages
	within the block is not initialized to zero and stored to the
	allocated block of the file system.
	This is obviously broken for the application, and it may disclose
	some of kernel memory to the user, which may include private
	mail, password, ...

	Since the problem occurs only in odd page at the file, I think
	it occurs only in the environment whose fsbsize > page size.

	NetBSD 1.5.1 seems to OK.

	See PR 13189.

>How-To-Repeat:
	Run attached program.

	% ./a.out
	filling 32768 pages
	testing 32768 pages
	a.out: corrupted: off 0x1001 data 0x8a

/*------------------------------------------------------------------*/
#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>

#define	FNAME	"testfile"
#define	FSIZE	(128*1024*1024)		/* total physical memory */
#define	PSIZE	4096			/* page size */

u_char zero[PSIZE];

main()
{
	int fd, off, i;
	u_char *p;

	if ((fd = open(FNAME, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0)
		err(1, "open: %s", FNAME);
	if (ftruncate(fd, FSIZE) < 0)
		err(1, "ftruncate: 0x%x", FSIZE);
	p = mmap(NULL, FSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if (p == MAP_FAILED)
		err(1, "mmap");
	printf("filling %d pages\n", FSIZE / PSIZE);
	for (off = 0; off < FSIZE; off += PSIZE)
		p[off] = 'a';
	zero[0] = 'a';
	printf("testing %d pages\n", FSIZE / PSIZE);
	for (off = 0; off < FSIZE; off += PSIZE) {
		if (memcmp(p + off, zero, PSIZE) != 0) {
			for (i = 0; i < PSIZE; i++, off++)
				if (p[off] != zero[i])
					break;
			errx(2, "corrupted: off 0x%x data 0x%x", off, p[off]);
		}
	}
	printf("test ok\n");
	exit(0);
}
/*------------------------------------------------------------------*/
>Fix:
	none provided.
>Release-Note:
>Audit-Trail:
>Unformatted: