isofs readdir boundarie and move sector error

From: Go Taniguchi (taniguchi@turbolinux.co.jp)
Date: Fri Jul 21 2000 - 02:54:43 EST


We have found a problem with readdir() for isofs. When there are a lot of files in a single directory, and when you copy that directory, some of the files can disappear. For example, we found this with the Windows 2000 CD-ROM.

After looking into it, it seems that there is a boundary error in linux/fs/isofs/dir.c. When the sector size is 2048 and the directory entry offset is also 2048, there is a problem.

When de_len, the sum of the buffer start address plus the offset becomes 2048 and *de_len is zero, then it skips one sector and you there fore skip some files.

Please look at the patch I have included for details.

--- linux/fs/isofs/dir.c.orig Sat Apr 24 13:20:38 1999
+++ linux/fs/isofs/dir.c Fri Jul 21 02:37:16 2000
@@ -160,9 +163,11 @@
                de = (struct iso_directory_record *) (bh->b_data + offset);
                if(first_de) inode_number = (block << bufbits) + (offset & (bufs
ize - 1));
 
- de_len = *(unsigned char *) de;
+ /* Check boundaries and get length. by GO! */
+ if (offset < bufsize) de_len = *(unsigned char *) de;
 #ifdef DEBUG
- printk("de_len = %ld\n", de_len);
+ if (offset < bufsize) printk("de_len = %ld\n", de_len);
+ else printk("Move to next sector\n");
 #endif
            
 
@@ -170,15 +175,15 @@
                   CDROM sector. If we are at the end of the directory, we
                   kick out of the while loop. */
 
- if ((de_len == 0) || (offset >= bufsize) ) {
+ if ((offset >= bufsize) || (de_len == 0) ) {
                        brelse(bh);
- if (de_len == 0) {
+ if (offset >= bufsize) { /*Check first. by GO!*/
+ offset -= bufsize;
+ filp->f_pos += offset;
+ } else {
                                filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE
 - 1))
                                               + ISOFS_BLOCK_SIZE);
                                offset = 0;
- } else {
- offset -= bufsize;
- filp->f_pos += offset;
                        }
 
                        if (filp->f_pos >= inode->i_size)



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Jul 23 2000 - 21:00:15 EST