SHA256
1
0
forked from pool/mupdf

- Add CVE-2016-10132.patch, CVE-2016-10133.patch and

CVE-2016-10141.patch to fix CVE-2016-10132, CVE-2016-10133 and
  CVE-2016-10141 bsc#1019877

OBS-URL: https://build.opensuse.org/package/show/Publishing/mupdf?expand=0&rev=45
This commit is contained in:
Ismail Dönmez 2017-01-24 12:04:55 +00:00 committed by Git OBS Bridge
parent c2ba1b5927
commit adf0a52264
5 changed files with 324 additions and 1 deletions

178
CVE-2016-10132.patch Normal file
View File

@ -0,0 +1,178 @@
From fd003eceda531e13fbdd1aeb6e9c73156496e569 Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor@ccxvii.net>
Date: Fri, 2 Dec 2016 14:56:20 -0500
Subject: [PATCH 1/1] Fix 697381: check allocation when compiling regular
expressions.
Also use allocator callback function.
---
jsgc.c | 2 +-
jsregexp.c | 2 +-
jsstate.c | 6 ------
regexp.c | 45 +++++++++++++++++++++++++++++++++++----------
regexp.h | 7 +++++++
5 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/jsgc.c b/jsgc.c
index 4f7e7dc..f80111e 100644
--- a/jsgc.c
+++ b/jsgc.c
@@ -46,7 +46,7 @@ static void jsG_freeobject(js_State *J, js_Object *obj)
jsG_freeproperty(J, obj->head);
if (obj->type == JS_CREGEXP) {
js_free(J, obj->u.r.source);
- js_regfree(obj->u.r.prog);
+ js_regfreex(J->alloc, J->actx, obj->u.r.prog);
}
if (obj->type == JS_CITERATOR)
jsG_freeiterator(J, obj->u.iter.head);
diff --git a/jsregexp.c b/jsregexp.c
index a2d5156..7b09c06 100644
--- a/jsregexp.c
+++ b/jsregexp.c
@@ -16,7 +16,7 @@ void js_newregexp(js_State *J, const char *pattern, int flags)
if (flags & JS_REGEXP_I) opts |= REG_ICASE;
if (flags & JS_REGEXP_M) opts |= REG_NEWLINE;
- prog = js_regcomp(pattern, opts, &error);
+ prog = js_regcompx(J->alloc, J->actx, pattern, opts, &error);
if (!prog)
js_syntaxerror(J, "regular expression: %s", error);
diff --git a/jsstate.c b/jsstate.c
index 638cab3..fd5bcf6 100644
--- a/jsstate.c
+++ b/jsstate.c
@@ -9,12 +9,6 @@
static void *js_defaultalloc(void *actx, void *ptr, int size)
{
- if (size == 0) {
- free(ptr);
- return NULL;
- }
- if (!ptr)
- return malloc((size_t)size);
return realloc(ptr, (size_t)size);
}
diff --git a/regexp.c b/regexp.c
index 9852be2..01c18a3 100644
--- a/regexp.c
+++ b/regexp.c
@@ -807,23 +807,31 @@ static void dumpprog(Reprog *prog)
}
#endif
-Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
+Reprog *regcompx(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
+ const char *pattern, int cflags, const char **errorp)
{
struct cstate g;
Renode *node;
Reinst *split, *jump;
int i;
- g.prog = malloc(sizeof (Reprog));
- g.pstart = g.pend = malloc(sizeof (Renode) * strlen(pattern) * 2);
+ g.pstart = NULL;
+ g.prog = NULL;
if (setjmp(g.kaboom)) {
if (errorp) *errorp = g.error;
- free(g.pstart);
- free(g.prog);
+ alloc(ctx, g.pstart, 0);
+ alloc(ctx, g.prog, 0);
return NULL;
}
+ g.prog = alloc(ctx, NULL, sizeof (Reprog));
+ if (!g.prog)
+ die(&g, "cannot allocate regular expression");
+ g.pstart = g.pend = alloc(ctx, NULL, sizeof (Renode) * strlen(pattern) * 2);
+ if (!g.pstart)
+ die(&g, "cannot allocate regular expression parse list");
+
g.source = pattern;
g.ncclass = 0;
g.nsub = 1;
@@ -840,7 +848,9 @@ Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
die(&g, "syntax error");
g.prog->nsub = g.nsub;
- g.prog->start = g.prog->end = malloc((count(node) + 6) * sizeof (Reinst));
+ g.prog->start = g.prog->end = alloc(ctx, NULL, (count(node) + 6) * sizeof (Reinst));
+ if (!g.prog->start)
+ die(&g, "cannot allocate regular expression instruction list");
split = emit(g.prog, I_SPLIT);
split->x = split + 3;
@@ -859,20 +869,35 @@ Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
dumpprog(g.prog);
#endif
- free(g.pstart);
+ alloc(ctx, g.pstart, 0);
if (errorp) *errorp = NULL;
return g.prog;
}
-void regfree(Reprog *prog)
+void regfreex(void *(*alloc)(void *ctx, void *p, int n), void *ctx, Reprog *prog)
{
if (prog) {
- free(prog->start);
- free(prog);
+ alloc(ctx, prog->start, 0);
+ alloc(ctx, prog, 0);
}
}
+static void *default_alloc(void *ctx, void *p, int n)
+{
+ return realloc(p, (size_t)n);
+}
+
+Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
+{
+ return regcompx(default_alloc, NULL, pattern, cflags, errorp);
+}
+
+void regfree(Reprog *prog)
+{
+ regfreex(default_alloc, NULL, prog);
+}
+
/* Match */
static int isnewline(int c)
diff --git a/regexp.h b/regexp.h
index 4bb4615..6bb73e8 100644
--- a/regexp.h
+++ b/regexp.h
@@ -1,6 +1,8 @@
#ifndef regexp_h
#define regexp_h
+#define regcompx js_regcompx
+#define regfreex js_regfreex
#define regcomp js_regcomp
#define regexec js_regexec
#define regfree js_regfree
@@ -8,6 +10,11 @@
typedef struct Reprog Reprog;
typedef struct Resub Resub;
+Reprog *regcompx(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
+ const char *pattern, int cflags, const char **errorp);
+void regfreex(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
+ Reprog *prog);
+
Reprog *regcomp(const char *pattern, int cflags, const char **errorp);
int regexec(Reprog *prog, const char *string, Resub *sub, int eflags);
void regfree(Reprog *prog);
--
2.9.1

26
CVE-2016-10133.patch Normal file
View File

@ -0,0 +1,26 @@
From 77ab465f1c394bb77f00966cd950650f3f53cb24 Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor.andersson@gmail.com>
Date: Thu, 12 Jan 2017 14:47:01 +0100
Subject: [PATCH 1/1] Fix 697401: Error when dropping extra arguments to
lightweight functions.
---
jsrun.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jsrun.c b/jsrun.c
index ee80845..782a6f9 100644
--- a/jsrun.c
+++ b/jsrun.c
@@ -937,7 +937,7 @@ static void jsR_calllwfunction(js_State *J, int n, js_Function *F, js_Environmen
jsR_savescope(J, scope);
if (n > F->numparams) {
- js_pop(J, F->numparams - n);
+ js_pop(J, n - F->numparams);
n = F->numparams;
}
for (i = n; i < F->varlen; ++i)
--
2.9.1

103
CVE-2016-10141.patch Normal file
View File

@ -0,0 +1,103 @@
From fa3d30fd18c348bb4b1f3858fb860f4fcd4b2045 Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor.andersson@gmail.com>
Date: Thu, 12 Jan 2017 15:13:14 +0100
Subject: [PATCH] Fix 697448: Limit the maximum program size to something
reasonable.
A regular expression with lots of nested repetition can lead to
integer overflow when calculating the size of the program.
Check max program size when counting the number of instructions required
for a loop, so we can bail before integer overflow can happen.
---
regexp.c | 38 ++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/regexp.c b/regexp.c
index 01c18a3..4a5948b 100644
--- a/regexp.c
+++ b/regexp.c
@@ -16,6 +16,7 @@
#define REPINF 255
#define MAXTHREAD 1000
#define MAXSUB REG_MAXSUB
+#define MAXPROG (32 << 10)
typedef struct Reclass Reclass;
typedef struct Renode Renode;
@@ -595,23 +596,25 @@ struct Reinst {
Reinst *y;
};
-static int count(Renode *node)
+static int count(struct cstate *g, Renode *node)
{
- int min, max;
+ int min, max, n;
if (!node) return 0;
switch (node->type) {
default: return 1;
- case P_CAT: return count(node->x) + count(node->y);
- case P_ALT: return count(node->x) + count(node->y) + 2;
+ case P_CAT: return count(g, node->x) + count(g, node->y);
+ case P_ALT: return count(g, node->x) + count(g, node->y) + 2;
case P_REP:
min = node->m;
max = node->n;
- if (min == max) return count(node->x) * min;
- if (max < REPINF) return count(node->x) * max + (max - min);
- return count(node->x) * (min + 1) + 2;
- case P_PAR: return count(node->x) + 2;
- case P_PLA: return count(node->x) + 2;
- case P_NLA: return count(node->x) + 2;
+ if (min == max) n = count(g, node->x) * min;
+ else if (max < REPINF) n = count(g, node->x) * max + (max - min);
+ else n = count(g, node->x) * (min + 1) + 2;
+ if (n < 0 || n > MAXPROG) die(g, "program too large");
+ return n;
+ case P_PAR: return count(g, node->x) + 2;
+ case P_PLA: return count(g, node->x) + 2;
+ case P_NLA: return count(g, node->x) + 2;
}
}
@@ -813,7 +816,7 @@ Reprog *regcompx(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
struct cstate g;
Renode *node;
Reinst *split, *jump;
- int i;
+ int i, n;
g.pstart = NULL;
g.prog = NULL;
@@ -847,8 +850,17 @@ Reprog *regcompx(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
if (g.lookahead != 0)
die(&g, "syntax error");
+#ifdef TEST
+ dumpnode(node);
+ putchar('\n');
+#endif
+
+ n = 6 + count(&g, node);
+ if (n < 0 || n > MAXPROG)
+ die(&g, "program too large");
+
g.prog->nsub = g.nsub;
- g.prog->start = g.prog->end = alloc(ctx, NULL, (count(node) + 6) * sizeof (Reinst));
+ g.prog->start = g.prog->end = alloc(ctx, NULL, n * sizeof (Reinst));
if (!g.prog->start)
die(&g, "cannot allocate regular expression instruction list");
@@ -864,8 +876,6 @@ Reprog *regcompx(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
emit(g.prog, I_END);
#ifdef TEST
- dumpnode(node);
- putchar('\n');
dumpprog(g.prog);
#endif
--
2.9.1

View File

@ -1,3 +1,10 @@
-------------------------------------------------------------------
Tue Jan 24 11:57:17 UTC 2017 - idonmez@suse.com
- Add CVE-2016-10132.patch, CVE-2016-10133.patch and
CVE-2016-10141.patch to fix CVE-2016-10132, CVE-2016-10133 and
CVE-2016-10141 bsc#1019877
-------------------------------------------------------------------
Tue Dec 20 12:20:07 UTC 2016 - idonmez@suse.com

View File

@ -1,7 +1,7 @@
#
# spec file for package mupdf
#
# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
# Copyright (c) 2011 Guido Berhoerster.
#
# All modifications and additions to the file contributed by third parties
@ -28,6 +28,9 @@ Source0: http://mupdf.com/downloads/mupdf-%{version}-source.tar.gz
Source1: mupdf.desktop
Source2: mupdf.png
Patch1: fix-openjpeg-flags.patch
Patch2: CVE-2016-10132.patch
Patch3: CVE-2016-10133.patch
Patch4: CVE-2016-10141.patch
BuildRequires: freetype-devel
BuildRequires: gcc-c++
BuildRequires: jbig2dec-devel
@ -65,6 +68,12 @@ based on mupdf.
%setup -q -n %{name}-%{version}-source
%patch1 -p1
pushd ./thirdparty/mujs
%patch2 -p1
%patch3 -p1
%patch4 -p1
popd
# do not use the inlined copies of build dpendencies except for mujs
rm -rf $(ls -d thirdparty/*/ | grep -v mujs)