bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug in readdir/readdir64 due to getdents


From: Tsafrir Dan
Subject: bug in readdir/readdir64 due to getdents
Date: Sun, 01 Feb 2004 21:30:39 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5b) Gecko/20030827

Hello,

1- This is the 3rd time I'm reporting this bug (maybe this time I will
   get a response): The following program might enter an endless loop
   due to a bug in getdents(3):

        DIR           * dir = opendir("some-directory");
        struct dirent * e;
        while( (e = readdir64(dir)) != NULL ) {
                //
                // readir/readdir64 might never return NULL
                //
                printf("ino=%d name=%s\n", e->d_ino, e->d_name)
        }

2- Most of the problem is caused due to the fact that the implementation
   of glibc's getdents() relies on the `d_off' field from struct dirent
   as being the *byte* offset of the next dirent:

        struct dirent
        {
            long d_ino;                 /* inode number */
            off_t d_off;                /* offset to next dirent */
            unsigned short d_reclen;    /* length of this dirent */
            char d_name [NAME_MAX+1];   /* file name (null-terminated) */
        }

3- The linux-kernel people however use it in a completely different manner
   (e.g. the *serial number* of the next dirent, i.e. this is indeed the
   offset but when counted in dirents + the name they contain).

4- Fortunately, there is actually no need to use d_off as all the needed
   information is embedded in the d_reclen field (dirents are consecutive
   and the "next" dirent is found exactly after the current dirent).

5- And indeed, glibc's getdents() uses the above technique most of the time.
   But, there are certain exceptional conditions that might trigger
   getdents() to stop using on the dependable d_reclen and start using
   the unreliable d_off (Furthermore, these exceptional-conditions are
   identified based on the unreliable information held by d_off).

6- The linux kernel folks do not intend to change the data of their
   'struct dirent'. They want it just the way it is and don't care
   if the glibc folks "wrongly" interpret the `d_off' field (this
   applies both to readir and readdir64).

7- One aspect of this bug was actually reported in 2001:
       http://mail.gnu.org/archive/html/bug-glibc/2001-03/msg00048.html
   but was wrongly dismissed by Ulrich Drepper who claimed that the bug
   is actually in the linux kernel.

8- A complete description of the bug (along with a few other minor bugs)
   and a very short and simple patch is found in my post:
       http://mail.gnu.org/archive/html/bug-glibc/2003-12/msg00027.html

Please respond.
Thanks,
        --Dan






reply via email to

[Prev in Thread] Current Thread [Next in Thread]