Bug 66425: Avoid a StackOverflowException found via oss-fuzz

We try to avoid causing StackOverflow, but it was possible
to trigger one here with a specially crafted input-file.

This puts a limit on the number of nested children in place
and logs a warning when the Stream is not fully parsed.

Should fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61256

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1911577 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dominik Stadler 2023-08-09 16:16:49 +00:00
parent ccec6c4bf8
commit 107def2e65
3 changed files with 21 additions and 4 deletions

View File

@ -17,6 +17,8 @@
package org.apache.poi.hdgf.streams;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hdgf.chunks.ChunkFactory;
import org.apache.poi.hdgf.pointers.Pointer;
import org.apache.poi.hdgf.pointers.PointerFactory;
@ -26,11 +28,15 @@ import org.apache.poi.hdgf.pointers.PointerFactory;
* other data too.
*/
public class PointerContainingStream extends Stream { // TODO - instantiable superclass
private Pointer[] childPointers;
private static final Logger LOG = LogManager.getLogger(PointerContainingStream.class);
private static final int MAX_CHILDREN_NESTING = 1000;
private final Pointer[] childPointers;
private Stream[] childStreams;
private ChunkFactory chunkFactory;
private PointerFactory pointerFactory;
private final ChunkFactory chunkFactory;
private final PointerFactory pointerFactory;
protected PointerContainingStream(Pointer pointer, StreamStore store, ChunkFactory chunkFactory, PointerFactory pointerFactory) {
super(pointer, store);
@ -58,6 +64,17 @@ public class PointerContainingStream extends Stream { // TODO - instantiable sup
* those if appropriate.
*/
public void findChildren(byte[] documentData) {
findChildren(documentData, 0);
}
private void findChildren(byte[] documentData, int nesting) {
if (nesting > MAX_CHILDREN_NESTING) {
LOG.warn("Encountered too deep nesting, cannot fully process stream " +
" with more than " + MAX_CHILDREN_NESTING + " nested children." +
" Some data could not be parsed.");
return;
}
// For each pointer, generate the Stream it points to
childStreams = new Stream[childPointers.length];
for(int i=0; i<childPointers.length; i++) {
@ -74,7 +91,7 @@ public class PointerContainingStream extends Stream { // TODO - instantiable sup
if(childStreams[i] instanceof PointerContainingStream) {
PointerContainingStream child =
(PointerContainingStream)childStreams[i];
child.findChildren(documentData);
child.findChildren(documentData, nesting + 1);
}
}
}

Binary file not shown.