Thu Mar 26 22:29:47 2020 UTC ()
archivers/unzoo: fix out-of-bounds read when matching non-ASCII
Found by GCC's -Wchar-subscripts.
(rillig)
diff -r1.14 -r1.15 pkgsrc/archivers/unzoo/Makefile
diff -r1.3 -r1.4 pkgsrc/archivers/unzoo/distinfo
diff -r0 -r1.1 pkgsrc/archivers/unzoo/patches/patch-unzoo.c
--- pkgsrc/archivers/unzoo/Makefile 2014/10/09 14:05:54 1.14
+++ pkgsrc/archivers/unzoo/Makefile 2020/03/26 22:29:47 1.15
| @@ -1,18 +1,19 @@ | | | @@ -1,18 +1,19 @@ |
1 | # $NetBSD: Makefile,v 1.14 2014/10/09 14:05:54 wiz Exp $ | | 1 | # $NetBSD: Makefile,v 1.15 2020/03/26 22:29:47 rillig Exp $ |
2 | # | | 2 | # |
3 | | | 3 | |
4 | DISTNAME= unzoo.c | | 4 | DISTNAME= unzoo.c |
5 | PKGNAME= unzoo-4.4 | | 5 | PKGNAME= unzoo-4.4 |
| | | 6 | PKGREVISION= 1 |
6 | CATEGORIES= archivers | | 7 | CATEGORIES= archivers |
7 | MASTER_SITES= # no dist site available | | 8 | MASTER_SITES= # no dist site available |
8 | EXTRACT_SUFX= # empty | | 9 | EXTRACT_SUFX= # empty |
9 | | | 10 | |
10 | MAINTAINER= pkgsrc-users@NetBSD.org | | 11 | MAINTAINER= pkgsrc-users@NetBSD.org |
11 | COMMENT= Extract zoo archives | | 12 | COMMENT= Extract zoo archives |
12 | | | 13 | |
13 | WRKSRC= ${WRKDIR} | | 14 | WRKSRC= ${WRKDIR} |
14 | NO_CONFIGURE= YES | | 15 | NO_CONFIGURE= YES |
15 | | | 16 | |
16 | INSTALLATION_DIRS= bin | | 17 | INSTALLATION_DIRS= bin |
17 | | | 18 | |
18 | do-extract: | | 19 | do-extract: |
--- pkgsrc/archivers/unzoo/distinfo 2015/11/03 00:56:26 1.3
+++ pkgsrc/archivers/unzoo/distinfo 2020/03/26 22:29:47 1.4
| @@ -1,6 +1,7 @@ | | | @@ -1,6 +1,7 @@ |
1 | $NetBSD: distinfo,v 1.3 2015/11/03 00:56:26 agc Exp $ | | 1 | $NetBSD: distinfo,v 1.4 2020/03/26 22:29:47 rillig Exp $ |
2 | | | 2 | |
3 | SHA1 (unzoo.c) = 99a6e9922ccdf5d454c78d3a514d5e33ae17562d | | 3 | SHA1 (unzoo.c) = 99a6e9922ccdf5d454c78d3a514d5e33ae17562d |
4 | RMD160 (unzoo.c) = f7cf751dc865e73d3c51e4476dd2472e409b20ff | | 4 | RMD160 (unzoo.c) = f7cf751dc865e73d3c51e4476dd2472e409b20ff |
5 | SHA512 (unzoo.c) = d293e244e44af131702550ddefdd035e32de3e7228f6c1c805139d448ba96357931405d313405572c30fc7c8d2ff005cc0ffc4d0ad209f47ee9ec1217ccaed21 | | 5 | SHA512 (unzoo.c) = d293e244e44af131702550ddefdd035e32de3e7228f6c1c805139d448ba96357931405d313405572c30fc7c8d2ff005cc0ffc4d0ad209f47ee9ec1217ccaed21 |
6 | Size (unzoo.c) = 115328 bytes | | 6 | Size (unzoo.c) = 115328 bytes |
| | | 7 | SHA1 (patch-unzoo.c) = 5b652586c919a8a5a5498c00ae2330620af39ea4 |
$NetBSD: patch-unzoo.c,v 1.1 2020/03/26 22:29:47 rillig Exp $
unzoo.c: In function 'IsMatchName':
unzoo.c:1268:40: error: array subscript has type 'char' [-Werror=char-subscripts]
else if ( *pat=='?' && ! IsSpec[*str] ) { pat++; str++; }
^
unzoo.c:1271:40: error: array subscript has type 'char' [-Werror=char-subscripts]
else if ( tmp != 0 && ! IsSpec[*tmp] ) { pat = pos; str = ++tmp; }
^
This looks indeed like undefined behavior since the function IsMatchName
accepts arbitrary filenames, and filenames containing non-ASCII
characters would access the array outside of its bounds.
On NetBSD-8.0-x86_64 using GCC 5.5.0 the memory below IsSpec is BufArch,
which means that pattern matching depended on the contents of the archive
before.
--- unzoo.c.orig 2020-03-26 22:01:16.074248902 +0000
+++ unzoo.c
@@ -244,6 +244,7 @@
*H
*/
#include <stdio.h>
+#include <string.h>
/****************************************************************************
@@ -1265,10 +1266,10 @@ int IsMatchName ( pat, str )
/* try to match the name part */
while ( *pat != '\0' || *str != '\0' ) {
if ( *pat==*str ) { pat++; str++; }
- else if ( *pat=='?' && ! IsSpec[*str] ) { pat++; str++; }
+ else if ( *pat=='?' && ! IsSpec[(unsigned char) *str] ) { pat++; str++; }
else if ( *pat=='?' && *str != '\0' ) { pat++; str++; }
else if ( *pat=='*' ) { pos = ++pat; tmp = str; }
- else if ( tmp != 0 && ! IsSpec[*tmp] ) { pat = pos; str = ++tmp; }
+ else if ( tmp != 0 && ! IsSpec[(unsigned char) *tmp] ) { pat = pos; str = ++tmp; }
else break;
}
return *pat == '\0' && *str == '\0';