oss-fuzz/projects/jackson-datatypes-collections
Arthur Chan 6b64a6b331
jackson-datatypes-collections: Fix OOM on Iterable creation of primitive byte array (#11339)
This PR fixes 3 false positive issues in
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64623,
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64625 and
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64634 which
accidentally loops a very large byte array for too many times.

In `GuavaSerailizerFuzzer` case 11. The logic uses a combination of
`Iterables.cycle(T...)` and `Iterables.limit(Iterable, int)` to create
an iterator for the fuzzing process. But there is a bug in the creation
causing OOM.

In Java, the generic type application is only possible for non-primitive
type. For example, if the following code is run, the result is 2 and
`elements[0] = 1` and `elements[1] = 2` inside `genericTest(T...)`
because the generic type retrieves the Integer type successfully and `T`
is treated as `Integer`.
```java
public class Test {
  public static void main (String[] args) {
    Integer[] test = {1, 2};
    genericTest(test);
  }

  public static <T> T genericTest(T...elements) {
    System.out.println(elements.length);
  }
}
```
But if the code changes to use a primitive type array instead like the
following, the result is 2 and `elements[0][0] = 1` and `elements[0][1]
= 2` inside `genericTest(T...)` because the generic type fails to
convert the primitive type and thus it treats `T` as `int[]`.
```java
public class Test {
  public static void main (String[] args) {
    int[] test = {1, 2};
    genericTest(test);
  }

  public static <T> T genericTest(T...elements) {
    System.out.println(elements.length);
  }
}
```

Because of the above reason, the original code in
`GuavaSerializerFuzzer` shown below provides a `byte[]` to the
`Iterables.cycle(T...)` method. Thus the later
`Iterables.limit(Iterable, int)` is looping through the whole byte[] for
limit time, instead of looping the byte elements in the byte[]. It
results in OOM in some issues when the `data.consumeRemainingAsBytes()`
returns a very large byte array (e.g. 10k bytes). Instead of looping
each byte in the byte array, it actually loops the whole byte array as a
single object for 10k times which uses up the heap memory and causes
OOM.
```java
Iterables.limit(Iterables.cycle(data.consumeRemainingAsBytes()), remainingBytes))
```


This PR fixes the problem by using the `Bytes.asList()` to retrieve the
correct iterable objects for the fuzzing.

Signed-off-by: Arthur Chan <arthur.chan@adalogics.com>
2023-12-08 16:42:29 +00:00
..
Dockerfile
EclipseCollectionsDeserializerFuzzer.java
EclipseCollectionsSerializerFuzzer.java
GuavaDeserializerFuzzer.java
GuavaSerializerFuzzer.java jackson-datatypes-collections: Fix OOM on Iterable creation of primitive byte array (#11339) 2023-12-08 16:42:29 +00:00
HppcDeserializerFuzzer.java
HppcSerializerFuzzer.java
PCollectionsFuzzer.java
build.sh
project.yaml