Messages in this thread Patch in this message | | | Date | Wed, 17 Nov 1999 12:22:39 -0500 | From | "Theodore Y. Ts'o" <> | Subject | Re: `filetype' ext2 feature causes dump to SEGV |
| |
From: patl@cag.lcs.mit.edu (Patrick J. LoPresti) Date: 17 Nov 1999 08:58:28 -0500
We have upgraded to e2fsprogs-1.18 and dump-0.4b9 on our RedHat-6.1 machines (kernel 2.2.13). On filesystems which we create with the most recent mke2fs, dump is aborting with a SEGV. This only happens when the filesystem is already populated; empty or nearly-empty filesystems do not cause the failure.
When we copy the files off, downgrade to e2fsprogs-1.15, re-run mke2fs, and copy the files back, the problem goes away. This behavior is very reproducible.
I would guess there is a bug in ext2fs_dir_iterate, or in dump's interaction with it, when the file system has the `filetype' feature enabled. This is the only difference I can discern between filesystems created by the old mke2fs and the new.
It's actually a bug in dump. It's not checking the superblock compatibility flags, so it didn't notice that it didn't know how to handle filesystems with the filetype feature. When it tried, it got itself into a lot of trouble. :-(
The problem was dump wasn't masking off the high bits of the dirent->name_len field, so it overran the size of the output buffer in convert_dir, and smashed pointers used by malloc/free. Dump then crashed in some other completely unrelated spot, later on. (Some additional sanity checks in this code would be a good idea.)
See below for the patch to dump-0.4b9/dump/traverse.c.
Here is a backtrace of the failure. (Incidentally, this was somewhat annoying to come by; I had to comment out dump's catching of SEGV in order to get a core dump. Running dump directly under gdb does not work because the crash happens in a forked subprocess.)
Yeah, there really ought to be a debugging flag which turns off all of the forks. It was a pain to have to manually comment out the fork in startnewtape() in order to be able to debug this under gdb. Stelian?
- Ted
--- traverse.c 1999/11/17 17:09:36 1.1 +++ traverse.c 1999/11/17 17:10:28 @@ -698,7 +698,7 @@ p = (struct convert_dir_context *)private; - reclen = EXT2_DIR_REC_LEN(dirent->name_len + 1); + reclen = EXT2_DIR_REC_LEN((dirent->name_len&0xFF) + 1); if (((p->offset + reclen - 1) / p->bs) != (p->offset / p->bs)) { dp = (struct direct *)(p->buf + p->prev_offset); dp->d_reclen += p->bs - (p->offset % p->bs); @@ -709,8 +709,8 @@ dp->d_ino = dirent->inode; dp->d_reclen = reclen; dp->d_type = 0; - dp->d_namlen = dirent->name_len; - strncpy(dp->d_name, dirent->name, dirent->name_len); + dp->d_namlen = dirent->name_len & 0xFF; + strncpy(dp->d_name, dirent->name, dp->d_namlen); dp->d_name[dp->d_namlen] = '\0'; p->prev_offset = p->offset; p->offset += reclen; - 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/
| |