[ 
https://issues.apache.org/jira/browse/TIKA-4830?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18108335#comment-18108335
 ] 

Hudson commented on TIKA-4830:
------------------------------

SUCCESS: Integrated in Jenkins build Tika » tika-main-jdk17 #1578 (See 
[https://ci-builds.apache.org/job/Tika/job/tika-main-jdk17/1578/])
[TIKA-4830]: Handle additional exceptions in JackcessParser, as suggested by 
Tim Scheckenbach (#3072) (github: 
[https://github.com/apache/tika/commit/cf893e8e3c2ef378a1d03bb73c47bafef5a564f3])
* (edit) 
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/JackcessParser.java


> JackcessParser.parse leaks Jackcess RuntimeExceptions 
> (IndexOutOfBoundsException / IllegalStateException) on malformed MDBs while 
> reading the global usage map
> --------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: TIKA-4830
>                 URL: https://issues.apache.org/jira/browse/TIKA-4830
>             Project: Tika
>          Issue Type: Bug
>          Components: parser
>    Affects Versions: 4.0.0, 3.3.2
>            Reporter: Tim Scheckenbach
>            Priority: Major
>             Fix For: 3.3.3, 4.1.0
>
>         Attachments: inputs.zip
>
>
> {{JackcessParser.parse}} is declared {{{}throws IOException, SAXException, 
> TikaException{}}}. Two fuzz inputs for the same open path —
> {{DatabaseBuilder.open}} → {{PageChannel.initialize}} → {{UsageMap.read}} 
> (global usage map, page 1, row 0)
> — make Jackcess throw a {{RuntimeException}} that Tika does not wrap. The 
> OSS-Fuzz target {{JackcessParserFuzzer}} swallows only 
> {{{}IllegalArgumentException | TikaException | SAXException | 
> IOException{}}}, so both are fuzzer crashes. {{AutoDetectParser}} / 
> {{CompositeParser}} would wrap them as {{{}TikaException: Unexpected 
> RuntimeException from JackcessParser{}}}; callers of {{JackcessParser}} 
> directly do not.
> Calling
> {code:java}
> new JackcessParser().parse(TikaInputStream.get(new 
> File("crash-083680cb14186e1be3e26b93946ea43c538d2e62")),
>         new ToTextContentHandler(), new Metadata(), new ParseContext());
> {code}
> on the first attached file (32768-byte Jet 4 MDB) results in:
> {code:java}
> java.lang.IndexOutOfBoundsException
>     at java.base/java.nio.Buffer.checkIndex(Buffer.java:743)
>     at java.base/java.nio.HeapByteBuffer.get(HeapByteBuffer.java:169)
>     at com.healthmarketscience.jackcess.impl.UsageMap.read(UsageMap.java:133)
>     at 
> com.healthmarketscience.jackcess.impl.PageChannel.initialize(PageChannel.java:117)
>     at 
> com.healthmarketscience.jackcess.impl.DatabaseImpl.<init>(DatabaseImpl.java:598)
>     at 
> com.healthmarketscience.jackcess.impl.DatabaseImpl.open(DatabaseImpl.java:458)
>     at 
> com.healthmarketscience.jackcess.DatabaseBuilder.open(DatabaseBuilder.java:278)
>     at 
> org.apache.tika.parser.microsoft.JackcessParser.parse(JackcessParser.java:101)
> {code}
> {{UsageMap.read}} is declared {{throws IOException}} but does:
> {code:java}
> short rowStart = TableImpl.findRowStart(tableBuffer, rowNum, format);
> int rowEnd = TableImpl.findRowEnd(tableBuffer, rowNum, format);
> tableBuffer.limit(rowEnd);
> byte mapType = tableBuffer.get(rowStart); // IndexOutOfBoundsException
> {code}
> Tika does not catch {{IndexOutOfBoundsException}} at all.
> Calling the same parse on the second attached file, 
> {{crash-107db845b1fe3fee58a3b1da3a4646e604af329b}} (24576-byte Jet 4 MDB), 
> results in:
> {code:java}
> java.lang.IllegalStateException: invalid page number 169285950
>     at 
> com.healthmarketscience.jackcess.impl.PageChannel.validatePageNumber(PageChannel.java:203)
>     at 
> com.healthmarketscience.jackcess.impl.PageChannel.readPage(PageChannel.java:219)
>     at 
> com.healthmarketscience.jackcess.impl.TempPageHolder.setPage(TempPageHolder.java:86)
>     at 
> com.healthmarketscience.jackcess.impl.UsageMap$ReferenceHandler.<init>(UsageMap.java:724)
>     at 
> com.healthmarketscience.jackcess.impl.UsageMap.initHandler(UsageMap.java:146)
>     at com.healthmarketscience.jackcess.impl.UsageMap.read(UsageMap.java:135)
>     at 
> com.healthmarketscience.jackcess.impl.PageChannel.initialize(PageChannel.java:117)
>     at 
> com.healthmarketscience.jackcess.impl.DatabaseImpl.open(DatabaseImpl.java:458)
>     at 
> com.healthmarketscience.jackcess.DatabaseBuilder.open(DatabaseBuilder.java:278)
>     at 
> org.apache.tika.parser.microsoft.JackcessParser.parse(JackcessParser.java:101)
> {code}
> Here the global usage map is a _reference_ map ({{{}MAP_TYPE_REFERENCE{}}}). 
> Its constructor walks page pointers and {{validatePageNumber}} is declared 
> {{throws IOException}} but does:
> {code:java}
> if ((pageNumber <= INVALID_PAGE_NUMBER) || (pageNumber >= nextPageNumber)) {
>     throw new IllegalStateException("invalid page number " + pageNumber);
> }
> {code}
> Page 169285950 is far past the end of a 6-page file. Tika already catches 
> {{{}IllegalStateException{}}}, but only to map "Incorrect password"; every 
> other one is rethrown:
> {code:java}
> } catch (IllegalStateException e) {
>     if (e.getMessage() != null && e.getMessage().contains("Incorrect 
> password")) {
>         throw new EncryptedDocumentException(e);
>     }
>     throw e;
> }
> {code}
> Suggested Tika-side fix: catch {{RuntimeException}} from 
> {{DatabaseBuilder.open}} (or at least {{IndexOutOfBoundsException}} and 
> remaining {{{}IllegalStateException{}}}) and rethrow as {{TikaException}} or 
> {{{}CorruptedFileException{}}}. One catch covers both inputs. The 
> Jackcess-side fix is to throw {{IOException}} for a corrupt usage map, 
> matching the declared contracts of {{UsageMap.read}} and 
> {{{}validatePageNumber{}}}.
> I have attached both files as an archive to the issue.
> Found by the CISPA Fandango Team



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to