Date: Wed, 12 Apr 95 15:27:12 MDT From: terry@cs.weber.edu (Terry Lambert) To: craig@munich.gcomm.com (Craig Yap) Cc: bugs@FreeBSD.org Subject: Re: seekdir bug Message-ID: <9504122127.AA19075@cs.weber.edu> In-Reply-To: <199504121348.JAA27823@munich.gcomm.com> from "Craig Yap" at Apr 12, 95 09:48:27 am
next in thread | previous in thread | raw e-mail | index | archive | help
> There is a bug when seeking through a directory. telldir() seems to return > a position in the directory that doesnt match the name of the file. I've > included a program that will exploit the bug. I ran it as followed: [ ... seekdir after close then reopen of dir ... ] If there is a bug, it's in the man page. Here's what the Sun man page has to say: seekdir() sets the position of the next readdir() operation on the directory stream. The new position reverts to the one associated with the directory stream when the telldir() operation was performed. Values returned by telldir() are good only for the lifetime of the DIR pointer from which they are derived. If the directory is closed and then reopened, the telldir() value may be invalidated due to undetected directory compaction. It is safe to use a previ- ous telldir() value immediately after a call to opendir() and before any calls to readdir. Admittedly, no compation is taking place in your use of the code, at least not from the code itself. The main problem is that telldir/seekdir imply the ability to save state across opens; in reality, they are abominations, and their use is to be frowned upon. The way directory entries are returned in the opendir is through the use of the internal system call getdents() which is supposed to return an atomic block of directory entries (an atomic block being defined as a block of data wherin changes to the data will not span a block boundry). In other words, getdents() takes a snapshot that is guranteed to be consistant for an external observer. Then the readdir/telldir operations operate on the user space copy of the block. The telldir() returns an offset which is not supposed to be a seek offset in the file itself, but a block/offset_into_block combination. A lot of the current code assumes that it is an actual file offset -- this is bogus, since POSIX does not guarantee that directories are themselves represented via a file abstraction in the first place (it just so happens that for the majority of UNIX file systems that they are). So the first problem is that you are violating the usage protocol, and the second problem is that you are doing so with an interface that doesn't guarantee atomicity for lookup and directory modification operations. Terry Lambert terry@cs.weber.edu --- Any opinions in this posting are my own and not those of my present or previous employers.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9504122127.AA19075>