The 25-Year-Old BSD Bug 213
sproketboy writes with news that a developer named Marc Balmer has recently fixed a bug in a bit of BSD code which is roughly 25 years old. In addition to the OSnews summary, you can read Balmer's comments and a technical description of the bug.
"This code will not work as expected when seeking to the second entry of a block where the first has been deleted: seekdir() calls readdir() which happily skips the first entry (it has inode set to zero), and advance to the second entry. When the user now calls readdir() to read the directory entry to which he just seekdir()ed, he does not get the second entry but the third. Much to my surprise I not only found this problem in all other BSDs or BSD derived systems like Mac OS X, but also in very old BSD versions. I first checked 4.4BSD Lite 2, and Otto confirmed it is also in 4.2BSD. The bug has been around for roughly 25 years or more."
Re:Wait... Would you ever hit this? (Score:5, Informative)
Re:Many eyes make bugs shallow... (Score:5, Informative)
This bug has been around for a long time, but is only visible if you have large directories and delete files from them in between calls to readdir and seekdir. This is quite uncommon behaviour, and was incredibly uncommon 25 years ago when filesystems were much smaller and directories almost never contained enough files to require more than one or two disk blocks to store the directory.
When the Samba people found it, they decided to just code a work-around and not bother to report it to any of the BSD teams. If they had done, it would probably have been fixed in 22 years.
Now that it has been fixed in OpenBSD, the change can easily be taken and incorporated into FreeBSD, NetBSD, DragonFlyBSD and Darwin.
Re:Now it's time for a little housekeeping (Score:5, Informative)
Re:Many eyes make bugs shallow... (Score:2, Informative)
seekdir and readdir are unreliable when you're modifying the directory being read. The API requirement is that readdir return each directory entry that existed at the time the directory was opened exactly once. In the traditional UNIX implementation, the directory is simply a sequential stream of bytes; this is pretty easy -- you can simply lseek to the position that telldir returned. However, other systems don't use something that simple -- Mac OS X, for example, uses a B-Tree for the catalog file. Worse, they use a single catalog file for the entire filesystem's catalog, meaning that any modifications (adding, removing, or renaming files anywhere) causes the layout to change.
And telldir only returns a long, which -- in most implementations -- is smaller than off_t, so a simplistic implementation can have some problems. Of course, having a directory that's larger than 4GBytes could result in some other problems 8-).
Re:the developers probably knew about it (Score:1, Informative)
Marc Balmer uncovered the bug.
Marc Balmer confirmed the bug was sitting in the code of all BSDs (including Mac OS X), including a lot of old releases.
Marc Balmer confirmed the bug was already in 4.2BSD, released in August of 1983.
Mildly amusing, so +1 Funny in my book.
Re:Old Code (Score:5, Informative)
Only 4 years ago.
Re:Should it be fixed? (Score:5, Informative)
Re:Many eyes make bugs shallow... (Score:5, Informative)
Re:Many eyes make bugs shallow... (Score:1, Informative)
Re:Should it be fixed? (Score:2, Informative)
So it seems like POSIX says, "this function is not guaranteed to work". Sounds like people were aware of the problem for a long time.
Re:Old Code (Score:4, Informative)
analysis of th win2000 source code
Re:Many eyes make bugs shallow... (Score:5, Informative)
https://bugzilla.samba.org/show_bug.cgi?id=4715 [samba.org]
I did point out that no other POSIX system behaved like that, but that didn't seem to make much difference
Jeremy.
Re:Many eyes make bugs shallow... (Score:3, Informative)
b) truncating title attributes is not a bug