diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2013-06-19 19:54:20 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2013-06-19 19:54:20 +0400 |
commit | 04f8f69cb711ae5ec609eda786b64bb0726fd5b4 (patch) | |
tree | 438b0bce45239efc52e93c34f506330f0a0e4b22 /newlib/libc/posix/readdir_r.c | |
parent | c1d6d0547036543038d5687373813bdc84088eba (diff) |
* libc/posix/readdir_r.c: Fix potential read past dirp->dd_buf.
Diffstat (limited to 'newlib/libc/posix/readdir_r.c')
-rw-r--r-- | newlib/libc/posix/readdir_r.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/newlib/libc/posix/readdir_r.c b/newlib/libc/posix/readdir_r.c index b9a0b9024..eafbeca6a 100644 --- a/newlib/libc/posix/readdir_r.c +++ b/newlib/libc/posix/readdir_r.c @@ -42,6 +42,7 @@ static char sccsid[] = "@(#)readdir.c 5.7 (Berkeley) 6/1/90"; #include <dirent.h> #include <errno.h> #include <string.h> +#include <sys/param.h> extern int getdents (int fd, void *dp, int count); @@ -84,16 +85,17 @@ struct dirent *tmpdp; continue; } tmpdp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); - memcpy (dp, tmpdp, sizeof(struct dirent)); - if (dp->d_reclen <= 0 || - dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) { + if (tmpdp->d_reclen <= 0 || + tmpdp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) { #ifdef HAVE_DD_LOCK __lock_release_recursive(dirp->dd_lock); #endif *dpp = NULL; return -1; } + memcpy (dp, tmpdp, MIN (tmpdp->d_reclen, sizeof (struct dirent))); + dirp->dd_loc += dp->d_reclen; if (dp->d_ino == 0) continue; |