>Synopsis:      rewinddir(3) does not invalidate buffer
>Category:      library
>Environment:
        System      : OpenBSD 7.7
        Details     : OpenBSD 7.7 (GENERIC.MP) #2: Sun Jun 29 09:04:02 MDT 2025
                         
r...@syspatch-77-amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP

        Architecture: OpenBSD.amd64
        Machine     : amd64
>Description:
According to POSIX.1-2004:
> The rewinddir() function shall reset the position of the directory
> stream to which dirp refers to the beginning of the directory. It
> shall also cause the directory stream to refer to the current state of
> the corresponding directory, as a call to opendir() would have
> done.

However, OpenBSD rewinddir(3) does not invalidate the buffer
dirp->dd_buf, so the next call to readdir(3) will reuse stale data.

>How-To-Repeat:
Reproducer:

#include <dirent.h>         
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

void main()
{
        DIR *dir = opendir(".");

        struct dirent *e;
        e = readdir(dir);
        puts(e->d_name);

        close(open("new", O_RDWR | O_CREAT, 0666));
        rewinddir(dir);

        puts("");
        while ((e = readdir(dir)))
                puts(e->d_name);
}

Run this in a dir which has a few files, but no file "new".  The file
"new" is being created, but the iteration after rewinddir does not
pick it up.

(I think this doesn't show up as a problem in practice since running
readdir until it returns 0 will do the right thing in rewinddir.)

>Fix:
I think it's enough to set dirp->dd_size = 0 in rewinddir, but I've
not tested this.

-- 
Leah Neukirchen  <l...@vuxu.org>  https://leahneukirchen.org/

Reply via email to