Module Name: src
Committed By: christos
Date: Wed Apr 15 02:29:13 UTC 2015
Modified Files:
src/usr.bin/gzip: gzip.c
Log Message:
Coverity CID 1264915, Via FreeBSD (Xin Li)
When reading in the original file name from gzip header, we read
in PATH_MAX + 1 bytes from the file. In r281500, strrchr() is
used to strip possible path portion of the file name to mitigate
a possible attack. Unfortunately, strrchr() expects a buffer
that is NUL-terminated, and since we are processing potentially
untrusted data, we can not assert that be always true.
Solve this by reading in one less byte (now PATH_MAX) and
explicitly terminate the buffer after the read size with NUL.
To generate a diff of this commit:
cvs rdiff -u -r1.107 -r1.108 src/usr.bin/gzip/gzip.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/gzip/gzip.c
diff -u src/usr.bin/gzip/gzip.c:1.107 src/usr.bin/gzip/gzip.c:1.108
--- src/usr.bin/gzip/gzip.c:1.107 Mon Jan 12 21:37:20 2015
+++ src/usr.bin/gzip/gzip.c Tue Apr 14 22:29:12 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: gzip.c,v 1.107 2015/01/13 02:37:20 mrg Exp $ */
+/* $NetBSD: gzip.c,v 1.108 2015/04/15 02:29:12 christos Exp $ */
/*
* Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green
@@ -30,7 +30,7 @@
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004, 2006\
Matthew R. Green. All rights reserved.");
-__RCSID("$NetBSD: gzip.c,v 1.107 2015/01/13 02:37:20 mrg Exp $");
+__RCSID("$NetBSD: gzip.c,v 1.108 2015/04/15 02:29:12 christos Exp $");
#endif /* not lint */
/*
@@ -1366,14 +1366,17 @@ file_uncompress(char *file, char *outfil
timestamp = ts[3] << 24 | ts[2] << 16 | ts[1] << 8 | ts[0];
if (header1[3] & ORIG_NAME) {
- rbytes = pread(fd, name, sizeof name, GZIP_ORIGNAME);
+ rbytes = pread(fd, name, sizeof(name) - 1, GZIP_ORIGNAME);
if (rbytes < 0) {
maybe_warn("can't read %s", file);
goto lose;
}
- if (name[0] != 0) {
+ if (name[0] != '\0') {
char *dp, *nf;
+ /* Make sure that name is NUL-terminated */
+ name[rbytes] = '\0';
+
/* strip saved directory name */
nf = strrchr(name, '/');
if (nf == NULL)