| Summary: | /usr/bin/cmp coredumps while reading a faulty CD-R | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Cinek <cinekcvs> |
| Component: | i386 | Assignee: | David Schultz <das> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.7-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
> >Description: > When using the command /usr/bin/cmp from the default > FreeBSD-4.7 package, it is possible to produce a coredump. > It seems, there is a problem in handling errors while > reading faulty files. It happened to me while I was comparing > two files which I suspected to be dupes on my CD-Rs. I think there is a problem with mmap() on files with i/o errors in them. Pages should not be mapped if some part of them is unreadable, and this should result in the application getting signals. cmp makes no attempt to handle signals. > I guess it will not help much when I post the output > from gdb without symbol tables, but let's try at least: Not much, but you might be able to see that the fauilting instruction is an ordinary memory access, which would indicate that the problem is just unmapped memory. Bruce On Monday 18 November 2002 12:21, Bruce Evans wrote: > I think there is a problem with mmap() on files with i/o errors in > them. Pages should not be mapped if some part of them is unreadable, > and this should result in the application getting signals. cmp makes > no attempt to handle signals. I see. I guess I cannot help much about it. > Not much, but you might be able to see that the fauilting instruction > is an ordinary memory access, which would indicate that the problem is > just unmapped memory. I have disassembled the part and indeed a memory access is causing the segfault. I will paste some lines here: Program terminated with signal 11, Segmentation fault. 0x8048e17 in open () 0x8048e14 <open+1904>: mov 0xfffffff8(%ebp),%edx 0x8048e17 <open+1907>: mov (%edx),%dl 0x8048e19 <open+1909>: mov %dl,0xffffffff(%ebp) 0x8048e1c <open+1912>: mov 0xfffffff4(%ebp),%eax 0x8048e1f <open+1915>: cmp (%eax),%dl 0x8048e21 <open+1917>: je 0x8048eb7 <open+2067> 0x8048e27 <open+1923>: cmpl $0x0,0x804a80c 0x8048e2e <open+1930>: je 0x8048e60 <open+1980> Martin > >Number: 45391 > >Category: i386 > >Synopsis: /usr/bin/cmp coredumps while reading a faulty CD-R ... > >Description: > When using the command /usr/bin/cmp from the default > FreeBSD-4.7 package, it is possible to produce a coredump. > It seems, there is a problem in handling errors while > reading faulty files. It happened to me while I was comparing > two files which I suspected to be dupes on my CD-Rs. This is not the first time this buglet has confused someone, so here's a simple fix. The diff is against -CURRENT, but it can be applied to -STABLE as well. Index: usr.bin/cmp/regular.c =================================================================== RCS file: /home/ncvs/src/usr.bin/cmp/regular.c,v retrieving revision 1.17 diff -u -u -r1.17 regular.c --- usr.bin/cmp/regular.c 2002/07/28 15:13:17 1.17 +++ usr.bin/cmp/regular.c 2003/01/25 01:14:02 @@ -45,7 +45,9 @@ #include <sys/stat.h> #include <err.h> +#include <errno.h> #include <limits.h> +#include <signal.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -54,6 +56,7 @@ #include "extern.h" static u_char *remmap(u_char *, int, off_t); +static void segv_handler(int); #define MMAP_CHUNK (8*1024*1024) #define ROUNDPAGE(i) ((i) & ~pagemask) @@ -67,6 +70,7 @@ int dfound; off_t pagemask, off1, off2; size_t pagesize; + struct sigaction act, oact; if (skip1 > len1) eofmsg(file1); @@ -78,6 +82,12 @@ if (sflag && len1 != len2) exit(DIFF_EXIT); + sigemptyset(&act.sa_mask); + act.sa_flags = SA_NODEFER; + act.sa_handler = segv_handler; + if (sigaction(SIGSEGV, &act, &oact)) + err(ERR_EXIT, "sigaction"); + pagesize = getpagesize(); pagemask = (off_t)pagesize - 1; off1 = ROUNDPAGE(skip1); @@ -138,6 +148,9 @@ munmap(m1, MMAP_CHUNK); munmap(m2, MMAP_CHUNK); + if (sigaction(SIGSEGV, &oact, NULL)) + err(ERR_EXIT, "sigaction"); + if (len1 != len2) eofmsg (len1 > len2 ? file2 : file1); if (dfound) @@ -154,4 +167,10 @@ return (NULL); madvise(mem, MMAP_CHUNK, MADV_SEQUENTIAL); return (mem); +} + +static void +segv_handler(int sig) { + + errc(ERR_EXIT, EIO, "(caught SIGSEGV)"); } Responsible Changed From-To: freebsd-bugs->das Over to me. State Changed From-To: open->closed Fixed in -CURRENT, src/usr.bin/cmp regular.c,v 1.18. Since this is mostly a cosmetic change, I don't intend to MFC it unless someone thinks it's important. |
When using the command /usr/bin/cmp from the default FreeBSD-4.7 package, it is possible to produce a coredump. It seems, there is a problem in handling errors while reading faulty files. It happened to me while I was comparing two files which I suspected to be dupes on my CD-Rs. I guess it will not help much when I post the output from gdb without symbol tables, but let's try at least: ---------------------------------------------------------------------- GNU gdb 4.18 (FreeBSD) Copyright 1998 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you = are welcome to change it and/or distribute copies of it under certain conditi= ons. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for detail= s. This GDB was configured as "i386-unknown-freebsd"... (no debugging symbols found)... Core was generated by `cmp'. Program terminated with signal 11, Segmentation fault. Reading symbols from /usr/lib/libc.so.4...(no debugging symbols found)...= done. Reading symbols from /usr/libexec/ld-elf.so.1...(no debugging symbols=20 found)... done. #0 0x8048e17 in open () (gdb) bt #0 0x8048e17 in open () #1 0xbfbffb0d in ?? () #2 0x8048bc1 in open () #3 0x8048731 in open () (gdb) info frame Stack level 0, frame at 0xbfbff840: eip =3D 0x8048e17 in open; saved eip 0x8048bc1 (FRAMELESS), called by frame at 0xbfbff840 Arglist at 0xbfbff840, args: Locals at 0xbfbff840, Previous frame's sp is 0x0 Saved registers: ebp at 0xbfbff840, eip at 0xbfbff844 (gdb) info sharedlibrary =46rom To Syms Read Shared Object Library 0x28067000 0x280fec78 Yes /usr/lib/libc.so.4 0x2804a000 0x2805e210 Yes /usr/libexec/ld-elf.so.1 ---------------------------------------------------------------------- Fix: There is no fix. How-To-Repeat: 1) You need two copies of files. One on Your hard-disk, the other one on a _almost_ unreadable CD(R). (That might be somehow difficult.) 2) Start the following command: cmp locally_stored_file same_file_on_unreadable_cd