The GitHub Actions job "Java CI with Gradle" on 
poi.git/cryptoapi-descriptor-count has failed.
Run started by GitHub user pjfanning (triggered by pjfanning).

Head commit for run:
bbb00014ee29367f621c3cafde086717da0c588c / PJ Fanning 
<[email protected]>
CryptoAPIDecryptor: don't size the descriptor array from an untrusted count

getSummaryEntries reads the stream descriptor count as an unsigned 32-bit
field and used it directly as an array length, with no bound at all:

    int encryptedStreamDescriptorCount = Math.toIntExact(leis.readUInt());
    StreamDescriptorEntry[] entries =
            new StreamDescriptorEntry[encryptedStreamDescriptorCount];

A crafted encrypted stream can therefore ask for a billion-element array from
a handful of input bytes.

Two changes:

* Reject a count the input cannot back. The whole stream is already in memory
  and every entry occupies at least 18 bytes, so a declared count larger than
  the remaining bytes can hold is necessarily bogus. This is derived from the
  data rather than a fixed cap, so it cannot reject a well formed file however
  many streams it carries.
* Collect the entries as they are parsed instead of pre-allocating, so the
  memory used stays proportional to the data actually present.

entries was only consumed by an enhanced-for loop, so a List works in place of
the array.

For reference, the encrypted summary stream carries the property set streams
(MS-OFFCRYPTO 2.3.5.4), so real files declare 2; the sample in
TestDocumentEncryption has 2 entries in 128 bytes.

Found while sweeping Math.toIntExact call sites after #1345.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

Report URL: https://github.com/apache/poi/actions/runs/35728681658

With regards,
GitHub Actions via GitBox


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to