*BSD News Article 17686


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!munnari.oz.au!ariel.ucs.unimelb.EDU.AU!werple.apana.org.au!news
From: andrew@werple.apana.org.au (Andrew Herbert)
Newsgroups: comp.os.386bsd.bugs
Subject: kernel writes to user space (was Re: Nethack)
Date: 30 Jun 1993 11:33:18 +1000
Organization: werple public-access unix, Melbourne
Lines: 60
Message-ID: <20qqgu$dj@werple.apana.org.au>
References: <20bfrm$le7@pdq.coe.montana.edu> <20cab6$b2d@binkley.cs.mcgill.ca> <C990xF.43n@sneaky.lonestar.org> <1993Jun29.181749.5833@fcom.cc.utah.edu>
NNTP-Posting-Host: werple.apana.org.au

terry@cs.weber.edu (A Wizard of Earth C) writes:

>In article <C990xF.43n@sneaky.lonestar.org> gordon@sneaky.lonestar.org (Gordon Burditt) writes:

>>Modified data is getting cached somewhere, probably in the VM system.
>>I suspect Nethack is modifying read-only storage somehow and the 
>>modified version is getting re-used.  But I haven't found the place
>>where it's doing it.

>Since the text pages are marked read only, obviously writes are occurring
>that are not trapped.  This is not an unreasonable assumption, given that
>writes are not trapped through a normal mechanism on 386 processers -- an
>exception is not generated in protected mode, only in unprotected mode.
...
>The way this is handled in most protected mode OS's on the brain-damaged
>Intel architecture is to ensure that copy-on-write data pages are marked
>read only, and that copy-on-write is actually handled during the trap...
>this implies a reverse (or indexed) lookup to determine if the trap is
>occuriing on a real read-only page or a copy-on-write page marked read
>only to generate the trap.

Exactly - these copy-on-write (actually read-only, as Terry says) protection
faults are not generated for data copied into user space by copyout() on the
i386, *nor* is it being handled manually by the copyout() routine.  I
recently wrote versions of copyin()/copyout() that are careful not to access
things they shouldn't, but copy-on-write handling is certainly a
spanner-in-the-works!  I have this terrible feeling I'm going to have to
change copyout() to check the page table entry for each page before it
copies it, and simulate a fault if the page is read-only. :)  A (presumably
incomplete and non-working) copyout() that does this can actually be found
in i386/locore.s, surrounded by "#ifdef notdef"s.

The copy-on-write handling in nethack is bypassed by something similar to
the program below.  Create a file "junk" that contains at least four
characters, then run the program a few times and see what happens - but make
sure you've installed Paul Kranenburg's VM deadlock patches (#147) first!

Andrew
--
/* tests for a copy-on-write bug when data is accessed in kernel mode */
/* andrew@werple.apana.org.au */

#include <stdio.h>
#include <sys/file.h>

char	pad1[4096] = "hello";
int	n[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
char	pad2[4096] = "there";

void main(void)
{
    int fd;

    printf("n[0] = %d\n", n[0]);

    fd = open("junk", O_RDONLY);
    read(fd, n, sizeof(n));

    printf("n[0] = %d\n", n[0]);
}