Line 0
Link Here
|
|
|
1 |
Description: Fixes a buffer overflow when reading bogus file headers |
2 |
The header parser was not checking if it had read enough data when trying |
3 |
to parse the header from memory, causing it to accept files with headers |
4 |
smaller than expected. |
5 |
. |
6 |
Fixes CVE-2015-2063. |
7 |
Author: Guillem Jover <guillem@debian.org> |
8 |
Origin: vendor |
9 |
Bug-Debian: https://bugs.debian.org/775003 |
10 |
Forwarded: no |
11 |
Last-Update: 2015-02-24 |
12 |
|
13 |
--- |
14 |
unace.c | 25 +++++++++++++++++++++++-- |
15 |
1 file changed, 23 insertions(+), 2 deletions(-) |
16 |
|
17 |
--- unace.c |
18 |
+++ unace.c |
19 |
@@ -113,6 +113,7 @@ INT read_header(INT print_err) |
20 |
{ |
21 |
USHORT rd, |
22 |
head_size, |
23 |
+ need_size, |
24 |
crc_ok; |
25 |
LONG crc; |
26 |
UCHAR *tp=readbuf; |
27 |
@@ -128,6 +129,9 @@ INT read_header(INT print_err) |
28 |
#endif |
29 |
// read size_headrdb bytes into |
30 |
head_size = head.HEAD_SIZE; // header structure |
31 |
+ need_size = 3; |
32 |
+ if (need_size > head.HEAD_SIZE) |
33 |
+ return 0; |
34 |
rd = (head_size > size_headrdb) ? size_headrdb : head_size; |
35 |
if (read(archan, readbuf, rd) < rd) |
36 |
return 0; |
37 |
@@ -147,7 +151,12 @@ INT read_header(INT print_err) |
38 |
head.HEAD_FLAGS=BUFP2WORD(tp); |
39 |
|
40 |
if (head.HEAD_FLAGS & ACE_ADDSIZE) |
41 |
+ { |
42 |
+ need_size += 4; |
43 |
+ if (need_size > head.HEAD_SIZE) |
44 |
+ return 0; |
45 |
skipsize = head.ADDSIZE = BUF2LONG(tp); // get ADDSIZE |
46 |
+ } |
47 |
else |
48 |
skipsize = 0; |
49 |
|
50 |
@@ -158,6 +167,9 @@ INT read_header(INT print_err) |
51 |
switch (head.HEAD_TYPE) // specific buffer to head conversion |
52 |
{ |
53 |
case MAIN_BLK: |
54 |
+ need_size += 24; |
55 |
+ if (need_size > head.HEAD_SIZE) |
56 |
+ return 0; |
57 |
memcpy(mhead.ACESIGN, tp, acesign_len); tp+=acesign_len; |
58 |
mhead.VER_MOD=*tp++; |
59 |
mhead.VER_CR =*tp++; |
60 |
@@ -168,9 +180,15 @@ INT read_header(INT print_err) |
61 |
mhead.RES2 =BUFP2WORD(tp); |
62 |
mhead.RES =BUFP2LONG(tp); |
63 |
mhead.AV_SIZE=*tp++; |
64 |
- memcpy(mhead.AV, tp, rd-(USHORT)(tp-readbuf)); |
65 |
+ if (mhead.AV_SIZE > sizeof(mhead.AV) || |
66 |
+ mhead.AV_SIZE + need_size > head.HEAD_SIZE) |
67 |
+ return 0; |
68 |
+ memcpy(mhead.AV, tp, mhead.AV_SIZE); |
69 |
break; |
70 |
case FILE_BLK: |
71 |
+ need_size += 28; |
72 |
+ if (need_size > head.HEAD_SIZE) |
73 |
+ return 0; |
74 |
fhead.PSIZE =BUFP2LONG(tp); |
75 |
fhead.SIZE =BUFP2LONG(tp); |
76 |
fhead.FTIME =BUFP2LONG(tp); |
77 |
@@ -181,7 +199,10 @@ INT read_header(INT print_err) |
78 |
fhead.TECH.PARM =BUFP2WORD(tp); |
79 |
fhead.RESERVED =BUFP2WORD(tp); |
80 |
fhead.FNAME_SIZE=BUFP2WORD(tp); |
81 |
- memcpy(fhead.FNAME, tp, rd-(USHORT)(tp-readbuf)); |
82 |
+ if (fhead.FNAME_SIZE > sizeof(fhead.FNAME) || |
83 |
+ fhead.FNAME_SIZE + need_size > head.HEAD_SIZE) |
84 |
+ return 0; |
85 |
+ memcpy(fhead.FNAME, tp, fhead.FNAME_SIZE); |
86 |
break; |
87 |
// default: (REC_BLK and future things): |
88 |
// do nothing 'cause isn't needed for extraction |