Subject: tail(1) seg faults on i/o error, with fix
To: None <netbsd-bugs@NetBSD.org>
From: Dieter <netbsd@sopwith.solgatos.com>
List: netbsd-bugs
Date: 02/16/2005 09:29:04
The tail(1) utility gets a segmentation fault core dump
if it gets an i/o error. This happens on 1.6.2 and 2.0
(and probably other releases as well).
Repeat by: run tail on a file that gives an i/o error.
The problem is using mmap(2) and not insuring that the
data can be read. I fixed it with mlock(2), which
allows a graceful handling of the i/o error without
a core dump.
The diff below (against 2.0) fixes the problem. I make
no claim that this is the best fix, or the most efficient fix.
(It does an mlock() and munlock for each char.)
It probably isn't necessary to exit upon i/o error.
There are probably other programs lurking out there
using mmap unsafely. :-(
===================================================================
RCS file: RCS/forward.c,v
retrieving revision 1.1
diff -c -r1.1 forward.c
*** forward.c 2005/02/10 18:34:56 1.1
--- forward.c 2005/02/16 17:11:40
***************
*** 312,321 ****
--- 312,334 ----
mmap_remaining = mmap_size;
/* Last char is special, ignore whether newline or not. */
for (p = start + mmap_remaining - 1 ; --mmap_remaining ; )
+ {
+ /* The mlock call is to prevent segmentation fault core dump
+ * if it gets an i/o error.
+ */
+ if (mlock(p - 1, 1))
+ {
+ perror("mlock failed, exiting");
+ exit(1);
+ }
+
if (*--p == '\n' && !--off) {
++p;
+ if (munlock(p - 1, 1)) { perror("munlock failed"); }
break;
}
+ if (munlock(p - 1, 1)) { perror("munlock failed"); }
+ }
file_remaining -= mmap_size - mmap_remaining;