*BSD News Article 17885


Return to BSD News archive

Newsgroups: comp.os.386bsd.bugs
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!olivea!pagesat!spssig.spss.com!news.oc.com!utacfd.uta.edu!rwsys!sneaky!gordon
From: gordon@sneaky.lonestar.org (Gordon Burditt)
Subject: Re: Nethack
Message-ID: <C9J9H8.Ltu@sneaky.lonestar.org>
Organization: Gordon Burditt
References: <20bfrm$le7@pdq.coe.montana.edu> <20cab6$b2d@binkley.cs.mcgill.ca> <C990xF.43n@sneaky.lonestar.org>
Date: Fri, 2 Jul 1993 10:36:37 GMT
Lines: 57

Ok, I managed to duplicate the "nethack problem" in a much simpler program.
System:  386bsd, patchkit 0.2.3.

It takes an initialized variable foo, prints its value, reads part of
the password file into it, and prints it.  The first printout isn't
supposed to change based on previous executions of the program.

% cc -o bug bug.c
% cp bug gub
Now, run gub twice.  The second time, you get password file data for the
before AND after printouts.  The modified page is hanging around 
somewhere in the system between executions.
No, this highly useful program :-( is NOT being used by more than one
user at a time, and it doesn't fork(), and the sticky bit isn't set.
% cmp bug gub
The changes DO NOT get written back to the executable.  Maybe
some other bug does this, but this one doesn't.
% cp bug gub
Run gub.  You get the correct BEFORE printout this time.
Somehow the data hanging around in the system got flushed or fixed.
Run gub.  The problem is back again.
% cmp bug gub
Changes still not written back to executable ...

The bar and baz variables are needed to make sure the page foo is on
is not written to by ordinary store instructions as well as read().


Now, the question I have is, with this bug in the system, why does
it stay up for more than 10 minutes?  Why can I run the compiler
without it crashing?  

Is there a 486-specific fix for this (set the WP bit in the cr0 register?  
anything else needed or is that alone enough?)

bug.c follows:

# include <fcntl.h>
/* need more include files */

/* these variables are NOT read-only! */
char bar[8196] = "dummy";
char foo[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
char baz[8196] = "dummy";
main()
{
	int	fd;

	fd = open("/etc/passwd", O_RDONLY); /* need error check */
	printf("%s\n", foo);
	read(fd, foo, sizeof(foo)); /* need error check */
	printf("%s\n", foo);
	exit(0);
}

					Gordon L. Burditt
					sneaky.lonestar.org!gordon