mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
9p: skip directory entries with names longer than NAME_MAX
The 9p wire format carries directory entry names of up to 65535 bytes and nothing on the client checks them against NAME_MAX. Since the previous patch, v9fs_dir_readdir_dotl() passes such names straight to dir_emit(), and the VFS only rejects names of PATH_MAX bytes or more in verify_dirent_name(), as -EIO, which again fails the whole getdents64() call. A name between NAME_MAX and PATH_MAX is therefore returned to userspace even though every later operation on it fails with -ENAMETOOLONG, and POSIX requires readdir() to only return components of at most NAME_MAX bytes. Nothing can use such an entry, so skip it instead of returning it or failing the listing, reusing the strlen() result that was already computed for dir_emit(). Log the skipped entry at P9_DEBUG_ERROR, the same level as the strscpy() failure message this replaces. Suggested-by: Dominique Martinet <asmadeus@codewreck.org> Link: https://lore.kernel.org/all/vz5bum547fqyxf5z4m3x7tuqkuq52jlopm65t7hvynqeulh7i3@2t4wnhfxs7qv/ Signed-off-by: Haobin Wu <853555@gmail.com> Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com> Message-ID: <20260918024851.51229-3-853555@gmail.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
This commit is contained in:
parent
8bb0279930
commit
edd807dc20
|
|
@ -184,6 +184,7 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx)
|
|||
}
|
||||
|
||||
while (rdir->head < rdir->tail) {
|
||||
size_t namelen;
|
||||
|
||||
err = p9dirent_read(fid->clnt, rdir->buf + rdir->head,
|
||||
rdir->tail - rdir->head,
|
||||
|
|
@ -193,10 +194,14 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
if (!dir_emit(ctx, curdirent.d_name,
|
||||
strlen(curdirent.d_name),
|
||||
QID2INO(&curdirent.qid),
|
||||
curdirent.d_type)) {
|
||||
namelen = strlen(curdirent.d_name);
|
||||
if (namelen > NAME_MAX) {
|
||||
p9_debug(P9_DEBUG_ERROR,
|
||||
"skip dentry: name length %zu > NAME_MAX\n",
|
||||
namelen);
|
||||
} else if (!dir_emit(ctx, curdirent.d_name, namelen,
|
||||
QID2INO(&curdirent.qid),
|
||||
curdirent.d_type)) {
|
||||
kfree(curdirent.d_name);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user