Skip to content

[BUG] fastjson2 短字段名 hash 快路径的 Unsafe 8 字节读取在缓冲区末尾附近存在越界读取 #7865

Open

Description

@annoymous3

问题描述

fastjson2 在解析短字段名并进行 typed bean binding 时,字段名 hash 快路径会通过 Unsafe 一次性读取 8 字节 little-endian long。当字段名靠近输入 byte array 结尾、从读取位置到缓冲区末尾不足 8 字节时,该读取会越过输入缓冲区边界。

该问题可以通过 Jazzer UnsafeSanitizer 稳定复现。

代表性输入:

{"ab":1}

确认复现版本:2.0.61, 2.0.62, 2.0.63, 2.0.64, 2.0.65。

环境信息

  • OS信息:Linux x86_64
  • JDK信息:Temurin OpenJDK 17.0.11
  • 版本信息:Fastjson2 2.0.61, 2.0.62, 2.0.63, 2.0.64, 2.0.65

重现步骤

  1. 使用 JSON.parseObject(String, Class<T>) 方法进行 typed bean binding。
  2. 输入短字段名 JSON 数据:{"ab":1}。
  3. 使用 Jazzer UnsafeSanitizer 运行时,出现 FuzzerSecurityIssueCritical: Access at offset 18 with size 8 exceeds end offset 24。
import com.alibaba.fastjson2.JSON;

public class Reproducer {
    public static class TestBean {
        public long id;
        public int count;
        public double ratio;
        public boolean enabled;
        public String name;
        public java.math.BigDecimal amount;
        public java.util.List<String> tags;
        public java.util.Map<String, Object> attributes;
    }

    public static void main(String[] args) {
        JSON.parseObject("{\"ab\":1}", TestBean.class);
    }
}

在普通 JVM 下,上述代码通常会正常执行;需要使用 Jazzer UnsafeSanitizer 才能观察到越界读取。复现命令示例:

JAVA_HOME=/path/to/jdk17 ./run-bug01-unsafe-read.sh

其中 run-bug01-unsafe-read.sh 使用 Jazzer 启用 sanitizer,并执行上述 typed bean 解析路径。

期待的正确结果

解析器不应读取输入 byte array 边界之外的数据。

在字段名 hash 快路径中,如果当前位置到输入缓冲区末尾不足 8 字节,应当使用有边界检查的读取方式,或者回退到 byte-wise 的安全慢路径,而不是直接调用 Unsafe 读取完整 8 字节。

相关日志输出

请复制并粘贴任何相关的日志输出。

Jazzer UnsafeSanitizer 报告如下:

com.code_intelligence.jazzer.api.FuzzerSecurityIssueCritical:
  Access at offset 18 with size 8 exceeds end offset 24
    at com.code_intelligence.jazzer.sanitizers.UnsafeSanitizer.report(UnsafeSanitizer.java:428)
    at com.code_intelligence.jazzer.sanitizers.UnsafeSanitizer.checkAccess(UnsafeSanitizer.java:505)
    at com.code_intelligence.jazzer.sanitizers.UnsafeSanitizer.checkByteSizedAccess(UnsafeSanitizer.java:444)
    at com.code_intelligence.jazzer.sanitizers.UnsafeSanitizer.primitiveGetterHook(UnsafeSanitizer.java:263)
    at com.alibaba.fastjson2.util.IOUtils.getLongLE(IOUtils.java:2776)
    at com.alibaba.fastjson2.util.Fnv.hashCode64(Fnv.java:82)
    at com.alibaba.fastjson2.JSONReaderASCII.readFieldNameHashCode(JSONReaderASCII.java:227)
    at com.alibaba.fastjson2.reader.ORG_1_8_TestBean.readObject(Unknown Source)
    at com.alibaba.fastjson2.JSON.parseObject(JSON.java:992)

建议修复方式:

  • 在调用 IOUtils.getLongLE 前检查剩余长度,确保 offset + 8 <= end;
  • 或者当字段名长度较短、输入尾部不足 8 字节时,使用 byte-wise 安全拼装逻辑;
  • 添加回归测试,覆盖字段名位于输入末尾附近、剩余字节不足 8 的情况。

Activity

  1. changed the title [-][BUG][/-] [+][BUG] fastjson2 短字段名 hash 快路径的 Unsafe 8 字节读取在缓冲区末尾附近存在越界读取[/+] on Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions