Re: [PATCH v2 2/2] 9p: skip directory entries with names longer than NAME_MAX
From: Christian Schoenebeck
Date: Wed Sep 16 2026 - 16:10:55 EST
On Wednesday, 16 September 2026 15:54:03 CEST Haobin Wu wrote:
> 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().
>
> Suggested-by: Dominique Martinet <asmadeus@xxxxxxxxxxxxx>
> Link:
> https://lore.kernel.org/all/vz5bum547fqyxf5z4m3x7tuqkuq52jlopm65t7hvynqeulh
> 7i3@2t4wnhfxs7qv/ Assisted-by: Claude:claude-fable-5-1
> Signed-off-by: Haobin Wu <853555@xxxxxxxxx>
> ---
> fs/9p/vfs_dir.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
> index af00b79d801e..ad6fdc99883d 100644
> --- a/fs/9p/vfs_dir.c
> +++ b/fs/9p/vfs_dir.c
> @@ -173,6 +173,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,
> @@ -182,10 +183,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_VFS,
> + "skipping entry with %zu byte name\n",
> + namelen);
Fair to say why:
"skip dentry: name length %zu > NAME_MAX"
This is only handled for 9p2000.L so far. For legacy 9p2000(.u) this should
then also be limited in v9fs_dir_readdir() IMO.
/Christian
> + } else if (!dir_emit(ctx, curdirent.d_name, namelen,
> + QID2INO(&curdirent.qid),
> + curdirent.d_type)) {
> kfree(curdirent.d_name);
> return 0;
> }