aboutsummaryrefslogtreecommitdiff
path: root/agent/src
diff options
context:
space:
mode:
authorFabian Meumertzheim <fabian@meumertzhe.im>2022-03-08 12:54:20 +0100
committerFabian Meumertzheim <fabian@meumertzhe.im>2022-03-09 11:57:17 +0100
commit59d16517cd5ae8d743d570ee24fed2403fdd4682 (patch)
tree478eec3e250397b0df05e149f6e42dc800b94f83 /agent/src
parent95520d2b1090934af983b2342770238084557d31 (diff)
downloadjazzer-api-59d16517cd5ae8d743d570ee24fed2403fdd4682.tar.gz
Fix ClassCastException in mapGet hook
If the argument to Map#get cannot be compared to the keys in the map due to an incompatible type, the hook threw a ClassCastException. To address this, we: * Catch and ignore ClassCastException where it could be thrown. * Reverse the compareTo calls so that the likely more lenient compareTo function of the valid map key is used. The original OSS-Fuzz finding that uncovered this bug: == Java Exception: java.lang.ClassCastException: class com.alibaba.fastjson.JSONObject cannot be cast to class java.lang.Integer (com.alibaba.fastjson.JSONObject is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')  at java.base/java.lang.Integer.compareTo(Integer.java:64)  at com.code_intelligence.jazzer.runtime.TraceCmpHooks.mapGet(TraceCmpHooks.java:308)  at com.alibaba.fastjson.JSONObject.get(JSONObject.java:110)  at com.alibaba.fastjson.JSONPath.getArrayItem(JSONPath.java:3577)  at com.alibaba.fastjson.JSONPath$ArrayAccessSegment.eval(JSONPath.java:2736)  at com.alibaba.fastjson.JSONPath.eval(JSONPath.java:121)  at com.alibaba.fastjson.parser.DefaultJSONParser.handleResovleTask(DefaultJSONParser.java:1599)  at com.alibaba.fastjson.JSON.parse(JSON.java:183)  at com.alibaba.fastjson.JSON.parse(JSON.java:191)  at com.alibaba.fastjson.JSON.parse(JSON.java:147)  at JsonFuzzer.fuzzerTestOneInput(JsonFuzzer.java:24) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=42365
Diffstat (limited to 'agent/src')
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceCmpHooks.java33
1 files changed, 22 insertions, 11 deletions
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceCmpHooks.java b/agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceCmpHooks.java
index c7d4947e..e6d74187 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceCmpHooks.java
+++ b/agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceCmpHooks.java
@@ -293,25 +293,36 @@ final public class TraceCmpHooks {
Object upperBoundKey = null;
if (map instanceof TreeMap) {
final TreeMap treeMap = (TreeMap) map;
- lowerBoundKey = treeMap.floorKey(currentKey);
- upperBoundKey = treeMap.ceilingKey(currentKey);
+ try {
+ lowerBoundKey = treeMap.floorKey(currentKey);
+ upperBoundKey = treeMap.ceilingKey(currentKey);
+ } catch (ClassCastException ignored) {
+ // Can be thrown by floorKey and ceilingKey if currentKey is of a type that can't be
+ // compared to the maps keys.
+ }
} else if (currentKey instanceof Comparable) {
- final Comparable comparableKey = (Comparable) currentKey;
+ final Comparable comparableCurrentKey = (Comparable) currentKey;
// Find two keys that bracket currentKey.
// Note: This is not deterministic if map.size() > MAX_NUM_KEYS_TO_ENUMERATE.
int enumeratedKeys = 0;
for (Object validKey : map.keySet()) {
- if (validKey == null)
+ if (!(validKey instanceof Comparable))
continue;
+ final Comparable comparableValidKey = (Comparable) validKey;
// If the key sorts lower than the non-existing key, but higher than the current lower
// bound, update the lower bound and vice versa for the upper bound.
- if (comparableKey.compareTo(validKey) > 0
- && (lowerBoundKey == null || ((Comparable) validKey).compareTo(lowerBoundKey) > 0)) {
- lowerBoundKey = validKey;
- }
- if (comparableKey.compareTo(validKey) < 0
- && (upperBoundKey == null || ((Comparable) validKey).compareTo(upperBoundKey) < 0)) {
- upperBoundKey = validKey;
+ try {
+ if (comparableValidKey.compareTo(comparableCurrentKey) < 0
+ && (lowerBoundKey == null || comparableValidKey.compareTo(lowerBoundKey) > 0)) {
+ lowerBoundKey = validKey;
+ }
+ if (comparableValidKey.compareTo(comparableCurrentKey) > 0
+ && (upperBoundKey == null || comparableValidKey.compareTo(upperBoundKey) < 0)) {
+ upperBoundKey = validKey;
+ }
+ } catch (ClassCastException ignored) {
+ // Can be thrown by floorKey and ceilingKey if currentKey is of a type that can't be
+ // compared to the maps keys.
}
if (enumeratedKeys++ > MAX_NUM_KEYS_TO_ENUMERATE)
break;