summaryrefslogtreecommitdiff
path: root/extra/openjpeg/openjpeg-1.5.1-CVE-2013-1447.patch
blob: a0e372325fec6a85d4ff5db1d7998814e776b833 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
diff -up openjpeg-1.5.1/libopenjpeg/cio.c.CVE-2013-1447 openjpeg-1.5.1/libopenjpeg/cio.c
--- openjpeg-1.5.1/libopenjpeg/cio.c.CVE-2013-1447	2014-01-07 15:12:20.517748762 -0600
+++ openjpeg-1.5.1/libopenjpeg/cio.c	2014-01-07 15:12:20.533748592 -0600
@@ -107,6 +107,11 @@ int OPJ_CALLCONV cio_tell(opj_cio_t *cio
  * pos : position, in number of bytes, from the beginning of the stream
  */
 void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) {
+	if ((cio->start + pos) > cio->end) {
+		opj_event_msg(cio->cinfo, EVT_ERROR, "error: trying to seek past the end of the codestream (start = %d, change = %d, end = %d\n", cio->start, pos, cio->end);
+		cio->bp = cio->end;
+		return;
+	}
 	cio->bp = cio->start + pos;
 }
 
@@ -114,6 +119,7 @@ void OPJ_CALLCONV cio_seek(opj_cio_t *ci
  * Number of bytes left before the end of the stream.
  */
 int cio_numbytesleft(opj_cio_t *cio) {
+	assert((cio->end - cio->bp) >= 0);
 	return cio->end - cio->bp;
 }
 
@@ -191,6 +197,11 @@ unsigned int cio_read(opj_cio_t *cio, in
  */
 void cio_skip(opj_cio_t *cio, int n) {
 	assert((cio->bp + n) >= cio->bp);
+	if (((cio->bp + n) < cio->start) || ((cio->bp + n) > cio->end)) {
+		opj_event_msg(cio->cinfo, EVT_ERROR, "error: trying to skip bytes past the end of the codestream (current = %d, change = %d, end = %d\n", cio->bp, n, cio->end);
+		cio->bp = cio->end;
+		return;
+	}
 	cio->bp += n;
 }
 
diff -up openjpeg-1.5.1/libopenjpeg/j2k.c.CVE-2013-1447 openjpeg-1.5.1/libopenjpeg/j2k.c
--- openjpeg-1.5.1/libopenjpeg/j2k.c.CVE-2013-1447	2014-01-07 15:12:20.525748677 -0600
+++ openjpeg-1.5.1/libopenjpeg/j2k.c	2014-01-07 15:12:20.534748582 -0600
@@ -476,7 +476,7 @@ static void j2k_read_siz(opj_j2k_t *j2k)
 
 	image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t));
 	for (i = 0; i < image->numcomps; i++) {
-		int tmp, w, h;
+		int tmp/*, w, h*/;
 		tmp = cio_read(cio, 1);		/* Ssiz_i */
 		image->comps[i].prec = (tmp & 0x7f) + 1;
 		image->comps[i].sgnd = tmp >> 7;
@@ -511,6 +511,14 @@ static void j2k_read_siz(opj_j2k_t *j2k)
 			
 		}
 #endif /* USE_JPWL */
+		{
+			if (!(image->comps[i].dx * image->comps[i].dy)) {
+				opj_event_msg(j2k->cinfo, EVT_ERROR,
+					"JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n",
+					i, i, image->comps[i].dx, image->comps[i].dy);
+					return;
+			}
+		}
 
     /* prevent division by zero */
     if (!(image->comps[i].dx * image->comps[i].dy)) {
@@ -519,8 +527,8 @@ static void j2k_read_siz(opj_j2k_t *j2k)
     }
 
 		/* TODO: unused ? */
-		w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx);
-		h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy);
+/*		w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx);
+		h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy);*/
 
 		image->comps[i].resno_decoded = 0;	/* number of resolution decoded */
 		image->comps[i].factor = cp->reduce; /* reducing factor per component */
@@ -2015,6 +2023,11 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k,
 	}
 	if (j2k->state == J2K_STATE_NEOC) {
 		j2k_read_eoc(j2k);
+		/* Check one last time for errors during decoding before returning */
+		if (j2k->state & J2K_STATE_ERR) {
+			opj_image_destroy(image);
+			return NULL;
+		}
 	}
 
 	if (j2k->state != J2K_STATE_MT) {
diff -up openjpeg-1.5.1/libopenjpeg/jp2.c.CVE-2013-1447 openjpeg-1.5.1/libopenjpeg/jp2.c
--- openjpeg-1.5.1/libopenjpeg/jp2.c.CVE-2013-1447	2014-01-07 15:12:20.518748752 -0600
+++ openjpeg-1.5.1/libopenjpeg/jp2.c	2014-01-07 15:12:20.535748571 -0600
@@ -819,6 +819,17 @@ void jp2_write_jp2h(opj_jp2_t *jp2, opj_
 
 	jp2_write_ihdr(jp2, cio);
 
+	{
+		int curpos = cio_tell(cio);
+		cio_seek(cio, box.init_pos);
+		cio_skip(cio, box.length);
+		if ((cio_tell(cio) - box.init_pos) != box.length) {
+			opj_event_msg(jp2->cinfo, EVT_ERROR, "Box size exceeds size of codestream (expected: %d, real: %d)\n", box.length, (cio_tell(cio) - box.init_pos));
+			return OPJ_FALSE;
+		}
+		cio_seek(cio, curpos);
+	}
+
 	if (jp2->bpc == 255) {
 		jp2_write_bpcc(jp2, cio);
 	}
@@ -871,6 +882,13 @@ static opj_bool jp2_read_ftyp(opj_jp2_t
 	jp2->numcl = (box.length - 16) / 4;
 	jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int));
 
+	if (cio_numbytesleft(cio) < ((int)jp2->numcl * 4)) {
+		opj_event_msg(cinfo, EVT_ERROR, "Not enough bytes in FTYP Box "
+				"(expected %d, but only %d left)\n",
+				((int)jp2->numcl * 4), cio_numbytesleft(cio));
+		return OPJ_FALSE;
+	}
+
 	for (i = 0; i < (int)jp2->numcl; i++) {
 		jp2->cl[i] = cio_read(cio, 4);	/* CLi */
 	}
diff -up openjpeg-1.5.1/libopenjpeg/t2.c.CVE-2013-1447 openjpeg-1.5.1/libopenjpeg/t2.c
--- openjpeg-1.5.1/libopenjpeg/t2.c.CVE-2013-1447	2012-09-13 02:58:39.000000000 -0500
+++ openjpeg-1.5.1/libopenjpeg/t2.c	2014-01-07 15:12:20.535748571 -0600
@@ -340,6 +340,11 @@ static int t2_decode_packet(opj_t2_t* t2
 	int precno = pi->precno;	/* precinct value */
 	int layno  = pi->layno;		/* quality layer value */
 
+	if (!&(tile->comps[compno])) {
+		opj_event_msg(t2->cinfo, EVT_ERROR, "Trying to decode tile with no components!\n");
+		return -999;
+	}
+
 	opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno];
 
 	unsigned char *hd = NULL;
diff -up openjpeg-1.5.1/libopenjpeg/tcd.c.CVE-2013-1447 openjpeg-1.5.1/libopenjpeg/tcd.c
--- openjpeg-1.5.1/libopenjpeg/tcd.c.CVE-2013-1447	2014-01-07 15:12:20.526748667 -0600
+++ openjpeg-1.5.1/libopenjpeg/tcd.c	2014-01-07 15:12:20.536748561 -0600
@@ -667,8 +667,8 @@ void tcd_malloc_decode(opj_tcd_t *tcd, o
 			y1 = j == 0 ? tilec->y1 : int_max(y1,	(unsigned int) tilec->y1);
 		}
 
-		w = int_ceildivpow2(x1 - x0, image->comps[i].factor);
-		h = int_ceildivpow2(y1 - y0, image->comps[i].factor);
+		w = int_ceildivpow2((long)(x1) - (long)(x0), image->comps[i].factor);
+		h = int_ceildivpow2((long)(y1) - (long)(y0), image->comps[i].factor);
 
 		image->comps[i].w = w;
 		image->comps[i].h = h;
@@ -1381,7 +1381,15 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd,
 	if (l == -999) {
 		eof = 1;
 		opj_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: incomplete bistream\n");
+		return OPJ_FALSE;
 	}
+
+	/* The code below assumes that numcomps > 0 */
+	if (tile->numcomps <= 0) {
+		opj_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: tile has a zero or negative numcomps\n");
+		return OPJ_TRUE;
+	}
+
 	
 	/*------------------TIER1-----------------*/