Bug 2229529 - ntfs3: getdents64 returns incorrect d_type for symbolic links
Summary: ntfs3: getdents64 returns incorrect d_type for symbolic links
Keywords:
Status: CLOSED EOL
Alias: None
Product: Fedora
Classification: Fedora
Component: kernel
Version: 38
Hardware: x86_64
OS: Linux
unspecified
low
Target Milestone: ---
Assignee: Kernel Maintainer List
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2023-08-06 19:55 UTC by Adrian Torregrosa
Modified: 2024-05-28 13:41 UTC (History)
19 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2024-05-28 13:41:41 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
How I reproduce this behaviour (1.41 KB, text/plain)
2023-08-06 19:55 UTC, Adrian Torregrosa
no flags Details

Description Adrian Torregrosa 2023-08-06 19:55:18 UTC
Created attachment 1982003 [details]
How I reproduce this behaviour

Description of problem:
Apparently find does not find soft links when these are on an NTFS device

Version-Release number of selected component (if applicable):
findutils-4.9.0-3.fc38.x86_64

How reproducible:
Always

Steps to Reproduce:
1. Connect an NTFS-formatted device to your Fedora Workstation
2. In the directory where the OS mounts the NTFS device, create a file and a soft-link to that file
3. Give a command such as "find <that_directory> -type l"

Actual results:
The find command does not find the soft-link.

Expected results:
The find command should find the soft-link.

Additional info:
The find command does find soft-links under other formats such as EXT4.
The find command does find the soft-link in the NTFS device if it looks for regular files.

Comment 1 Lukáš Zaoral 2023-08-08 15:07:35 UTC
Hello!
I was able to reproduce this issue on my machine.  Unfortunately, this seems to be a bug in the kernel.  find internally uses the fts* functions from glibc to traverse the filesystem and it tries to minimise the number of (l)stat(2) calls by reusing as much information it already has acquired before.  For fts to work, glibc internally calls readdir(3) which is implemented using the getdents64(2) syscall.  The structure forwarded by readdir(3) from getdents64(2) for every directory entry also contains file type information which seems to be incorrect for symlinks on NTFS volumes as witnessed by the following experiment:

$mount
...
/dev/sda1 on /mnt/ntfs type ntfs3 (rw,relatime,uid=0,gid=0,iocharset=utf8)
$ cat ~/tmp/readdir_test.c
#include <dirent.h>
#include <stdio.h>
#include <sys/types.h>

int main(int argc, char* argv[])
{
    DIR* dp = opendir(argv[1]);
    if (dp == NULL) {
        perror("opendir");
        return 1;
    }

    struct dirent* dent;
    while ((dent = readdir(dp)) != NULL) {
        const char* type;
        switch (dent->d_type) {
            case DT_BLK:
                type = "block dev"; break;
            case DT_CHR:
                type = "char dev"; break;
            case DT_DIR:
                type = "dir"; break;
            case DT_FIFO:
                type = "pipe"; break;
            case DT_LNK:
                type = "symlink"; break;
            case DT_REG:
                type = "regular file"; break;
            case DT_SOCK:
                type = "socket"; break;
            case DT_UNKNOWN:
                type = "unknown"; break;
        }
        printf("name: %s, type: %s\n", dent->d_name, type);
    }

    closedir(dp);
}
$ cc ~/tmp/readdir_test.c
$ ./a.out /mnt/ntfs
name: ., type: dir
name: .., type: dir
name: a, type: regular file
name: b, type: regular file  <-- WRONG!


I've checked ls and while it also uses readdir(3), it always issues an explicit (l)stat(2) so that's the reason why the final displayed information are correct.

Comment 2 Lukáš Zaoral 2023-08-08 15:09:58 UTC
I forgot to mention that I've used the enclosed reproducer for the experiment above.

Comment 3 Aoife Moloney 2024-05-28 13:41:41 UTC
Fedora Linux 38 entered end-of-life (EOL) status on 2024-05-21.

Fedora Linux 38 is no longer maintained, which means that it
will not receive any further security or bug fix updates. As a result we
are closing this bug.

If you can reproduce this bug against a currently maintained version of Fedora Linux
please feel free to reopen this bug against that version. Note that the version
field may be hidden. Click the "Show advanced fields" button if you do not see
the version field.

If you are unable to reopen this bug, please file a new report against an
active release.

Thank you for reporting this bug and we are sorry it could not be fixed.


Note You need to log in before you can comment on or make changes to this bug.