On Tue, 17 Jun 2008, maximilian attems wrote: > > > klibc cpio segfaults extracting various cpio files. It seems to work for > > small files, but fail for larger ones, including the d-i root floppy > > image. > > > > For example: > > > > [EMAIL PROTECTED]:/tmp/empty>wget > > http://people.debian.org/~joeyh/d-i/images/20080401-09:01/floppy/root.img > > [EMAIL PROTECTED]:/tmp/empty>zcat root.img | sudo /usr/lib/klibc/bin/cpio -i > > zsh: broken pipe zcat root.img | > > zsh: segmentation fault sudo /usr/lib/klibc/bin/cpio -i > > right easy testcase.
ok so doublechecked that it is not a type issue. right small files needs to be really small according to my tests. but building klibc with debug aka make V=1 DEBUG=y KLIBCOPTFLAGS='-g -Os -D DEBUG_MALLOC' it seems that with gcc-4.3 doesn't get the sscanf() in cpio.c right so thanks to hpa that patch got proposed diff --git a/usr/utils/cpio.c b/usr/utils/cpio.c index 8acfe6f..3df8927 100644 --- a/usr/utils/cpio.c +++ b/usr/utils/cpio.c @@ -82,19 +82,24 @@ int io_block_size = 512; struct new_cpio_header { unsigned short c_magic; - unsigned long c_ino; - unsigned long c_mode; - unsigned long c_uid; - unsigned long c_gid; - unsigned long c_nlink; - unsigned long c_mtime; - unsigned long c_filesize; - long c_dev_maj; - long c_dev_min; - long c_rdev_maj; - long c_rdev_min; - unsigned long c_namesize; - unsigned long c_chksum; + union { + struct { + unsigned long c_ino; + unsigned long c_mode; + unsigned long c_uid; + unsigned long c_gid; + unsigned long c_nlink; + unsigned long c_mtime; + unsigned long c_filesize; + long c_dev_maj; + long c_dev_min; + long c_rdev_maj; + long c_rdev_min; + unsigned long c_namesize; + unsigned long c_chksum; + }; + unsigned long c_hdr[13]; + }; char *c_name; char *c_tar_linkname; }; @@ -897,18 +902,17 @@ static void copyin_file(struct new_cpio_header *file_hdr, int in_file_des) static void read_in_new_ascii(struct new_cpio_header *file_hdr, int in_des) { - char ascii_header[112]; - - tape_buffered_read(ascii_header, in_des, 104L); - ascii_header[104] = '\0'; - sscanf(ascii_header, - "%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx", - &file_hdr->c_ino, &file_hdr->c_mode, &file_hdr->c_uid, - &file_hdr->c_gid, &file_hdr->c_nlink, &file_hdr->c_mtime, - &file_hdr->c_filesize, &file_hdr->c_dev_maj, - &file_hdr->c_dev_min, &file_hdr->c_rdev_maj, - &file_hdr->c_rdev_min, &file_hdr->c_namesize, - &file_hdr->c_chksum); + char ascii_header[112], *ah, hexbuf[9]; + int i; + + tape_buffered_read(ascii_header, in_des, 13*8); + ah = ascii_header; + hexbuf[8] = '\0'; + for (i = 0; i < 13; i++) { + memcpy(hexbuf, ah, 8); + file_hdr->c_hdr[i] = strtoul(hexbuf, NULL, 16); + ah += 8; + } /* Read file name from input. */ if (file_hdr->c_name != NULL) free(file_hdr->c_name); but the memory corruption hitting that free seems to come from another fishy culprit. this looks like a recently-allocated buffer overwriting the head of the free block following it. -- maks -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]