On Thu, 2023-12-28 at 15:15 -0500, trondmy@xxxxxxxxxx wrote: > From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> > > The fallback implementation for the get_name export operation uses > readdir() to try to match the inode number to a filename. That filename > is then used together with lookup_one() to produce a dentry. > A problem arises when we match the '.' or '..' entries, since that > causes lookup_one() to fail. This has sometimes been seen to occur for > filesystems that violate POSIX requirements around uniqueness of inode > numbers, something that is common for snapshot directories. > > This patch just ensures that we skip '.' and '..' rather than allowing a > match. > > Fixes: 21d8a15ac333 ("lookup_one_len: don't accept . and ..") > Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> > --- > fs/exportfs/expfs.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c > index 3ae0154c5680..84af58eaf2ca 100644 > --- a/fs/exportfs/expfs.c > +++ b/fs/exportfs/expfs.c > @@ -255,7 +255,9 @@ static bool filldir_one(struct dir_context *ctx, const char *name, int len, > container_of(ctx, struct getdents_callback, ctx); > > buf->sequence++; > - if (buf->ino == ino && len <= NAME_MAX) { > + /* Ignore the '.' and '..' entries */ > + if ((len > 2 || name[0] != '.' || (len == 2 && name[1] != '.')) && > + buf->ino == ino && len <= NAME_MAX) { > memcpy(buf->name, name, len); > buf->name[len] = '\0'; > buf->found = 1; Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>