一句话:提出 classming,通过活字节码变异生成有效可执行程序,对主流 JVM 实现进行深度差分测试并发现大量缺陷。
验证生产级 JVM 的可靠性研究十分稀缺。已有的 classfuzz 仅对 Java 字节码做语法变异,主要产生非法字节码文件,多暴露 JVM 启动阶段的缺陷,难以深入测试字节码验证器与执行引擎。本文提出 classming,一种深度差分 JVM 测试方法,其核心是活字节码变异(live bytecode mutation):首先从种子字节码文件 f 中捕获其实际执行的指令序列(活字节码);然后反复操纵该活字节码中的控制流与数据流,生成语义不同的变异体;最后有选择地接受变异体,使变异过程朝活且多样的方向推进。生成的变异体被用于对多个 JVM 做差分测试。作者在 OpenJDK HotSpot 与 IBM J9 等主流 JVM 上以 DaCapo 基准程序为种子进行评估,超过 1800 个生成类暴露了 JVM 差异,30 余个触发 JVM 崩溃,其中 14 个已被确认或修复,包括 J9 中一个允许不可信代码关闭安全管理器并提升权限的高危安全漏洞(CVE-2017-1376)。
The Java Virtual Machine (JVM) is the cornerstone of the widely-used Java platform. Thus, it is critical to ensure the reliability and robustness of popular JVM implementations. However, little research exists on validating production JVMs. One notable effort is classfuzz, which mutates Java bytecode syntactically to stress-test different JVMs. It is shown that classfuzz mainly produces illegal bytecode files and uncovers defects in JVMs' startup processes. It remains a challenge to effectively test JVMs' bytecode verifiers and execution engines to expose deeper bugs. This paper tackles this challenge by introducing classming, a novel, effective approach to performing deep, differential JVM testing. The key of classming is a technique, live bytecode mutation, to generate, from a seed bytecode file f, likely valid, executable (live) bytecode files: (1) capture the seed f 's live bytecode, the sequence of its executed bytecode instructions; (2) repeatedly manipulate the control- and data-flow in f 's live bytecode to generate semantically different mutants; and (3) selectively accept the generated mutants to steer the mutation process toward live, diverse mutants. The generated mutants are then employed to differentially test JVMs. We have evaluated classming on mainstream JVM implementations, including OpenJDK's HotSpot and IBM's J9, by mutating the DaCapo benchmarks. Our results show that classming is very effective in uncovering deep JVM differences. More than 1,800 of the generated classes exposed JVM differences, and more than 30 triggered JVM crashes. We analyzed and reported the JVM runtime differences and crashes, of which 14 have already been confirmed/fixed, including a highly critical security vulnerability in J9 that allowed untrusted code to disable the security manager and elevate its privileges (CVE-2017-1376).