diff options
author | kib <kib@FreeBSD.org> | 2011-01-19 12:19:25 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2011-01-19 12:19:25 +0000 |
commit | 71201deeff9b267a7d46889986c7386de40c4a4b (patch) | |
tree | dd61952946b2b5db0f870b07239e0b4b9347b214 /sys/compat/linux | |
parent | 687faa19af0628800a1a5a41a95324c18a58d63d (diff) | |
download | FreeBSD-src-71201deeff9b267a7d46889986c7386de40c4a4b.zip FreeBSD-src-71201deeff9b267a7d46889986c7386de40c4a4b.tar.gz |
In linuxolator getdents_common(), it seems there is no reason to loop
if no records where returned by VOP_READDIR(). Readdir implementations
allowed to return 0 records when first record is larger then supplied
buffer. In this case trying to execute VOP_READDIR() again causes the
syscall looping forewer.
The goto was there from the day 1, which goes back to 1995 year.
Reported and tested by: Beat G?tzi <beat chruetertee ch>
MFC after: 2 weeks
Diffstat (limited to 'sys/compat/linux')
-rw-r--r-- | sys/compat/linux/linux_file.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 9ff1cf0..44ad193 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -369,7 +369,6 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args, lbuf = malloc(LINUX_MAXRECLEN, M_TEMP, M_WAITOK | M_ZERO); vn_lock(vp, LK_SHARED | LK_RETRY); -again: aiov.iov_base = buf; aiov.iov_len = buflen; auio.uio_iov = &aiov; @@ -506,8 +505,10 @@ again: break; } - if (outp == (caddr_t)args->dirent) - goto again; + if (outp == (caddr_t)args->dirent) { + nbytes = resid; + goto eof; + } fp->f_offset = off; if (justone) |