lkml.org 
[lkml]   [2005]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [RFC,PATCH] libfs dcache_readdir() and dcache_dir_lseek() bugfix
From
Date
On Fri, 2005-11-04 at 16:11 +0100, jblunck@suse.de wrote:
> On Fri, Nov 04, Miklos Szeredi wrote:
>
> > > As I said: "Old glibc implementations (e.g. glibc-2.2.5) are
> > > lseeking after every call to getdents() ..."
> >
> > Hmm, why would it do that? This seems like it's glibc being stupid.
> >
>
> Well, glibc is that stupid and triggers the bug.

It is due to the kernel's 32-bit struct dirent being smaller than
glibc's 32-bit struct dirent (glibc has the extra ->d_type field).
Because the dirent record length depends on the filename length, the
exact expansion factor for the results of a call to getdents() may not
be precomputed.
glibc uses a heuristic in order to estimate the expansion size, and then
uses that to allocate an intermediate buffer in which to store the
results of the getdents syscall.
If the contents of said intermediate buffer still happen to overflow the
user-allocated buffer, then glibc calls lseek() in order to rewind the
file pointer to the next entry it wants to read (and screws any
filesystem that doesn't support lseek on directories).

This code appears still to be part of glibc, however it is rarely
triggered these days because glibc's implementation now defaults to
using the getdents64 syscall (if it exists) instead of the 32-bit
version. Since the kernel's struct dirent64 is the same size as the
glibc struct dirent64 (and larger than the 32-bit struct dirent), there
is never any chance of buffer overflow.

The new bug is rather that glibc will return EOVERFLOW, and try to
rewind your file pointer if your filesystem happens to return 64-bit
offsets to getdents64().

> > Unfortunately I can't since I don't have such old glibc.
>
> The testcase is similar to what "rm *" with the old glibc would do. It just
> a testcase to show where the problem is.

'rm -rf' on a large directory used to be a great way to trigger it.

Cheers,
Trond

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-11-04 17:30    [from the cache]
©2003-2011 Jasper Spaans