Projects
Eulaceura:Mainline
unzip
_service:obs_scm:CVE-2019-13232-fur2.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:CVE-2019-13232-fur2.patch of Package unzip
From b701988480151e6693343ecdb246092824604c61 Mon Sep 17 00:00:00 2001 From: wangshouping <wangshouping@huawei.com> Date: Tue, 11 Feb 2020 19:07:28 -0500 Subject: [PATCH] add param to limit the number of overlap files Signed-off-by: wangshouping <wangshouping@huawei.com> --- extract.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++-------------- man/unzip.1 | 8 +++-- unzip.c | 84 +++++++++++++++++++++++++++++++++++++++----- unzip.h | 1 + unzip.txt | 6 +++- 5 files changed, 176 insertions(+), 37 deletions(-) diff --git a/extract.c b/extract.c index 3a01d13..031efdb 100644 --- a/extract.c +++ b/extract.c @@ -340,23 +340,32 @@ typedef struct { span_t *span; /* allocated, distinct, and sorted list of spans */ size_t num; /* number of spans in the list */ size_t max; /* allocated number of spans (num <= max) */ + unsigned long count; } cover_t; /* * Return the index of the first span in cover whose beg is greater than val. * If there is no such span, then cover->num is returned. */ -static size_t cover_find(cover, val) +static size_t cover_find(cover, val, op) cover_t *cover; bound_t val; + int op; { size_t lo = 0, hi = cover->num; + bound_t tmp_val; while (lo < hi) { size_t mid = (lo + hi) >> 1; - if (val < cover->span[mid].beg) - hi = mid; - else - lo = mid + 1; + if (!op) { + tmp_val = cover->span[mid].beg; + } else { + tmp_val = cover->span[mid].end; + } + if (val < tmp_val) { + hi = mid; + } else { + lo = mid + 1; + } } return hi; } @@ -366,10 +375,16 @@ static int cover_within(cover, val) cover_t *cover; bound_t val; { - size_t pos = cover_find(cover, val); + size_t pos = cover_find(cover, val, 0); return pos > 0 && val < cover->span[pos - 1].end; } +static int is_exceed_max_overlaps(cover, val) + cover_t *cover; +{ + return cover->count >= G.UzO.max_overlaps; +} + /* * Add a new span to the list, but only if the new span does not overlap any * spans already in the list. The new span covers the values beg..end-1. beg @@ -387,7 +402,8 @@ static int cover_add(cover, beg, end) bound_t beg; bound_t end; { - size_t pos; + size_t pos_beg; + size_t pos_end; int prec, foll; if (beg >= end) @@ -396,31 +412,76 @@ static int cover_add(cover, beg, end) /* Find where the new span should go, and make sure that it does not overlap with any existing spans. */ - pos = cover_find(cover, beg); - if ((pos > 0 && beg < cover->span[pos - 1].end) || - (pos < cover->num && end > cover->span[pos].beg)) - return 1; + pos_beg = cover_find(cover, beg, 0); + pos_end = cover_find(cover, end, 1); /* Check for adjacencies. */ - prec = pos > 0 && beg == cover->span[pos - 1].end; - foll = pos < cover->num && end == cover->span[pos].beg; + prec = pos_beg > 0 && beg <= cover->span[pos_beg - 1].end; + foll = pos_beg < cover->num && end >= cover->span[pos_beg].beg; if (prec && foll) { + if (beg < cover->span[pos_beg - 1].end || end > cover->span[pos_beg].beg) { + cover->count++; + } + /* The new span connects the preceding and following spans. Merge the following span into the preceding span, and delete the following span. */ - cover->span[pos - 1].end = cover->span[pos].end; - cover->num--; - memmove(cover->span + pos, cover->span + pos + 1, - (cover->num - pos) * sizeof(span_t)); + if (end <= cover->span[pos_beg].end) { + cover->span[pos_beg - 1].end = cover->span[pos_beg].end; + cover->num--; + memmove(cover->span + pos_beg, cover->span + pos_beg + 1, + (cover->num - pos_beg) * sizeof(span_t)); + } else { + if (pos_end == cover->num) { + cover->span[pos_beg - 1].end = end; + cover->num = cover->num - (pos_end - pos_beg); + } else if (end >= cover->span[pos_end].beg) { + cover->span[pos_beg - 1].end = cover->span[pos_end].end; + memmove(cover->span + pos_beg, cover->span + pos_end + 1, + (cover->num - 1 - pos_end) * sizeof(span_t)); + cover->num = cover->num - (pos_end - pos_beg) - 1; + } else { + cover->span[pos_beg - 1].end = end; + memmove(cover->span + pos_beg, cover->span + pos_end, + (cover->num - 1 - pos_end + 1) * sizeof(span_t)); + cover->num = cover->num - (pos_end - pos_beg); + } + } } - else if (prec) + else if (prec) { /* The new span is adjacent only to the preceding span. Extend the end of the preceding span. */ - cover->span[pos - 1].end = end; - else if (foll) + if (beg < cover->span[pos_beg - 1].end) { + cover->count++; + } + if (end > cover->span[pos_beg - 1].end) { + cover->span[pos_beg - 1].end = end; + } + } + else if (foll) { + if (end > cover->span[pos_beg].beg) { + cover->count++; + } /* The new span is adjacent only to the following span. Extend the beginning of the following span. */ - cover->span[pos].beg = beg; + cover->span[pos_beg].beg = beg; + if (end > cover->span[pos_beg].end) { + if (pos_end == cover->num) { + cover->span[pos_beg].end = end; + cover->num = cover->num - (pos_end - pos_beg) + 1; + } else if (end >= cover->span[pos_end].beg) { + cover->span[pos_beg].end = cover->span[pos_end].end; + memmove(cover->span + pos_beg + 1, cover->span + pos_end + 1, + (cover->num - 1 - pos_end) * sizeof(span_t)); + cover->num = cover->num - (pos_end - pos_beg); + } else { + cover->span[pos_beg].end = end; + memmove(cover->span + pos_beg + 1, cover->span + pos_end, + (cover->num - 1 - pos_end + 1) * sizeof(span_t)); + cover->num = cover->num - (pos_end - pos_beg) + 1; + } + } + } else { /* The new span has gaps between both the preceding and the following spans. Assure that there is room and insert the span. */ @@ -432,11 +493,11 @@ static int cover_add(cover, beg, end) cover->span = span; cover->max = max; } - memmove(cover->span + pos + 1, cover->span + pos, - (cover->num - pos) * sizeof(span_t)); + memmove(cover->span + pos_beg + 1, cover->span + pos_beg, + (cover->num - pos_beg) * sizeof(span_t)); cover->num++; - cover->span[pos].beg = beg; - cover->span[pos].end = end; + cover->span[pos_beg].beg = beg; + cover->span[pos_beg].end = end; } return 0; } @@ -511,6 +572,7 @@ int extract_or_test_files(__G) /* return PK-type error code */ ((cover_t *)G.cover)->max = 0; } ((cover_t *)G.cover)->num = 0; + ((cover_t *)G.cover)->count = 0; if (cover_add((cover_t *)G.cover, G.extra_bytes + G.ecrec.offset_start_central_directory, G.extra_bytes + G.ecrec.offset_start_central_directory + @@ -1218,7 +1280,7 @@ static int extract_or_test_entrylist(__G__ numchunk, /* seek_zipf(__G__ pInfo->offset); */ request = G.pInfo->offset + G.extra_bytes; - if (cover_within((cover_t *)G.cover, request)) { + if (is_exceed_max_overlaps((cover_t *)G.cover)) { Info(slide, 0x401, ((char *)slide, LoadFarString(OverlappedComponents))); return PK_BOMB; diff --git a/man/unzip.1 b/man/unzip.1 index 21816d1..a637a14 100644 --- a/man/unzip.1 +++ b/man/unzip.1 @@ -25,7 +25,7 @@ unzip \- list, test and extract compressed files in a ZIP archive .PD .SH SYNOPSIS -\fBunzip\fP [\fB\-Z\fP] [\fB\-cflptTuvz\fP[\fBabjnoqsCDKLMUVWX$/:^\fP]] +\fBunzip\fP [\fB\-Z\fP] [\fB\-cflptTuvz\fP[\fBabjnoqsCDKLMUVWX$/:^\fP][\fB\-g num\fP]] \fIfile\fP[\fI.zip\fP] [\fIfile(s)\fP\ .\|.\|.] [\fB\-x\fP\ \fIxfile(s)\fP\ .\|.\|.] [\fB\-d\fP\ \fIexdir\fP] .PD @@ -195,6 +195,10 @@ but will be in future releases. .TP .B \-z display only the archive comment. +.IP \fB\-g\fP\ \fInum\fP +limit the number of overlap files. When the number of +overlap files exceeds the num we set, it is a bomb. the num +is a decimal number. .PD .\" ========================================================================= .SH MODIFIERS diff --git a/unzip.c b/unzip.c index 5b7d288..8c4c37e 100644 --- a/unzip.c +++ b/unzip.c @@ -601,7 +601,7 @@ Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip/ ;\ \n file[.zip] may be a wildcard. %s\n"; #else /* !VM_CMS */ static ZCONST char Far UnzipUsageLine2[] = "\ -Usage: unzip %s[-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]\n \ +Usage: unzip %s[-opts[modifiers][-g num]] file[.zip] [list] [-x xlist] [-d exdir]\n \ Default action is to extract files in list, except those in xlist, to exdir;\n\ file[.zip] may be a wildcard. %s\n"; #endif /* ?VM_CMS */ @@ -647,7 +648,8 @@ static ZCONST char Far UnzipUsageLine3[] = "\n\ -f freshen existing files, create none -t test compressed archive data\n\ -u update files, create if necessary -z display archive comment only\n\ -v list verbosely/show version info %s\n\ - -x exclude files that follow (in xlist) -d extract files into exdir\n"; + -x exclude files that follow (in xlist) -d extract files into exdir\n\ + -g limit the number of overlap files\n"; #endif /* ?VM_CMS */ #endif /* ?MACOS */ @@ -1367,7 +1414,7 @@ int uz_opts(__G__ pargc, pargv) extern char OEM_CP[MAX_CP_NAME]; extern char ISO_CP[MAX_CP_NAME]; #endif - + uO.max_overlaps = (unsigned long)(-1); /* if not set, uncheck overlaps */ while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) { s = *argv + 1; while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */ @@ -1528,6 +1575,26 @@ int uz_opts(__G__ pargc, pargv) uO.acorn_nfs_ext = TRUE; break; #endif /* RISCOS || ACORN_FTYPE_NFS */ +#ifdef UNIX + case('g'): /* set overlap entries */ + if (negative) { // invalid param, eg: --g + Info(slide, 0x401, ((char *)slide, + "error: invalid param, eg: unzip --g")); + return(PK_PARAM); + } else { + if (argc > 1) { + char *leftover; + --argc; + ++argv; + uO.max_overlaps = strtoul(*argv, &leftover, 10); + } else { /* else pwdarg points at decryption password */ + Info(slide, 0x401, ((char *)slide, + "error: invalid param, -g need add decimal number")); + return(PK_PARAM); + } + } + break; +#endif case ('h'): /* just print help message and quit */ if (showhelp == 0) { #ifndef SFX @@ -2235,6 +2302,7 @@ static void help_extended(__G) " information. Also can be added to other list commands for more", " verbose output.", " -z Display only archive comment.", + " -g Limit the number of overlap files.", "", "unzip modifiers:", " -a Convert text files to local OS format. Convert line ends, EOF", diff --git a/unzip.h b/unzip.h index ed24a5b..a7e8a64 100644 --- a/unzip.h +++ b/unzip.h @@ -560,6 +560,7 @@ typedef struct _UzpOpts { int cflxflag; /* -^: allow control chars in extracted filenames */ #endif #endif /* !FUNZIP */ + unsigned long max_overlaps; /* Maximum number of overlaps allowed */ } UzpOpts; /* intended to be a private struct: */ diff --git a/unzip.txt b/unzip.txt index e8e9719..6594ee6 100644 --- a/unzip.txt +++ b/unzip.txt @@ -4,7 +4,7 @@ NAME unzip - list, test and extract compressed files in a ZIP archive SYNOPSIS - unzip [-Z] [-cflptTuvz[abjnoqsCDKLMUVWX$/:^]] file[.zip] [file(s) ...] + unzip [-Z] [-cflptTuvz[abjnoqsCDKLMUVWX$/:^][-g num]] file[.zip] [file(s) ...] [-x xfile(s) ...] [-d exdir] DESCRIPTION @@ -177,6 +177,10 @@ OPTIONS implemented but will be in future releases. -z display only the archive comment. + -g num + limit the number of overlap files. When the number of overlap f- + iles exceeds the num we set, it is a bomb. the num is a decimal + number. MODIFIERS -a convert text files. Ordinarily all files are extracted exactly -- 1.8.3.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2