From: Thomas Veerman Date: Thu, 26 Jul 2012 12:42:55 +0000 (+0000) Subject: MFS: getdents fixes X-Git-Tag: v3.2.1~437 X-Git-Url: http://zhaoyanbai.com/repos/man.dnssec-checkds.html?a=commitdiff_plain;h=fa9199e049f9de4cb6f9a0690621e1d8e92789e2;p=minix.git MFS: getdents fixes .Use a bigger buffer to hold results .Do not try to store more data than user buffer can hold --- diff --git a/servers/mfs/const.h b/servers/mfs/const.h index d651a10cb..286ed9021 100644 --- a/servers/mfs/const.h +++ b/servers/mfs/const.h @@ -11,7 +11,6 @@ * should be more or less the same as * NR_VNODES in vfs */ -#define GETDENTS_BUFSIZ 257 #define INODE_HASH_LOG2 7 /* 2 based logarithm of the inode hash size */ #define INODE_HASH_SIZE ((unsigned long)1<b_data)); - if(tmpbuf_off + reclen > GETDENTS_BUFSIZ) { + if (userbuf_off + tmpbuf_off + reclen >= size) { + /* The user has no space for one more record */ + done = TRUE; + + /* Record the position of this entry, it is the + * starting point of the next request (unless the + * postion is modified with lseek). + */ + new_pos = ent_pos; + break; + } + + if (tmpbuf_off + reclen >= GETDENTS_BUFSIZE*GETDENTS_ENTRIES) { r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) userbuf_off, (vir_bytes) getdents_buf, @@ -621,46 +635,34 @@ int fs_getdents(void) userbuf_off += tmpbuf_off; tmpbuf_off = 0; - } - - if(userbuf_off + tmpbuf_off + reclen > size) { - /* The user has no space for one more record */ - done = TRUE; - - /* Record the position of this entry, it is the - * starting point of the next request (unless the - * postion is modified with lseek). - */ - new_pos = ent_pos; - break; - } - - dep = (struct dirent *) &getdents_buf[tmpbuf_off]; - dep->d_ino = dp->mfs_d_ino; - dep->d_off = ent_pos; - dep->d_reclen = (unsigned short) reclen; - memcpy(dep->d_name, dp->mfs_d_name, len); - dep->d_name[len] = '\0'; - tmpbuf_off += reclen; - } + } + + dep = (struct dirent *) &getdents_buf[tmpbuf_off]; + dep->d_ino = dp->mfs_d_ino; + dep->d_off = ent_pos; + dep->d_reclen = (unsigned short) reclen; + memcpy(dep->d_name, dp->mfs_d_name, len); + dep->d_name[len] = '\0'; + tmpbuf_off += reclen; + } - put_block(bp, DIRECTORY_BLOCK); - if(done) - break; + put_block(bp, DIRECTORY_BLOCK); + if (done) + break; } - if(tmpbuf_off != 0) { - r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) userbuf_off, + if (tmpbuf_off != 0) { + r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) userbuf_off, (vir_bytes) getdents_buf, (size_t) tmpbuf_off); - if (r != OK) { - put_inode(rip); - return(r); - } + if (r != OK) { + put_inode(rip); + return(r); + } - userbuf_off += tmpbuf_off; + userbuf_off += tmpbuf_off; } - if(done && userbuf_off == 0) + if (done && userbuf_off == 0) r = EINVAL; /* The user's buffer is too small */ else { fs_m_out.RES_NBYTES = userbuf_off;