diff options
authorJeffrey Mitchell <>2020-09-15 16:42:52 -0500
committerGreg Kroah-Hartman <>2020-10-07 08:02:51 +0200
commita98e3583bd8d4ed8c5cab6a154a645aff8ea5873 (patch)
parent6846eb76234461c498be72c3d27c641cd245ca40 (diff)
nfs: Fix security label length not being reset
[ Upstream commit d33030e2ee3508d65db5644551435310df86010e ] nfs_readdir_page_filler() iterates over entries in a directory, reusing the same security label buffer, but does not reset the buffer's length. This causes decode_attr_security_label() to return -ERANGE if an entry's security label is longer than the previous one's. This error, in nfs4_decode_dirent(), only gets passed up as -EAGAIN, which causes another failed attempt to copy into the buffer. The second error is ignored and the remaining entries do not show up in ls, specifically the getdents64() syscall. Reproduce by creating multiple files in NFS and giving one of the later files a longer security label. ls will not see that file nor any that are added afterwards, though they will exist on the backend. In nfs_readdir_page_filler(), reset security label buffer length before every reuse Signed-off-by: Jeffrey Mitchell <> Fixes: b4487b935452 ("nfs: Fix getxattr kernel panic and memory overflow") Signed-off-by: Trond Myklebust <> Signed-off-by: Sasha Levin <>
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 5a331da5f55a..785f46217f11 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -579,6 +579,9 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
do {
+ if (entry->label)
+ entry->label->len = NFS4_MAXLABELLEN;
status = xdr_decode(desc, entry, &stream);
if (status != 0) {
if (status == -EAGAIN)