Re: [RFC,PATCH] libfs dcache_readdir() and dcache_dir_lseek() bugfix

From: Jörn Engel
Date: Fri Nov 04 2005 - 10:45:11 EST


On Fri, 4 November 2005 16:34:20 +0100, jblunck@xxxxxxx wrote:
> On Fri, Nov 04, Jörn Engel wrote:
> > On Fri, 4 November 2005 16:11:04 +0100, jblunck@xxxxxxx wrote:
> > >
> > > True. Seeking to that offset should at least fail and shouldn't stop at the
> > > new entry. But SuSV3 says that the offset given by telldir() is valid until
> > > the next rewinddir(). This is no problem for directories that can only grow.
> > > I tried to implement some kind of deferred dput'ing of the d_child's but that
> > > was too hackish and was wasting memory. So the best thing I can do now is fail
> > > if someone wants to seek to an offset of an already unlinked file.
> >
> > Does that mean that, to satisfy the standard, you'd have to allow the
> > seek, but return 0 bytes on further reads, as you're already at (or
> > beyond, whatever) EOF?
>
> No. To satisfy the standard, it would be necessary to let the seek succeed and
> to return the already unlinked dentry or the next dentry (this is
> unspecified).

Do you have a link to the standard? Iirc, it is explicitly
unspecified whether files created/deleted after opendir/rewinddir are
returned. Why do you want to return one such unspecified file now?
Especially when the implementation is ugly and the whole concept
appears to be plain stupid.

> I think we should return the next dentry, therefore I let the
> seek fail (seekdir() doesn't even have a return value) and the cursor/f_pos is
> still at the old offset.
>
> The real problem is this IMHO:
> ...
> telldir() = a
> ...
> telldir() = b
> readdir() = foo.txt
> unlink(foo.txt)
> seekdir(a)
> seekdir(b)
> readdir() = ???
>
> With my patch the seekdir(b) doesn't find the offset and is placing the cursor
> at the end of the directory. In my understanding of the SuSV3 this should be
> possible and should return either "foo.txt" or the next entry after
> "foo.txt". I don't see any chance how I can implement that.

Does the above really happen, or is this just a theoretical case? At
least it looks as if ext3 with dir_index will simply barf on it:
/* Some one has messed with f_pos; reset the world */
if (info->last_pos != filp->f_pos) {
...

And imo, that is the correct behaviour. Anything else would leave the
door wide open for trivial DOS attacks on kernel memory.

Jörn

--
The strong give up and move away, while the weak give up and stay.
-- unknown
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/