Skip to content

Commit 0c93ac6

Browse files
committed
readdir: make sure to verify directory entry for legacy interfaces too
This does the directory entry name verification for the legacy "fillonedir" (and compat) interface that goes all the way back to the dark ages before we had a proper dirent, and the readdir() system call returned just a single entry at a time. Nobody should use this interface unless you still have binaries from 1991, but let's do it right. This came up during discussions about unsafe_copy_to_user() and proper checking of all the inputs to it, as the networking layer is looking to use it in a few new places. So let's make sure the _old_ users do it all right and proper, before we add new ones. See also commit 8a23eb8 ("Make filldir[64]() verify the directory entry filename is valid") which did the proper modern interfaces that people actually use. It had a note: Note that I didn't bother adding the checks to any legacy interfaces that nobody uses. which this now corrects. Note that we really don't care about POSIX and the presense of '/' in a directory entry, but verify_dirent_name() also ends up doing the proper name length verification which is what the input checking discussion was about. [ Another option would be to remove the support for this particular very old interface: any binaries that use it are likely a.out binaries, and they will no longer run anyway since we removed a.out binftm support in commit eac6165 ("x86: Deprecate a.out support"). But I'm not sure which came first: getdents() or ELF support, so let's pretend somebody might still have a working binary that uses the legacy readdir() case.. ] Link: https://lore.kernel.org/lkml/CAHk-=wjbvzCAhAtvG0d81W5o0-KT5PPTHhfJ5ieDFq+bGtgOYg@mail.gmail.com/ Acked-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 88a5af9 commit 0c93ac6

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

fs/readdir.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ static int fillonedir(struct dir_context *ctx, const char *name, int namlen,
150150

151151
if (buf->result)
152152
return -EINVAL;
153+
buf->result = verify_dirent_name(name, namlen);
154+
if (buf->result < 0)
155+
return buf->result;
153156
d_ino = ino;
154157
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
155158
buf->result = -EOVERFLOW;
@@ -405,6 +408,9 @@ static int compat_fillonedir(struct dir_context *ctx, const char *name,
405408

406409
if (buf->result)
407410
return -EINVAL;
411+
buf->result = verify_dirent_name(name, namlen);
412+
if (buf->result < 0)
413+
return buf->result;
408414
d_ino = ino;
409415
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
410416
buf->result = -EOVERFLOW;

0 commit comments

Comments
 (0)