[libapache-poi-java] 03/04: Fixed CVE-2014-9527: Infinite loop on corrupted PPT file (Closes: #775171)
Emmanuel Bourg
ebourg-guest at moszumanska.debian.org
Mon Jan 12 14:13:08 UTC 2015
This is an automated email from the git hooks/post-receive script.
ebourg-guest pushed a commit to branch master
in repository libapache-poi-java.
commit 7385dcada6d99c3376f3ca9c45e94719f8bf766d
Author: Emmanuel Bourg <ebourg at apache.org>
Date: Mon Jan 12 14:45:36 2015 +0100
Fixed CVE-2014-9527: Infinite loop on corrupted PPT file (Closes: #775171)
---
debian/changelog | 1 +
debian/patches/07_CVE-2014-9527.patch | 145 ++++++++++++++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 147 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index fc368f3..3ec3bde 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,6 @@
libapache-poi-java (3.10.1-2) UNRELEASED; 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
diff --git a/debian/patches/07_CVE-2014-9527.patch b/debian/patches/07_CVE-2014-9527.patch
new file mode 100644
index 0000000..b338fd9
--- /dev/null
+++ b/debian/patches/07_CVE-2014-9527.patch
@@ -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 --git a/debian/patches/series b/debian/patches/series
index 9964913..2b51bda 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,3 +2,4 @@
04_jar_names.patch
05_use-local-ooxml-xsds.patch
06_java8-compatibility.patch
+07_CVE-2014-9527.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libapache-poi-java.git
More information about the pkg-java-commits
mailing list