]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
smb: client: fix readdir returning wrong type with POSIX extensions
authorPhilipp Kerling <pkerling@casix.org>
Sun, 29 Jun 2025 17:05:05 +0000 (19:05 +0200)
committerSteve French <stfrench@microsoft.com>
Sun, 29 Jun 2025 21:16:29 +0000 (16:16 -0500)
When SMB 3.1.1 POSIX Extensions are negotiated, userspace applications
using readdir() or getdents() calls without stat() on each individual file
(such as a simple "ls" or "find") would misidentify file types and exhibit
strange behavior such as not descending into directories. The reason for
this behavior is an oversight in the cifs_posix_to_fattr conversion
function. Instead of extracting the entry type for cf_dtype from the
properly converted cf_mode field, it tries to extract the type from the
PDU. While the wire representation of the entry mode is similar in
structure to POSIX stat(), the assignments of the entry types are
different. Applying the S_DT macro to cf_mode instead yields the correct
result. This is also what the equivalent function
smb311_posix_info_to_fattr in inode.c already does for stat() etc.; which
is why "ls -l" would give the correct file type but "ls" would not (as
identified by the colors).

Cc: stable@vger.kernel.org
Signed-off-by: Philipp Kerling <pkerling@casix.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/readdir.c

index ba0193cf90334da53c4d58e11874b6cb65de22e3..4e5460206397440ddc9f5a8edd2739d28ab94790 100644 (file)
@@ -264,7 +264,7 @@ cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info,
        /* The Mode field in the response can now include the file type as well */
        fattr->cf_mode = wire_mode_to_posix(le32_to_cpu(info->Mode),
                                            fattr->cf_cifsattrs & ATTR_DIRECTORY);
-       fattr->cf_dtype = S_DT(le32_to_cpu(info->Mode));
+       fattr->cf_dtype = S_DT(fattr->cf_mode);
 
        switch (fattr->cf_mode & S_IFMT) {
        case S_IFLNK: