[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#775208: unblock: libapache-poi-java/3.10.1-2



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package libapache-poi-java, the version 3.10.1-2 fixes CVE-2014-9527.

Thank you.


dpkg-source: warning: extracting unsigned source package (/home/ebourg/packaging/debian-java-svn2git/libapache-poi-java_3.10.1-2.dsc)
diff -Nru libapache-poi-java-3.10.1/debian/changelog libapache-poi-java-3.10.1/debian/changelog
--- libapache-poi-java-3.10.1/debian/changelog  2014-08-28 22:49:30.000000000 +0200
+++ libapache-poi-java-3.10.1/debian/changelog  2015-01-12 15:06:47.000000000 +0100
@@ -1,3 +1,11 @@
+libapache-poi-java (3.10.1-2) unstable; urgency=medium
+
+  * Fixed CVE-2014-9527: Infinite loop on corrupted PPT file (Closes: #775171)
+  * Standards-Version updated to 3.9.6 (no changes)
+  * Moved the package to Git
+
+ -- Emmanuel Bourg <ebourg@apache.org>  Mon, 12 Jan 2015 15:06:33 +0100
+
 libapache-poi-java (3.10.1-1) unstable; urgency=medium

   * New upstream release (Fixes CVE-2014-3529 and CVE-2014-3574)
diff -Nru libapache-poi-java-3.10.1/debian/control libapache-poi-java-3.10.1/debian/control
--- libapache-poi-java-3.10.1/debian/control    2014-02-18 00:56:45.000000000 +0100
+++ libapache-poi-java-3.10.1/debian/control    2015-01-12 13:06:03.000000000 +0100
@@ -19,9 +19,9 @@
                liblog4j1.2-java,
                libxmlbeans-java,
                maven-repo-helper
-Standards-Version: 3.9.5
-Vcs-Svn: svn://anonscm.debian.org/pkg-java/trunk/libapache-poi-java
-Vcs-Browser: http://anonscm.debian.org/viewvc/pkg-java/trunk/libapache-poi-java/
+Standards-Version: 3.9.6
+Vcs-Git: git://anonscm.debian.org/pkg-java/libapache-poi-java.git
+Vcs-Browser: http://anonscm.debian.org/cgit/pkg-java/libapache-poi-java.git
 Homepage: http://poi.apache.org

 Package: libapache-poi-java
diff -Nru libapache-poi-java-3.10.1/debian/patches/07_CVE-2014-9527.patch libapache-poi-java-3.10.1/debian/patches/07_CVE-2014-9527.patch
--- libapache-poi-java-3.10.1/debian/patches/07_CVE-2014-9527.patch     1970-01-01 01:00:00.000000000 +0100
+++ libapache-poi-java-3.10.1/debian/patches/07_CVE-2014-9527.patch     2015-01-12 14:44:20.000000000 +0100
@@ -0,0 +1,145 @@
+Description: Fix an infinite loop on corrupted PPT file (CVE-2014-9527).
+ This patch can be dropped after upgrading to Apache POI 3.11 or later.
+Origin: backport, http://svn.apache.org/r1643680
+Bug: https://issues.apache.org/bugzilla/show_bug.cgi?id=57272
+diff --git a/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
+index 420bd38..e4128c9 100644
+--- a/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
++++ b/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
+@@ -20,16 +20,16 @@ package org.apache.poi.hslf;
+ import java.io.ByteArrayInputStream;
+ import java.io.ByteArrayOutputStream;
+ import java.io.FileInputStream;
+-import java.io.FileNotFoundException;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.OutputStream;
+ import java.util.ArrayList;
+-import java.util.Arrays;
+ import java.util.HashMap;
+ import java.util.Hashtable;
+ import java.util.List;
+ import java.util.Map;
++import java.util.NavigableMap;
++import java.util.TreeMap;
+
+ import org.apache.poi.POIDocument;
+ import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
+@@ -269,41 +269,66 @@ public final class HSLFSlideShow extends POIDocument {
+         _records = read(_docstream, (int)currentUser.getCurrentEditOffset());
+       }
+
+-    private Record[] read(byte[] docstream, int usrOffset){
+-        ArrayList<Integer> lst = new ArrayList<Integer>();
+-        HashMap<Integer,Integer> offset2id = new HashMap<Integer,Integer>();
++      private Record[] read(byte[] docstream, int usrOffset){
++        //sort found records by offset.
++        //(it is not necessary but SlideShow.findMostRecentCoreRecords() expects them sorted)
++          NavigableMap<Integer,Record> records = new TreeMap<Integer,Record>(); // offset -> record
++        Map<Integer,Integer> persistIds = new HashMap<Integer,Integer>(); // offset -> persistId
++        initRecordOffsets(docstream, usrOffset, records, persistIds);
++
++        for (Map.Entry<Integer,Record> entry : records.entrySet()) {
++            Integer offset = entry.getKey();
++            Record record = entry.getValue();
++            Integer persistId = persistIds.get(offset);
++            if (record == null) {
++                // all plain records have been already added,
++                // only new records need to be decrypted (tbd #35897)
++                record = Record.buildRecordAtOffset(docstream, offset);
++                entry.setValue(record);
++            }
++
++            if (record instanceof PersistRecord) {
++                ((PersistRecord)record).setPersistId(persistId);
++            }
++        }
++
++        return records.values().toArray(new Record[records.size()]);
++    }
++
++    private void initRecordOffsets(byte[] docstream, int usrOffset, NavigableMap<Integer,Record> recordMap, Map<Integer,Integer> offset2id) {
+         while (usrOffset != 0){
+             UserEditAtom usr = (UserEditAtom) Record.buildRecordAtOffset(docstream, usrOffset);
+-            lst.add(usrOffset);
++            recordMap.put(usrOffset, usr);
+             int psrOffset = usr.getPersistPointersOffset();
+-
+             PersistPtrHolder ptr = (PersistPtrHolder)Record.buildRecordAtOffset(docstream, psrOffset);
+-            lst.add(psrOffset);
+-            Hashtable<Integer,Integer> entries = ptr.getSlideLocationsLookup();
+-            for(Integer id : entries.keySet()) {
+-                Integer offset = entries.get(id);
+-                lst.add(offset);
++            recordMap.put(psrOffset, ptr);
++
++            for(Map.Entry<Integer,Integer> entry : ptr.getSlideLocationsLookup().entrySet()) {
++                Integer offset = entry.getValue();
++                Integer id = entry.getKey();
++                recordMap.put(offset, null); // reserve a slot for the record
+                 offset2id.put(offset, id);
+             }
+
+             usrOffset = usr.getLastUserEditAtomOffset();
+-        }
+-        //sort found records by offset.
+-        //(it is not necessary but SlideShow.findMostRecentCoreRecords() expects them sorted)
+-        Integer a[] = lst.toArray(new Integer[lst.size()]);
+-        Arrays.sort(a);
+-        Record[] rec = new Record[lst.size()];
+-        for (int i = 0; i < a.length; i++) {
+-            Integer offset = a[i];
+-            rec[i] = Record.buildRecordAtOffset(docstream, offset.intValue());
+-            if(rec[i] instanceof PersistRecord) {
+-                PersistRecord psr = (PersistRecord)rec[i];
+-                Integer id = offset2id.get(offset);
+-                psr.setPersistId(id.intValue());
++
++            // check for corrupted user edit atom and try to repair it
++            // if the next user edit atom offset is already known, we would go into an endless loop
++            if (usrOffset > 0 && recordMap.containsKey(usrOffset)) {
++                // a user edit atom is usually located 36 byte before the smallest known record offset
++                usrOffset = recordMap.firstKey()-36;
++                // check that we really are located on a user edit atom
++                int ver_inst = LittleEndian.getUShort(docstream, usrOffset);
++                int type = LittleEndian.getUShort(docstream, usrOffset+2);
++                int len = LittleEndian.getInt(docstream, usrOffset+4);
++                if (ver_inst == 0 && type == 4085 && (len == 0x1C || len == 0x20)) {
++                    logger.log(POILogger.WARN, "Repairing invalid user edit atom");
++                    usr.setLastUserEditAtomOffset(usrOffset);
++                } else {
++                    throw new CorruptPowerPointFileException("Powerpoint document contains invalid user edit atom");
++                }
+             }
+         }
+-
+-        return rec;
+     }
+
+       /**
+@@ -332,18 +357,14 @@ public final class HSLFSlideShow extends POIDocument {
+       private void readPictures() throws IOException {
+         _pictures = new ArrayList<PictureData>();
+
+-              byte[] pictstream;
++        // if the presentation doesn't contain pictures - will use a null set instead
++        if (!directory.hasEntry("Pictures")) return;
+
+-              try {
+-                      DocumentEntry entry = (DocumentEntry)directory.getEntry("Pictures");
+-                      pictstream = new byte[entry.getSize()];
+-                      DocumentInputStream is = directory.createDocumentInputStream("Pictures");
+-                      is.read(pictstream);
+-              } catch (FileNotFoundException e){
+-                      // Silently catch exceptions if the presentation doesn't
+-                      //  contain pictures - will use a null set instead
+-                      return;
+-              }
++      DocumentEntry entry = (DocumentEntry)directory.getEntry("Pictures");
++      byte[] pictstream = new byte[entry.getSize()];
++      DocumentInputStream is = directory.createDocumentInputStream(entry);
++      is.read(pictstream);
++      is.close();
+
+         int pos = 0;
+               // An empty picture record (length 0) will take up 8 bytes
diff -Nru libapache-poi-java-3.10.1/debian/patches/series libapache-poi-java-3.10.1/debian/patches/series
--- libapache-poi-java-3.10.1/debian/patches/series     2014-07-16 13:51:14.000000000 +0200
+++ libapache-poi-java-3.10.1/debian/patches/series     2015-01-12 14:27:49.000000000 +0100
@@ -2,3 +2,4 @@
 04_jar_names.patch
 05_use-local-ooxml-xsds.patch
 06_java8-compatibility.patch
+07_CVE-2014-9527.patch


unblock libapache-poi-java/3.10.1-2


Reply to: