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
index | next in thread | previous in thread | raw e-mail
> 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.
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9504122127.AA19075>
