Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37737622
en ru br
ALT Linux repos
S:1.2b-alt5
5.0: 1.2b-alt2
4.1: 1.2b-alt2
4.0: 1.2b-alt2
3.0: 1.2b-alt2

Group :: Archiving/Compression
RPM: unace

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: 006_security-afl.patch
Download


Description: Fixes a buffer overflow when reading bogus file headers
 The header parser was not checking if it had read enough data when trying
 to parse the header from memory, causing it to accept files with headers
 smaller than expected.
 .
 Fixes CVE-2015-2063.
Author: Guillem Jover <guillem@debian.org>
Origin: vendor
Bug-Debian: https://bugs.debian.org/775003
Forwarded: no
Last-Update: 2015-02-24
---
 unace.c |   25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)
--- a/unace.c
+++ b/unace.c
@@ -113,6 +113,7 @@ INT  read_header(INT print_err)
 {
    USHORT rd,
         head_size,
+        need_size,
         crc_ok;
    LONG crc;
    UCHAR *tp=readbuf;
@@ -128,6 +129,9 @@ INT  read_header(INT print_err)
 #endif
                                         // read size_headrdb bytes into 
    head_size = head.HEAD_SIZE;          // header structure 
+   need_size = 3;
+   if (need_size > head.HEAD_SIZE)
+      return 0;
    rd = (head_size > size_headrdb) ? size_headrdb : head_size;
    if (read(archan, readbuf, rd) < rd)
       return 0;
@@ -147,7 +151,12 @@ INT  read_header(INT print_err)
    head.HEAD_FLAGS=BUFP2WORD(tp);
 
    if (head.HEAD_FLAGS & ACE_ADDSIZE)
+   {
+      need_size += 4;
+      if (need_size > head.HEAD_SIZE)
+         return 0;
       skipsize = head.ADDSIZE = BUF2LONG(tp);   // get ADDSIZE
+   }
    else
       skipsize = 0;
 
@@ -158,6 +167,9 @@ INT  read_header(INT print_err)
    switch (head.HEAD_TYPE)              // specific buffer to head conversion
    {
       case MAIN_BLK:
+         need_size += 24;
+         if (need_size > head.HEAD_SIZE)
+            return 0;
          memcpy(mhead.ACESIGN, tp, acesign_len); tp+=acesign_len;
          mhead.VER_MOD=*tp++;
          mhead.VER_CR =*tp++;
@@ -168,9 +180,15 @@ INT  read_header(INT print_err)
          mhead.RES2   =BUFP2WORD(tp);
          mhead.RES    =BUFP2LONG(tp);
          mhead.AV_SIZE=*tp++;
-         memcpy(mhead.AV, tp, rd-(USHORT)(tp-readbuf));
+         if (mhead.AV_SIZE > sizeof(mhead.AV) ||
+             mhead.AV_SIZE + need_size > head.HEAD_SIZE)
+            return 0;
+         memcpy(mhead.AV, tp, mhead.AV_SIZE);
          break;
       case FILE_BLK:
+         need_size += 28;
+         if (need_size > head.HEAD_SIZE)
+            return 0;
          fhead.PSIZE     =BUFP2LONG(tp);
          fhead.SIZE      =BUFP2LONG(tp);
          fhead.FTIME     =BUFP2LONG(tp);
@@ -181,7 +199,10 @@ INT  read_header(INT print_err)
          fhead.TECH.PARM =BUFP2WORD(tp);
          fhead.RESERVED  =BUFP2WORD(tp);
          fhead.FNAME_SIZE=BUFP2WORD(tp);
-         memcpy(fhead.FNAME, tp, rd-(USHORT)(tp-readbuf));
+         if (fhead.FNAME_SIZE > sizeof(fhead.FNAME) ||
+             fhead.FNAME_SIZE + need_size > head.HEAD_SIZE)
+            return 0;
+         memcpy(fhead.FNAME, tp, fhead.FNAME_SIZE);
          break;
 //    default: (REC_BLK and future things): 
 //              do nothing 'cause isn't needed for extraction
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin