Differential fuzzy test method for JIT compiler in JS engine and terminal equipment
By constructing test cases that include elements that induce JIT compiler errors, and by using function hijacking and strict mode to fix the return values and execution context of dynamic functions and isolate global objects, the accuracy and efficiency issues of JIT compiler error detection are solved, achieving low false positive rate and high efficiency in JIT compiler error detection.
Patent Information
- Application Number
- CN202511041486.8
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2025-07-28
- Publication Date
- 2025-10-17
AI Technical Summary
In JavaScript execution environments, existing technologies have low accuracy in JIT compiler error detection, high false positive rates, and low operating efficiency, making it difficult to effectively eliminate execution differences caused by dynamic factors.
By constructing test cases that include JIT compiler error triggering elements, using function hijacking to fix dynamic function return values, employing strict mode to fix the execution context, and isolating global objects, combined with consistency test results, the nondeterminism of the interpreted execution mode is eliminated, and redundant execution is reduced.
It improved the accuracy of JIT compiler error detection, reduced the false positive rate, improved runtime efficiency, discovered new JIT optimization errors, and reduced the false positive rate.
Smart Images

Figure CN120803946A_ABST
Abstract
Description
TECHNICAL FIELD
[0001] The application belongs to the technical field of software security, and particularly relates to a differential fuzz testing method for a JIT compiler in a JS engine and a terminal device. BACKGROUND
[0002] With the improvement of performance requirements of modern software, the JIT compiler has become a core component of the JavaScript engine, but the complexity of the optimization logic of the JIT compiler makes it difficult for traditional testing methods to effectively cover such defects. Traditional fuzz testing techniques mainly discover vulnerabilities by monitoring program crashes and exceptions (such as memory access out of bounds), but JIT optimization errors are usually not easy to observe, and traditional testing predictions are difficult to detect. In recent years, differential testing methods targeting dynamic optimization processes have gradually become mainstream. Such techniques trigger the interpreter and JIT compiler execution modes, capture the execution results of different modes, and compare the results to detect JIT optimization errors.
[0003] The existing differential testing scheme faces two major challenges: first, there are a large number of non-deterministic factors (such as random function calls, global object state tampering, etc.) in the JavaScript execution environment, which may not be caused by real optimization errors, and the false positive rate of the current optimal detection scheme is more than 90%; second, the existing method causes low running efficiency due to the redundant optimization execution of invalid test cases or the initialization of the engine twice to trigger the interpreter and the JIT compiler. For example, the JIT-Picker scheme requires two independent runs of the interpreter mode and the JIT compiler mode to compare the results, which doubles the time consumption and cannot accurately locate the specific component from which the difference comes; and FuzzJIT, although it uses a single execution template to trigger both modes in one execution, fails to effectively eliminate the dynamic nature of the input, resulting in a large number of invalid test cases entering the JIT optimization phase, wasting computing resources.
[0004] In summary, how to achieve low false positive rate and high running efficiency of JIT compiler error detection in a highly dynamic JavaScript execution environment is still a problem to be solved in this field. SUMMARY
[0005] The technical problem to be solved by the application is to provide a differential fuzz testing method for a JIT compiler in a JS engine and a terminal device to improve the accuracy of JIT compiler error detection.
[0006] In a first aspect, the application provides a differential fuzz testing method for a JIT compiler in a JS engine, which comprises the following steps: constructing a plurality of initial test cases containing JIT compiler error inducing elements and capable of triggering both bytecode interpreter optimization function and JIT compiler optimization function simultaneously; fixing the return value of the dynamic function in each initial test case through function hijacking to obtain a plurality of first test cases; fixing the execution context in each first test case based on strict mode and isolating the global object in the first test case to obtain a plurality of second test cases; the plurality of initial test cases correspond one-to-one to the plurality of first test cases and the plurality of second test cases; for each second test case, executing the second test case multiple times using the bytecode interpreter and detecting the consistency of the interpretation execution results obtained after the multiple executions to obtain a consistency detection result corresponding to the second test case; the consistency detection result is consistent or inconsistent; triggering the JIT compiler optimization function using the second test case with consistent consistency detection result and detecting whether the JIT compiler has errors according to the execution results of the second test case before and after optimization.
[0007] Optionally, constructing a plurality of initial test cases containing JIT compiler error inducing elements and capable of triggering both bytecode interpreter optimization function and JIT compiler optimization function simultaneously, comprises: mutating a plurality of source test cases obtained in advance using language elements that cause errors of the JIT compiler to obtain a plurality of mutation test cases; obtaining the plurality of initial test cases by combining each mutation test case with a single trigger template; the single trigger template includes bytecode interpreter optimization trigger code and JIT compiler optimization function trigger code.
[0008] Optionally, the language elements at least include array, object and object member access.
[0009] Optionally, the dynamic function includes random number generation function and time calling function. fixing the return value of the dynamic function in each initial test case through function hijacking, comprises: forcibly redirecting the return value of the random number generation function to a fixed value; forcibly returning a predefined fixed timestamp through function reconstruction of the constructor and prototype chain of the time calling function.
[0010] Optionally, isolating the global object in the first test case, comprises: freezing the global object using static function to fix the attribute value of the global object.
[0011] Optionally, consistency detection is performed on the interpretation execution results obtained after multiple executions to obtain a consistency detection result corresponding to the second test case, including: If the interpretation execution results obtained after any two executions are different, it is determined that the consistency detection result is inconsistent, otherwise, it is determined that the consistency detection result is consistent.
[0012] Optionally, the JIT compiler optimization function is triggered by the second test case with a consistent consistency detection result, and whether the JIT compiler has an error is detected according to the execution results of the second test case before and after optimization, including: The reference prediction of the second test case with a consistent consistency detection result is obtained, and the reference prediction is any one interpretation execution result of the second test case in the bytecode interpreter; The second test case with a consistent consistency detection result is executed by using the JIT compiler to obtain a compiled execution result; It is determined whether the reference prediction and the compiled execution result are the same, if not, it is determined that the JIT compiler has an error, otherwise, it is determined that the JIT compiler has no error.
[0013] Optionally, the static function is a global object freezing function or a property fixing function.
[0014] In a second aspect, the present application provides a terminal device, including a memory, a processor and a computer program stored in the memory and executable on the processor, and the processor implements the above method when executing the computer program.
[0015] In a third aspect, the present application provides a computer readable storage medium, the computer readable storage medium stores a computer program, and the computer program is executed by a processor to implement the above method.
[0016] The beneficial effects of the present application are: The JIT compiler differential fuzz testing method for the JS engine provided by the application can fix the return value of the dynamic function in each initial test case through function hijacking, can eliminate the non-determinism of the interpretation execution mode caused by the dynamic change of the return value of the dynamic function, is conducive to reducing the false positive rate, and improves the accuracy of the error detection of the JIT compiler; the execution context in each first test case is fixed based on the strict mode, and the global object in the first test case is isolated, which can realize the protection of the execution context and the global object state, avoid the non-determinism of the interpretation execution mode caused by the dynamic change of the context and the tampering of the global object, is conducive to reducing the false positive rate, and improves the accuracy of the error detection of the JIT compiler; only the second test case with consistent consistency detection results is used to trigger the JIT compiler optimization function, which can further eliminate the non-determinism of the interpretation execution mode, reduce the redundant execution of the JIT compiler optimization, is conducive to reducing the false positive rate, and improves the accuracy of the error detection of the JIT compiler. BRIEF DESCRIPTION OF DRAWINGS
[0017] Figure 1 A first test case in the embodiment of the application is shown in the figure; Figure 2 A flowchart of the JIT compiler differential fuzz testing method for the JS engine in one of the embodiments of the application is shown in the figure; Figure 3 A second test case in the embodiment of the application is shown in the figure; Figure 4 A third test case in the embodiment of the application is shown in the figure; Figure 5 A structure diagram of a terminal device in one of the embodiments of the application is shown in the figure. DETAILED DESCRIPTION
[0018] In order to solve the problem of low accuracy of error detection of the traditional JIT compiler, the application discloses a differential fuzz testing method for a JIT compiler in a JS engine and a terminal device, the method can fix the return value of a dynamic function in each initial test case through function hijacking, can eliminate the non-determinism of the interpretation execution mode caused by the dynamic change of the return value of the dynamic function, is beneficial to reduce the false positive rate and improve the accuracy of error detection of the JIT compiler, the execution context in each first test case is fixed based on the strict mode, and the global object in the first test case is isolated, the protection of the execution context and the global object state can be realized, the non-determinism of the interpretation execution mode caused by the dynamic change of the context and the tampering of the global object can be avoided, which is beneficial to reduce the false positive rate and improve the accuracy of error detection of the JIT compiler, and only the second test case with consistent consistency detection results is used to trigger the JIT compiler optimization function, which can further eliminate the non-determinism of the interpretation execution mode, reduce the redundant execution of the JIT compiler optimization, and is beneficial to reduce the false positive rate and improve the accuracy of error detection of the JIT compiler.
[0019] In order to explore the cause of false positive of the JIT compiler, the inventors use the method combining cross-engine dynamic tracking and specification consistency verification to construct the test scene covering three engines of V8 (from Google), SpiderMonkey (from Mczilla) and JavaScriptCore (from Apple). Based on 5,000 false positive samples collected from the most advanced fuzz testing framework (such as FuzzJIT, JIT-Picker), systematic analysis is carried out, the causes of false positive are summarized, and the false positive is divided into four categories according to the root cause: ① False positive caused by random data dependence When there is a random function call in the variant code, random data will be generated as the data stream input of the interpreter and the JIT compiler, and this dynamic change of input may cause false positives of the test prediction. For example Figure 1When the function opt() depends on Math.random() to generate random values, the first execution result (e.g., a1 = 0.7) of the interpreter may be different from the execution result (e.g., a2 = 0.3) after JIT optimization, as shown in the second row of Table 1. This execution difference will be determined as a defect by the test oracle, but it is not a JIT optimization error, thus leading to a false positive. The natural dynamic nature of the random number generation algorithm is one of the causes of Interpreter execution mode's Non-Determinisim (IEND). The execution difference caused by IEND is unrelated to JIT optimization, but the test oracle mistakenly judges it as an optimization error. In fact, even if the opt() function is called continuously in the interpreter execution mode, the results may still be different due to dynamic input. This case illustrates the existing differential test oracle's neglect of IEND, and comparing the execution differences between the interpreter and JIT stages cannot correctly determine JIT optimization errors.
[0020] ②False positives caused by the dynamic nature of time functions When there are time function calls in the mutated code, time-related data will be generated as input data for the interpreter and JIT compiler. The dynamic nature of these data may cause false positives in the test oracle. For example, Figure 1 As shown in the third row of Table 1, the function opt() calls Date.now() to return the real-time timestamp. Since the time of interpreter execution and the time of JIT optimization execution will inevitably differ, the final execution results will also be different, thus being determined as a defect by the test oracle, which is a false positive case. The fourth row shows another case of time function calls, which obtains the current time by calling the constructor function of Date. Although the form is the same as Date.now(), since the constructor function is related to the prototype of the object in JavaScript, this false positive case of calling the constructor function is more difficult to eliminate.
[0021] ③False positives caused by changes in execution context During the test case process, if the execution context is obtained by the mutated code and becomes a variable related to the input of the interpreter and JIT compiler, the dynamic change of the execution context becomes one of the sources of IEND. For example, Figure 1As shown in line 5, JSON.stringify() converts a JavaScript object or value to a JSON string. In non-strict mode, if its input is the this keyword, this refers to the execution context and is provided as input to the function. In other words, JSON.stringify(this) converts the current execution context into a JSON string output. The execution context is dynamic, so IEND is generated, leading to a false positive in the test prophecy of execution differences. For example, in the SpiderMonkey engine, the performance interface related to the execution context provides a Firefox browser-specific performance monitoring API, performance.mozMemory, which is used to track memory and garbage collection (GC) status. In SpiderMonkey, JSON.stringify(this) converts the performance.mozMemory.gc object into a JSON string for output, which contains the real-time status and statistical information of the current GC (such as gcBytes). This type of false positive is different from the previous two cases. The IEND is not directly caused by the variant code logic, but by the change in the execution context during program execution. If the this keyword is bound to a fixed object, the execution context may not change during program execution.
[0022] ④False positives caused by tampering with global objects During code execution, if a JavaScript built-in object is actively tampered with by the code, the state of the global object may change. When the test prophecy execution code takes the global object as data flow input, it may cause false positives. For example, Figure 1 As shown in line 6, the built-in object Array is called by the opt() function, and Array.prototype is actively tampered with by the code as its prototype. The push() method adds a new property to the prototype of the Array object and returns the modified length value. Specifically, Array.prototype.push(1) adds a property named 1 to the prototype of Array and increments the length of the Array prototype by one, so the state of the global object Array is contaminated. Since each call to the opt() function increments the length of the Array prototype by one, the dynamic change caused by this global state contamination leads to the generation of IEND.
[0023] False positive type caused by global object tampering exposes the problem of execution difference caused by prototype chain pollution in dynamic language. Since various global objects have various methods and prototype properties with different functions, and the ways of modifying the prototype of global objects are different, it is very difficult to find all the tampering ways. This paper illustrates a simple case here, but this kind of false positive reveals a deep challenge in dynamic language testing, that is, the dynamic tampering of global objects leads to different outputs of the same function under the same input and execution environment. This execution difference comes from the execution result of the code itself in the dynamic execution process, not the error of the static code logic. Even if the JIT optimization process is completely correct, the execution result of the interpreter and the execution result of the JIT compiler will still be different. To check the existence of such differences requires a great overhead.
[0024] Based on the above analysis, the application provides a differential fuzz testing method for JIT compiler in JS engine, which takes a progressive elimination to form a collaborative system of active inhibition and passive verification for different false positive types, so as to improve the accuracy of error detection of JIT compiler.
[0025] As shown in Figure 2 The differential fuzz testing method for JIT compiler in JS engine includes the following steps: Step 21, constructing a plurality of initial test cases containing JIT compiler error inducing elements and capable of triggering the bytecode interpreter optimization function and the JIT compiler optimization function at the same time.
[0026] It should be noted that the test cases in the embodiments of the application are valid inputs extracted from existing code libraries (such as common JavaScript scripts); in other embodiments, the test cases can also be simple test cases written by hand (such as basic JavaScript code segments) or randomly generated legal inputs (such as syntax correct code structures).
[0027] In the embodiments of the application, the plurality of initial test cases containing JIT compiler error inducing elements and capable of triggering the bytecode interpreter optimization function and the JIT compiler optimization function at the same time include steps 21.1 to 21.2.
[0028] Step 21.1, using language elements that cause JIT compiler errors to mutate a plurality of source test cases obtained in advance to obtain a plurality of mutated test cases.
[0029] In a feasible embodiment, the above-mentioned language elements that cause JIT compiler errors at least include arrays, objects and object member access.
[0030] The process of mutating the pre-acquired multiple source test cases in one embodiment of the present application is described below.
[0031] Specifically, the mutation strategy for arrays includes super large index access, dynamic type conversion, and prototype chain pollution. The super large index access refers to inserting a very large numerical index (such as 2^32-1) during array initialization or runtime to trigger integer overflow or out-of-bound optimization vulnerabilities of the JIT engine. The dynamic type conversion refers to mixing basic types and object elements through methods such as push(), splice(), and the like to interfere with the type speculation mechanism of the JIT. The prototype chain pollution refers to modifying the array prototype (such as Array.prototype) to insert irregular properties, causing unexpected behavior when traversing or accessing.
[0032] The mutation strategy for objects includes property hijacking, prototype chain pollution, dynamic property deletion and reconstruction. The property hijacking refers to defining an accessor property (getter / setter) using Object.defineProperty to throw an exception or return an unexpected type value when accessed. The prototype chain pollution in the mutation strategy for objects refers to injecting a pollution property into the prototype chain through __proto__ or Object.setPrototypeOf, causing type confusion when accessing inherited properties. Dynamic property deletion and reconstruction refers to dynamically deleting properties in an object and replacing them with accessor properties or non-enumerable properties to interfere with the Inline Cache mechanism of the JIT.
[0033] The mutation strategy for object member access includes nested structure out-of-bound and computed property name pollution. The nested structure out-of-bound refers to accessing properties or elements beyond the actual level by constructing a multi-dimensional array / object nested structure (such as arr
[99999] .prop). The computed property name pollution refers to using dynamically generated property names (such as obj[computedKey]) combined with irregular values (such as objects, functions) to force property lookup path exceptions.
[0034] Step 21.2, for each mutated test case, combine a single trigger template to obtain multiple initial test cases.
[0035] The single trigger template includes bytecode interpreter optimization trigger code and JIT compiler optimization function trigger code.
[0036] Since the bytecode interpreter of the JS engine has no optimization function and only the JIT compiler has the optimization function, in the embodiment of the present invention, the interpreter is initially used by default to execute the JS file. When the number of executions of a certain part of the code reaches a threshold, the JIT compiler will be triggered to optimize and compile and execute. Therefore, the single trigger template means that the actual code part of the test case is the opt function, and the subsequent first execution is the interpreter triggering code, and the cyclic execution activates the JIT optimization and becomes the JIT compiler triggering code.
[0037] Step 22: Fix the return value of the dynamic function in each initial test case through function hijacking to obtain multiple first test cases.
[0038] Based on the analysis of the causes of false positives in the previous article, the main reasons for false positives caused by random data dependence and false positives caused by the dynamic nature of time functions are changes in the return values of dynamic functions, and dynamic functions include random number generation functions and time call functions.
[0039] In order to eliminate false positives caused by changes in dynamic function return values, in an embodiment of the present invention, for the random number generation function, the return value of the random number generation function is forcibly redirected to a fixed value; for the time call function, through function reconstruction, the constructor and prototype chain of the time call function are forced to return a predefined fixed timestamp.
[0040] In a possible embodiment, Figure 3 As shown in the first line of the code, for the random number generation function, the Math.random() function is modified so that its return value is forced to 1, making it impossible to generate a random sequence. The dynamically changing return value is fixed to avoid the generation of IEND. For the time call function, a fixed function timestamp method is used to eliminate it. First, by rewriting Date.now(), its return value is fixed to a predefined constant timestamp. Then, the global object Date is proxied, and its constructor logic is modified to return a fixed value. Finally, the constructor of the Date prototype is bound to the modified proxy Date object. At this point, the dynamic nature of the constructor is eliminated, and the IEND caused by time changes will no longer be generated. Figure 3 The second line represents the specific implementation of rewriting jsDate.
[0041] It should be noted that only Math.random(), Date.now() and new Date() are taken as examples in the embodiments of the present application. In other feasible embodiments, the random number generation functions also include crypto.getRandomValues(typedArray), crypto.randomBytes(size) and the like; the time calling functions also include performance.now(), process.hrtime() and the like; and the specific function types are not limited herein, as long as the random number generation functions and the time calling functions in the JavaScript engine can eliminate false positives according to the above scheme.
[0042] It should be noted that the return value of the fixed dynamic function is essentially to force the dynamic function to be modified into a static function, and the static return value becomes the deterministic input of the interpreter and the JIT compiler.
[0043] In step 23, the execution context in each first test case is fixed based on the strict mode, and the global object in the first test case is isolated, to obtain a plurality of second test cases.
[0044] In the embodiments of the present application, the plurality of initial test cases correspond one-to-one to the plurality of first test cases and the plurality of second test cases.
[0045] It should be noted that the strict mode is a more restrictive code execution mode introduced by ECMAScript, which aims to eliminate unsafe operations in the code and improve code security, and one of the key restrictions is that the this keyword points to undefined in the strict mode. For example, the opt function in the following code is executed in the strict mode, and the this keyword points to undefined. Figure 3 As shown in line 6 in the middle, by forcing to start the strict mode of ECMAScript 5 ("use strict") in the scope of the opt function, the this keyword without binding execution context points to undefined, and JSON.stringify(this) will also return undefined, thus blocking the program from implicitly obtaining the execution context through the this keyword, and avoiding the dynamic nature of the execution context to produce IEND.
[0046] For false positives caused by global object tampering, the most direct way to eliminate is to check whether tampering occurs before entering the JIT optimization phase, but this method needs to backup the initial state of all global objects and their methods and prototype properties first, and then compare them with the global state after the interpreter execution to detect tampering behavior, and the two traversals of the global state will introduce unacceptable additional overhead, greatly reducing the running efficiency. Therefore, in the embodiment of the present application, an indirect way is selected to realize the isolation of global objects: freeze global objects using static functions to fix the attribute values of global objects.
[0047] Specifically, in JavaScript, almost all objects are instances of Object, and Object.prototype is the only object in JavaScript with an immutable prototype, that is, its prototype is always null and cannot be changed; in particular, Object has a static method called freeze() that can freeze an object, making it non-extensible and locking all property values and configurations, and after freezing, the object will be completely immutable: it is prohibited to add new properties, delete existing properties, or modify property values, at the same time, the enumerability, configurability, and writability of all properties are fixed, and the prototype of the object cannot be re-specified. In an embodiment of the present application, the built-in objects of JavaScript are frozen using the Object.freeze() method in the initialization phase to block the way for test cases to pollute the global object state, avoiding IEND caused by changes in the global object state. Figure 3 The 3rd line in the middle represents recursive freezing of built-in objects and their prototypes. Among them, the static function is a global object freezing function or a property fixing function.
[0048] Step 24, for each second test case, respectively, the bytecode interpreter is used to execute the second test case multiple times, and the consistency of the interpretation execution results obtained after multiple executions is detected to obtain the consistency detection result corresponding to the second test case.
[0049] The consistency detection result is consistent or inconsistent. Specifically, if the interpretation execution results obtained after any two executions are different, it is determined that the consistency detection result is inconsistent; otherwise, it is determined that the consistency detection result is consistent.
[0050] Although the foregoing summarizes four types of existing false positives, due to the dynamic nature and complexity of JavaScript, the elimination of IENDs in actual implementation cannot reach 100%. Therefore, before entering the JIT optimization execution phase, the execution results of the interpreter phase need to be detected, further filtering potential residual IENDs, and discarding such test cases to reduce the redundant execution of JIT optimization. As shown in lines 1-8 of Figure 4 Before entering the JIT compiler optimization execution, the test case is executed N times in the interpreter mode, and the output set O={o1,o2,…,on} is recorded; then consistency detection is performed, if there is oi ≠ oj(i ≠ j), it is determined that the test case is disturbed by residual IEND, and is discarded without entering the JIT compiler optimization execution. If the interpreter itself execution result O is consistent, o1 can be used as the benchmark prophecy (a0), and the JIT compiler optimization execution is entered. This mechanism intercepts the interference caused by the IEND that has not been completely eliminated through multiple rounds of interpreter self-validation, terminates such test cases in advance to avoid entering the JIT optimization phase and differential arbitration phase, and reduces redundant tests to improve running efficiency. Figure 4
[0051] Step 25, triggering the JIT compiler optimization function for the second test case with consistent consistency detection results, and detecting whether the JIT compiler has an error according to the execution results of the second test case before and after optimization.
[0052] Specifically, steps 25.1 to 25.3 are included.
[0053] Step 25.1, obtaining the benchmark prophecy of the second test case with consistent consistency detection results; the benchmark prophecy is the execution result of the second test case in any one interpretation execution of the bytecode interpreter; Step 25.2, executing the second test case with consistent consistency detection results using the JIT compiler to obtain the compiled execution result; Step 25.3, determining whether the benchmark prophecy and the compiled execution result are the same, if not, determining that the JIT compiler has an error; otherwise, determining that the JIT compiler has no error.
[0054] For example, as shown in lines 9-17 of Figure 4 The execution result after JIT optimization is strictly compared with the benchmark prophecy (a0) generated by pre-checking, if there is a difference (a0≠a2), it is confirmed that the execution difference comes only from the JIT optimization process, and it is determined that the JIT compiler has an error.
[0055] In order to verify the effectiveness of the differential fuzz testing method for the JIT compiler in the JS engine provided by the present application, in another embodiment of the present application, the differential fuzz testing method for the JIT compiler in the JS engine provided by the present application is compared with the traditional method (FuzzJIT, JIT-Picker) respectively on V8, SpiderMonkey and JavaScriptCore.
[0056] The results show that: the differential fuzz testing method for the JIT compiler in the JS engine provided by the present application completely eliminates false positives (FuzzJIT averages 212.6, and AccuOracle is 0); the throughput of the differential fuzz testing method for the JIT compiler in the JS engine provided by the present application is significantly higher than that of JIT-Picker, slightly lower than that of FuzzJIT, but the cost of zero false positives is reasonable; the effectiveness of the test cases generated by the differential fuzz testing method for the JIT compiler in the JS engine provided by the present application (about 60%) is comparable to that of existing methods; the code coverage of the differential fuzz testing method for the JIT compiler in the JS engine provided by the present application is close to that of FuzzJIT and superior to that of JIT-Picker; the differential fuzz testing method for the JIT compiler in the JS engine provided by the present application finds 8 new JIT errors (including two CVEs), such as a vulnerability (CVE-2025-3031) in SpiderMonkey caused by an error in the calculation of the width of the stack slot, which leads to sensitive data leakage.
[0057] In summary, the differential fuzz testing method for the JIT compiler in the JS engine provided by the present application can eliminate the non-determinism of the interpretation execution mode caused by the dynamic changes of the return values of dynamic functions by fixing the return values of dynamic functions in each initial test case through function hijacking, which is conducive to reducing the false positive rate and improving the accuracy of JIT compiler error detection; the execution context in each first test case is fixed based on the strict mode, and the global object in the first test case is isolated, which can protect the execution context and the state of the global object, avoid the non-determinism of the interpretation execution mode caused by the dynamic changes of the context and the tampering of the global object, and is conducive to reducing the false positive rate and improving the accuracy of JIT compiler error detection; only the second test case with consistent detection results is used to trigger the JIT compiler optimization function, which can further eliminate the non-determinism of the interpretation execution mode, reduce the redundant execution of the JIT compiler optimization, and is conducive to reducing the false positive rate and improving the accuracy of JIT compiler error detection.
[0058] As shown in Figure 5 , an embodiment of the present application provides a terminal device, as shown in Figure 5 The terminal device D10 of the embodiment includes at least one processor D100 ( Figure 5The computer program D102, when executed by the at least one processor D100, implements the steps of any of the method embodiments described above. In particular, the processor D100, in execution of the computer program D102, constructs a plurality of initial test cases containing JIT compiler bug inducing elements and capable of triggering both bytecode interpreter optimization function and JIT compiler optimization function simultaneously; fixes the return value of a dynamic function in each initial test case by function hijacking to obtain a plurality of first test cases; fixes the execution context in each first test case based on strict mode and isolates the global object in the first test case to obtain a plurality of second test cases; for each second test case, respectively, executes the second test case multiple times by using the bytecode interpreter, and detects the consistency of the interpretation execution results obtained after multiple executions to obtain a consistency detection result corresponding to the second test case; triggers the JIT compiler optimization function for the second test cases with consistent consistency detection results, and detects whether the JIT compiler has errors according to the execution results of the second test cases before and after optimization. By fixing the return value of the dynamic function in each initial test case by function hijacking, the non-determinism of the interpretation execution mode caused by the dynamic change of the return value of the dynamic function can be eliminated, which is conducive to reducing the false positive rate and improving the accuracy of JIT compiler error detection; by fixing the execution context in each first test case based on strict mode and isolating the global object in the first test case, the protection of the execution context and the global object state can be realized, which is conducive to reducing the false positive rate and improving the accuracy of JIT compiler error detection; by triggering the JIT compiler optimization function only for the second test cases with consistent consistency detection results, the non-determinism of the interpretation execution mode can be further eliminated, the redundant execution of the JIT compiler optimization can be reduced, which is conducive to reducing the false positive rate and improving the accuracy of JIT compiler error detection.
[0059] In particular, the processor D100, in execution of the computer program D102, constructs a plurality of initial test cases containing JIT compiler bug inducing elements and capable of triggering both bytecode interpreter optimization function and JIT compiler optimization function simultaneously; fixes the return value of a dynamic function in each initial test case by function hijacking to obtain a plurality of first test cases; fixes the execution context in each first test case based on strict mode and isolates the global object in the first test case to obtain a plurality of second test cases; for each second test case, respectively, executes the second test case multiple times by using the bytecode interpreter, and detects the consistency of the interpretation execution results obtained after multiple executions to obtain a consistency detection result corresponding to the second test case; triggers the JIT compiler optimization function for the second test cases with consistent consistency detection results, and detects whether the JIT compiler has errors according to the execution results of the second test cases before and after optimization. By fixing the return value of the dynamic function in each initial test case by function hijacking, the non-determinism of the interpretation execution mode caused by the dynamic change of the return value of the dynamic function can be eliminated, which is conducive to reducing the false positive rate and improving the accuracy of JIT compiler error detection; by fixing the execution context in each first test case based on strict mode and isolating the global object in the first test case, the protection of the execution context and the global object state can be realized, which is conducive to reducing the false positive rate and improving the accuracy of JIT compiler error detection; by triggering the JIT compiler optimization function only for the second test cases with consistent consistency detection results, the non-determinism of the interpretation execution mode can be further eliminated, the redundant execution of the JIT compiler optimization can be reduced, which is conducive to reducing the false positive rate and improving the accuracy of JIT compiler error detection.
[0060] The processor D100 can be a central processing unit (CPU), and can also be other general-purpose processors, digital signal processors (DSP), application specific integrated circuits (ASIC), field-programmable gate arrays (FPGA) or other programmable logic devices, discrete gates or transistor logic, discrete hardware components, etc. The general-purpose processor can be a microprocessor or the processor can also be any conventional processor.
[0061] The memory D101 can be an internal storage unit of the terminal device D10 in some embodiments, such as a hard disk or a memory of the terminal device D10. The memory D101 can also be an external storage device of the terminal device D10 in other embodiments, such as a plug-in hard disk, a smart media card (SMC), a secure digital (SD) card, a flash card, etc. Further, the memory D101 can include both an internal storage unit and an external storage device of the terminal device D10. The memory D101 is used to store an operating system, application programs, a boot loader, data, and other programs, such as program codes of the computer program, etc. The memory D101 can also be used to temporarily store data that has been output or will be output.
[0062] The embodiments of the present application further provide a computer readable storage medium, which stores a computer program. The computer program is executed by a processor to implement the steps in the above various method embodiments.
[0063] The embodiments of the present application provide a computer program product. When the computer program product is run on a terminal device, the terminal device is caused to implement the steps in the above various method embodiments.
[0064] Those skilled in the art should understand that the discussion of the above any embodiment is only exemplary, and is not intended to imply that the protection scope of the present application is limited to these examples; under the idea of the present application, the above embodiments or technical features in different embodiments can also be combined, the steps can be implemented in any order, and there are many other changes of different aspects of one or more embodiments of the present application as described above. In order to be brief, they are not provided in details.
[0065] It is intended that the embodiments of the application herein described be interpreted to cover all such modifications, alterations, and equivalents as fall within the true spirit and scope of the application. Accordingly, what is desired to be secured by Letters Patent is the subject matter as follows.
Claims
1. A differential fuzz testing method for a JIT compiler in a JS engine, characterized in that: include: Build several initial test cases that contain JIT compiler error-inducing elements and can trigger both bytecode interpreter optimizations and JIT compiler optimizations; Fixing the return value of the dynamic function in each of the initial test cases by function hijacking to obtain a plurality of first test cases; Fixing the execution context in each of the first test cases based on the strict mode and isolating the global objects in the first test case to obtain a plurality of second test cases; wherein the plurality of initial test cases correspond one-to-one to the plurality of first test cases and the plurality of second test cases; For each of the second test cases, execute the second test case multiple times using a bytecode interpreter, and perform consistency testing on interpretation and execution results obtained after the multiple executions to obtain a consistency test result corresponding to the second test case; The consistency test result is consistent or inconsistent; The JIT compiler optimization function is triggered by using the second test case whose consistency detection result is consistent, and whether an error occurs in the JIT compiler is detected according to the execution results of the second test case before and after optimization.
2. The differential fuzz testing method for the JIT compiler in the JS engine according to claim 1, characterized in that: The build contains JIT compiler error-inducing elements and several initial test cases that can trigger both bytecode interpreter optimizations and JIT compiler optimizations, including: Utilizing language elements that cause JIT compiler errors to mutate multiple source test cases obtained in advance, multiple mutated test cases are obtained; Each of the variant test cases is combined with a single trigger template to obtain the multiple initial test cases; the single trigger template includes a bytecode interpreter optimization trigger code and a JIT compiler optimization function trigger code.
3. The differential fuzz testing method for the JIT compiler in the JS engine according to claim 2, characterized in that: The language elements include at least array, object and object member access.
4. The differential fuzz testing method for a JIT compiler in a JS engine according to claim 1, characterized in that: The dynamic function includes a random number generation function and a time calling function; Fixing the return value of each dynamic function in the initial test case by function hijacking includes: Forcibly redirecting the return value of the random number generation function to a fixed value; By refactoring the function, the constructor and prototype chain of the time calling function are forced to return a predefined fixed timestamp.
5. The differential fuzz testing method for the JIT compiler in the JS engine according to claim 4, characterized in that: The isolating the global object in the first test case includes: The global object is frozen using a static function to fix the property value of the global object.
6. The differential fuzz testing method for the JIT compiler in the JS engine according to claim 5, characterized in that: The performing consistency testing on the interpretation and execution results obtained after multiple executions to obtain a consistency test result corresponding to the second test case includes: If the interpretation and execution results obtained after any two executions are different, the consistency detection result is determined to be inconsistent; otherwise, the consistency detection result is determined to be consistent.
7. The differential fuzz testing method for a JIT compiler in a JS engine according to claim 6, characterized in that: The triggering of the JIT compiler optimization function by using the second test case whose consistency detection result is consistent, and detecting whether an error occurs in the JIT compiler according to the execution results of the second test case before and after the optimization, includes: Obtaining a benchmark prediction for a second test case whose consistency detection result is consistent; the benchmark prediction is an arbitrary interpretation and execution result of the second test case in a bytecode interpreter; Execute the second test case whose consistency detection result is consistent by using a JIT compiler to obtain a compilation execution result; It is determined whether the benchmark prediction is the same as the compilation execution result. If they are not the same, it is determined that an error occurs in the JIT compiler; otherwise, it is determined that no error occurs in the JIT compiler.
8. The differential fuzz testing method for a JIT compiler in a JS engine according to claim 5, characterized in that: The static function is a global object freezing function or a property fixing function.
9. A terminal device comprising a memory, a processor, and a computer program stored in the memory and executable on the processor, wherein: When the processor executes the computer program, the method according to any one of claims 1 to 8 is implemented.
10. A computer-readable storage medium storing a computer program, characterized in that: When the computer program is executed by a processor, the method according to any one of claims 1 to 8 is implemented.