A data stream analysis and memory vulnerability detection method based on lazy merge

CN122926435APending Publication Date: 2026-10-16NANJING UNIV
View PDF 0 Cites 0 Cited by

Patent Information

Application Number
CN202611005523.4
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2026-07-07
Publication Date
2026-10-16

AI Technical Summary

Technical Problem

因此,本发明提供一种基于惰性合并的数据流分析和内存漏洞检测方法,是一种时空高效的流敏感指针分析方法,能够在保持流敏感分析精度的前提下高效处理大规模程序,以解决现有数据流分析技术中空间开销过大、时间效率低下以及精度与效率难以兼顾的问题

Benefits of technology

指针分析模块是本发明的核心模块,实现了时空高效的流敏感指针分析。该模块采用稀疏程序状态表示技术,在每个程序点处仅存储相对于上一程序点的状态变化量,而非完整的程序状态映射,从而将空间复杂度从传统的O(N×|Obj|)降低至O(N)。模块定义了可达定义函数,通过在控制流图上进行深度优先搜索动态计算指针指向关系,避免了预计算和传播完整程序状态的开销。基于该可达定义函数,模块针对分配语句、取址语句、赋值语句、存储语句和加载语句分别设计了新型迁移函数,使迁移函数不依赖前驱程序点的完整状态,而依赖可达定义函数的查询结果。模块还实现了改进的worklist迭代算法,当程序状态发生变化时,仅将可能被影响的使用该定义对象的语句放入工作队列,通过精确的依赖分析避免了大量冗余的节点重处理。

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN122926435A_ABST
    Figure CN122926435A_ABST
Patent Text Reader

Abstract

The application discloses a data stream analysis and memory leak detection method based on lazy merging, and belongs to the technical field of computer software security. The method optimizes the propagation of useless redundant data in the existing stream sensitive pointer analysis based on a lazy merging strategy, quickly and efficiently constructs a stream sensitive pointing relationship, and realizes memory leak, release after use, multiple release and other memory leak detectors on the basis of the data stream analysis, thereby avoiding excessive memory occupation of the analyzer on the premise of preserving accuracy, and realizing rapid analysis. The application supports real-time memory safety monitoring of C / C++ programs and the like under extremely low memory overhead, and does not significantly reduce the detection coverage of typical vulnerabilities such as memory leak and use of released memory. The experimental results show that the application has excellent stability and resource utilization when processing numerous open source projects, and can be seamlessly integrated into the existing LLVM or GCC compilation chain.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This invention belongs to the field of computer software security technology, and in particular relates to static program analysis technology related to memory vulnerabilities. Specifically, it is a data flow analysis and memory vulnerability detection method based on lazy merging, which is suitable for improving the space efficiency and memory utilization of flow-sensitive data flow analysis, and can be applied to memory error detection. Background Technology

[0002] Memory errors are a significant factor affecting software security and stability. Memory vulnerabilities such as use-after-free, memory leaks, double-free, and buffer overflows can be exploited by attackers, leading to serious consequences such as program crashes, data corruption, and even remote code execution. In recent years, security incidents caused by memory errors have become increasingly common; for example, the Heartbleed vulnerability stemmed from out-of-bounds access to a memory buffer, posing a significant threat to global internet security. Therefore, effectively detecting and preventing memory errors has become a core issue that urgently needs to be addressed in the field of software security.

[0003] Static program analysis, as a core technology for detecting memory errors, can discover potential vulnerabilities by analyzing program code without executing the program. It can perform a comprehensive and systematic security assessment of the code without constructing test cases or running the program, making it an important means of ensuring software security. However, static analysis faces an inherent contradiction between accuracy and efficiency: overly conservative analysis will produce a large number of false positives, while overly precise analysis may lead to exponential computational overhead.

[0004] Stream-sensitive pointer analysis is a key technique in static program analysis. It tracks the memory objects that pointer variables might point to at each program point, thus accurately describing alias relationships within the program. This fine-grained context awareness allows the analyzer to distinguish between different objects that the same pointer variable might point to at different program locations, providing a solid foundation for subsequent memory error detection. Based on this precise pointing information, the analyzer can further detect various memory errors such as memory leaks, reuse after free, and double-free. However, stream-sensitive pointer analysis faces dual challenges of space and time efficiency in engineering practice, which limits its widespread application in real-world large-scale software analysis.

[0005] In terms of space efficiency, traditional data flow analysis employs a tightly coupled state storage model, requiring the storage of a complete program state mapping at each program point. For pointer analysis, program state is a mapping from memory objects to the objects they might point to, and this mapping grows exponentially with program complexity. Taking a large-scale program with hundreds of thousands of program points as an example, even if only the pointer relationship of a single local variable changes, the analyzer still needs to store and propagate the complete state data for all program points. This redundant storage mechanism causes memory consumption to balloon with program size, creating a severe storage bottleneck. More importantly, when analyzing large enterprise-level codebases or open-source projects, limited main memory capacity often cannot accommodate such a massive state space, making flow-sensitive analysis unsustainable in practice.

[0006] In terms of time efficiency, the traditional Worklist iterative algorithm employs a coarse-grained event-driven mechanism. When the program state changes, all successor nodes of that node are unconditionally added to the work queue for re-analysis. This naive scheduling strategy ignores data dependencies between statements, leading to the repeated processing of a large number of nodes unrelated to the current update. Furthermore, for programs with loop structures, the Worklist algorithm may require multiple iterations to converge, with each iteration potentially introducing redundant computation. In the worst case, the algorithm's computational complexity can reach [a certain value]. Even higher, where n is the program size. This efficiency bottleneck means that flow-sensitive pointer analysis often requires hours or even days of computation time when processing real code, severely limiting its practical application in engineering.

[0007] Traditional sparse value flow analysis techniques trace value evolution by constructing value flow graphs. While this reduces redundant computation to some extent, its over-reliance on flow-insensitive pointer analysis as a foundation necessitates iterative refinement of pointer relationships during graph construction to approximate flow-sensitive precision. This coupled approach weakens the modular structure of software and increases development costs. The mechanism of storing the complete program state at each program point in traditional data flow analysis leads to a sharp increase in memory consumption with program size, making it unsuitable for large-scale programs containing hundreds of thousands of program points. Furthermore, the traditional Worklist iterative algorithm employs a coarse-grained scheduling strategy, ignoring data dependencies between statements, resulting in the repeated processing of numerous unnecessary nodes and hindering efficiency improvements. Moreover, existing sparse analysis methods often sacrifice accuracy in pursuit of efficiency, struggling to accurately handle complex pointer operations and alias relationships. Summary of the Invention

[0008] Purpose of the Invention: Given the problems and shortcomings of existing technologies, obtaining flow-sensitive pointer analysis results directly with lower overhead in the early stages, and then constructing a value flow graph based on these results, could potentially achieve better analysis results. Therefore, this invention provides a data flow analysis and memory vulnerability detection method based on lazy merging. This is a time- and space-efficient flow-sensitive pointer analysis method that can efficiently process large-scale programs while maintaining the accuracy of flow-sensitive analysis. It addresses the problems of excessive space overhead, low time efficiency, and the difficulty in balancing accuracy and efficiency in existing data flow analysis techniques.

[0009] This invention proposes a sparse program state representation, reachability definition functions, and a dependency-based precise scheduling strategy. While maintaining the accuracy of flow-sensitive analysis, it significantly reduces space complexity and time overhead. Furthermore, it enables accurate memory error detection based on this efficient pointer analysis, including typical memory vulnerabilities such as memory leaks, double-freeing, and use after freeing.

[0010] Technical solution: A data flow analysis and memory vulnerability detection method based on lazy merging, comprising the following steps: Step 1, Construct Control Flow Graph: Analyze the target program and construct the program's control flow graph (CFG), where nodes represent basic program blocks and edges represent control flow transitions; Step 2, define sparse program state representation: at each program point, only the change in program state relative to the previous program point is stored, not the complete program state. The program state at program point v is denoted as... For pointer analysis, It represents a change in pointer relationship relative to the previous program point, and is a mapping relationship from memory object to a collection of memory objects; Step 3, Define the reachable function and pointing relation function For object o at program point v, Returns all values ​​that can flow to object o at program point v, starting from the program entry point; for pointer analysis, Record It returns the set of all reachable objects that object o may point to from the program entry point to program point v; Step 4: Design transition functions based on reachability definitions: Design new transition functions for allocation, load, and store statements in pointer analysis, so that the transition functions do not depend on the complete program state of the predecessor program point, but depend on the reachability definition function. In pointer analysis, it is ; Step 5, construct an improved Worklist iterative algorithm: when the program state changes at a certain program point, only the statements that may be affected are put into the work queue; Step 6, Perform data flow analysis: Run the improved Worklist iterative algorithm until the program point is stationary, and obtain the flow-sensitive pointer relationships at each program point; Step 7: Construct a Value Flow Graph (VFG) based on the flow-sensitive pointer relationships: The VFG tracks which control flow paths each pointer value flows through to an object o; the VFG adds path information to flow-sensitive pointer analysis. Step 8: Traverse each instruction to detect memory leaks: When traversing to the `free(ptr)` or `delete ptr` statement, record that the object pointed to by `ptr` has been released on the corresponding control flow path. At the same time, check whether the object pointed to by `ptr` has already been released. If it has been released, report double free. When traversing to the `*ptr / ptr->field / ptr[i]` statement, check whether the object pointed to by `ptr` has already been released. If it has been released, report use afterfree. After traversing the entire function, check whether all heap objects that have not escaped have been released on all paths. If there are any paths that have not been released, report memory leaks.

[0011] Obtaining the flow-sensitive pointer relationship at each program point is a specific application scenario of data flow analysis. For the sake of convenience, this invention uses pointer analysis as a specific application scenario of data flow analysis for introduction. However, the method provided by this invention is actually applicable to general data flow analysis problems.

[0012] The sparse program state representation method described in step 2 is used to model the memory state during program execution. Specifically, a key-value pair set is used as the state representation structure, where the key represents the identifier of a memory object or pointer variable, and the value represents the set of target objects pointed to by that memory object at the current program point. During program execution or data flow propagation, the object and its updated set of pointers are only recorded in the state representation when the pointer relationship of a memory object changes; for objects that have not changed, their state is not explicitly stored repeatedly, and their pointer relationship at previous program points is used by default. Through this method, a sparse state representation of program pointer relationships is achieved, thereby reducing the storage and updating overhead of redundant state information and providing an efficient state foundation for subsequent pointer-based data flow analysis and memory vulnerability detection.

[0013] A data flow analysis and memory vulnerability detection system based on lazy merging includes the following modules: (1) Front-end module The front-end module is responsible for converting the source code of the target program into an intermediate representation suitable for static analysis. This invention employs an MLIR-based front-end, capable of compiling C / C++ programs while preserving rich high-level semantic information, including variable names, structure field names, and scope information. The generated intermediate representation uses SSA format, facilitating subsequent data flow analysis. The front-end module is also responsible for constructing the program's control flow graph, identifying the program's basic block structure by traversing the intermediate representation, and annotating control flow features such as loops and back edges. After constructing the control flow graph, the module performs dead code elimination, removing nodes unreachable from the program's entry point to improve the efficiency of subsequent analysis.

[0014] (2) Pointer Analysis Module The pointer analysis module is the core module of this invention, realizing time- and space-efficient flow-sensitive pointer analysis. This module employs sparse program state representation technology, storing only the state change relative to the previous program point at each program point, rather than a complete program state mapping, thereby reducing the space complexity from the traditional O(N×|Obj|) to O(N). The module defines reachability definition functions. By dynamically calculating pointer relationships through depth-first search on the control flow graph, the overhead of pre-computing and propagating the complete program state is avoided. Based on this reachable definition function, the module designs novel transition functions for allocation, fetch, assignment, store, and load statements, making the transition functions independent of the complete state of the predecessor program point, but dependent on the query results of the reachable definition function. The module also implements an improved worklist iteration algorithm, which, when the program state changes, only adds statements that may be affected by using the defined object to the work queue, avoiding a large amount of redundant node reprocessing through precise dependency analysis.

[0015] (3) Analyzer module The analyzer module performs memory error detection based on the flow-sensitive pointer relationships obtained from the pointer analysis module. First, it constructs a value flow graph based on the pointer analysis results. Nodes in the value flow graph represent pairings between program points and objects, and edges represent the flow of values. Based on the value flow graph, the module traces the set of release paths for each heap memory object. For memory leak detection, the module calculates all subsequent control flow paths for each allocation point and performs a difference operation with the set of release paths to determine if a leaky path exists. For double-free detection, the module calculates the intersection of the current release path and the set of existing release paths at each release operation, determining if there is a duplicate release on the intersection path. For use after release detection, the module determines whether the memory access path overlaps with the release path and whether the access occurred after the release point. The analyzer module also supports inter-function analysis, enabling cross-function memory error detection by constructing and instantiating function summaries. Finally, the module outputs the analysis results in a structured format for use by users or downstream tools.

[0016] A computer device includes a memory, a processor, and a computer program stored in the memory and executable on the processor. When the processor executes the computer program, it implements the steps of the data flow analysis and memory vulnerability detection method based on lazy merging described above.

[0017] A computer-readable storage medium having a computer program / instructions stored thereon, which, when executed by a processor, implements the steps of the lazy-merging-based data flow analysis and memory vulnerability detection method described above.

[0018] Beneficial effects: Compared with existing memory vulnerability detection technologies, the data flow analysis and memory vulnerability detection method based on lazy merging provided by this invention has the following significant advantages: (1) Significantly improved space efficiency: This invention reduces the space complexity of flow-sensitive pointer analysis from the traditional N×|Obj| or N×|Obj|×|Obj| to O(N) through sparse program state representation technology. When processing large-scale programs, this improvement enables the analyzer to complete analysis tasks that were originally impossible to execute with limited memory resources, effectively solving the memory bottleneck problem faced by traditional flow-sensitive analysis on large code bases.

[0019] (2) Significantly Improved Time Efficiency: This invention eliminates a large number of redundant propagation operations in traditional data flow analysis by using reachability definition functions and an improved Worklist algorithm with precise dependency scheduling. Each iteration only processes the changed parts, rather than unconditionally reprocessing all successor nodes, significantly reducing computational overhead. Experimental results show that this invention can analyze programs with millions of lines of code in minutes, demonstrating good practicality.

[0020] (3) High detection accuracy is maintained: While improving spatiotemporal efficiency, this invention fully retains the accuracy of flow-sensitive analysis. Data flow information can still be accurately obtained at each program point, supporting path-sensitive memory error detection. Experimental results on the Juliet test set show that this invention achieves a detection accuracy of 91.3% and a false positive rate of less than 10%. It also exhibits the characteristics of low false positive rate and high detection rate in real open source projects.

[0021] (4) Significant Industrial Application Potential: This invention is based on the LLVM MLIR framework and can be seamlessly integrated into existing LLVM or GCC compilation chains, supporting convenient interface with existing development toolchains. The system supports function-level parallel analysis and achieves efficient parallel scheduling through call graph guidance, making full use of multi-core processor resources. Experiments on well-known open-source projects such as Git and FFmpeg have verified the effectiveness of the method, detected several previously unknown memory vulnerabilities and obtained confirmation from developers, demonstrating significant industrial application value. Attached Figure Description

[0022] Figure 1 This is a general flowchart of an embodiment of the present invention. Detailed Implementation

[0023] The present invention will be further illustrated below with reference to specific embodiments. It should be understood that these embodiments are for illustrative purposes only and are not intended to limit the scope of the invention. After reading the present invention, any modifications of the present invention in various equivalent forms by those skilled in the art will fall within the scope defined by the appended claims.

[0024] Based on lazy merging, this data flow analysis and memory vulnerability detection method has advantages such as sparse value flow analysis, path-sensitive pointer analysis, and function-level parallel analysis. It can achieve high-precision detection of memory errors such as memory leaks, double frees, and use after free while maintaining low space overhead and high time efficiency.

[0025] A data flow analysis and memory vulnerability detection method based on lazy merging includes the following steps: Step 1, Construct Control Flow Graph: Analyze the target program and construct the program's control flow graph (CFG), where nodes represent basic program blocks and edges represent control flow transitions; Step 2, define sparse program state representation: at each program point, only the change in program state relative to the previous program point is stored, not the complete program state. The program state at program point v is denoted as... For pointer analysis, It represents a change in pointer relationship relative to the previous program point, and is a mapping relationship from memory object to a collection of memory objects; Step 3, Define the reachable function and pointing relation function For object o at program point v, Returns all values ​​that can flow to object o at program point v, starting from the program entry point; for pointer analysis, Record It returns the set of all reachable objects that object o may point to from the program entry point to program point v; Step 4: Design transition functions based on reachability definitions: Design new transition functions for allocation, load, and store statements in pointer analysis, so that the transition functions do not depend on the complete program state of the predecessor program point, but depend on the reachability definition function. In pointer analysis, it is ; Step 5, construct an improved Worklist iterative algorithm: when the program state changes at a certain program point, only the statements that may be affected are put into the work queue; Step 6, Perform data flow analysis: Run the improved Worklist iterative algorithm until the program point is stationary, and obtain the flow-sensitive pointer relationships at each program point; Step 7: Construct a Value Flow Graph (VFG) based on the flow-sensitive pointer relationships: The VFG tracks which control flow paths each pointer value flows through to an object o; the VFG adds path information to flow-sensitive pointer analysis. Step 8: Traverse each instruction to detect memory leaks: When traversing to the `free(ptr)` or `delete ptr` statement, record that the object pointed to by `ptr` has been released on the corresponding control flow path. At the same time, check whether the object pointed to by `ptr` has already been released. If it has been released, report double free. When traversing to the `*ptr / ptr->field / ptr[i]` statement, check whether the object pointed to by `ptr` has already been released. If it has been released, report use afterfree. After traversing the entire function, check whether all heap objects that have not escaped have been released on all paths. If there are any paths that have not been released, report memory leaks.

[0026] Obtaining the flow-sensitive pointer relationships at each program point is a specific application scenario of the data flow analysis. For the sake of convenience, this invention uses pointer analysis as a specific application scenario of data flow analysis for introduction. However, the method provided by this invention is actually applicable to general data flow analysis problems.

[0027] The sparse program state representation described in step 2 uses a set of key-value pairs, which only records the modified memory objects and their new values. The program state space complexity corresponding to each statement is O(1).

[0028] The source code is compiled into an IR using a C / C++-designed MLIR frontend (vast-front). This IR preserves all high-level semantic information of C / C++, with a tree-like structure similar to a syntax tree. While it lacks the properties of traditional control flow graphs (single entry, single exit), it preserves high-level semantics such as scope and expression evaluation order, and possesses an SSA (Static Single Assignment) structure, making it suitable for precise pointer analysis. Furthermore, MLIR employs a multi-layered intermediate representation design, supporting different levels of abstraction, facilitating customized analysis for specific domains. As a C / C++ MLIR frontend, vast-front can completely migrate complex C / C++ semantics into the MLIR system, providing high-quality input for subsequent flow-sensitive pointer analysis.

[0029] Analyzing the Ingress Graph (IR) yields the control flow graph, and dead code is removed using a dead code elimination algorithm. The control flow graph is fundamental to data flow analysis. Since the IR stores all semantic information and its structure is similar to a syntax tree, converting the IR into a control flow graph only requires a depth-first traversal of the IR (not considering control flow graphs with cross-function exceptions). During the depth-first traversal of the IR, in addition to obtaining the control flow graph, loop structures can be easily identified and labeled on it. After obtaining the control flow graph, traversal begins from the program entry block, removing all nodes unreachable from the entry block to facilitate subsequent analysis.

[0030] Pointer analysis based on lazy merging is performed on the control flow graph in topological order (removing loop back edges). Analyzing basic blocks in topological order is to quickly reach fixed points. The core idea of ​​lazy merging is that the states of predecessor basic blocks are not immediately merged at the entry point of a basic block, as merging states requires taking the union of all predecessor basic blocks, resulting in significant space waste. To avoid waste and improve performance, lazy merging is delayed until the actual pointer relationship needs to be queried. For the improved pointer analysis of this invention, it is necessary to design each instruction statement to cause a separate program state. What changes occurred (transfer function)? Also, since the transfer function needs to query the pointer variable x's pointer relationship, what is the program state at the current program point? The state information of the predecessor basic block is not preserved, so a function needs to be defined. Lazy lookup is used to obtain the set of objects that x might point to by traversing the CFG backwards from program point v. Finally, the basic blocks affected by the program state change caused by the current statement are not limited to successor basic blocks, so the traditional algorithm that only adds successor nodes to the work queue is no longer applicable. The transition function and the improved Worklist algorithm are introduced below.

[0031] (1) Each instruction executes a transition function to create the program state for the current program point. In the following formula, Represents the transfer function. This indicates the creation of a mapping relationship, which will... Mapping This means that a points to b. In pointer analysis, This indicates the creation of a new program state in which a points to b; *a indicates dereferencing a, that is, retrieving the object that a points to; Indicates that the program state has been found. The mapping of x, i.e., if the program state If x is included, then It will return all objects that x points to; This represents the program state at program point w. The following are the instructions and transition functions related to pointer analysis: Assign x = new type: ,in This represents a newly created heap memory object; Address y = &x: ; Assigning x = y: ; Store *x = y: ,in The storage instruction means that a weak update operation has occurred, that is, the object pointed to by *x and the object pointed to by y are merged and stored in *x; Load x = *y: The load instruction means loading all objects that y points to. All the objects they point to are merged and placed into object x; As can be seen, the transfer function no longer requires the program state of the predecessor basic block as input, unlike traditional data flow analysis. Therefore, it no longer propagates irrelevant states from the program state of the predecessor basic block. In contrast, the transfer function in traditional data flow analysis is... Indicates reservation In all states, only change the pointer relationship of 'a' to point to 'b': Assign x = new type: ; Address y = &x: ; Assigning x = y: ; Store *x = y: ,in ; Load x = *y: .

[0032] Merging predecessor basic block program status: The transfer function has a basically the same form, but the improved algorithm no longer propagates irrelevant states, which significantly reduces space and time complexity. However, due to... It only contains the changed parts and cannot be passed through. Find the pointer relationship of x at a given point in the program. To solve this problem, define a function. to replace , For all basic blocks on CFG Perform a search and return all objects that x may point to at point v. The definition is as follows: Define function This indicates that there exists a reverse path in the CFG from basic block w to program point v, and that there are no other definitions of pointer o on this path (other than w), specifically satisfying the following conditions: 1) w is a basic block in CFG, and w contains the definition of pointer o; 2) If w = v, then True; 3) If there exists an edge from basic block u to basic block v (i.e., u is the predecessor of v), and there are no other definitions of pointer o before v on the path, and If true, then True; 4) Only the relationships derived from the above rules are valid.

[0033] The function can be implemented by performing a reverse depth-first traversal at program point v: starting from v, recursively search along the predecessor edge of CFG, record the definition of pointer o encountered on the traversal path, and stop the search of the path if a new definition is encountered.

[0034] It can be proven that if the order of each iteration is consistent, the results of traditional data flow analysis and the improved data flow analysis are the same. Clearly, the improved transfer function and... Since they are all monotonic, the iterative algorithm will eventually reach the minimum fixed point.

[0035] (2) After executing the transfer function of an instruction, put the statements affected by the instruction into the work queue. In traditional dataflow methods, only the program state of the predecessor basic block is needed. If it remains unchanged, then the program state at the entry and exit points corresponding to the basic block being analyzed will also remain unchanged. However, the improved transfer function depends on... The basic blocks involved in this process mean that the traditional worklist algorithm for data flow analysis is no longer applicable. To adapt to the improved data flow analysis algorithm, we define the instructions that a single instruction might affect as follows: if an instruction changes the pointer relationship of 'o', then the affected instructions are: assigning x = 'o', storing *o = y, or *x = y and... Load x = *o, or x = *y and After executing a statement, the transition function should iterate through all potentially affected instructions in the work queue. In practice, without executing the fixed-point algorithm, simply analyzing each basic block once is sufficient to achieve good accuracy.

[0036] This invention constructs a value flow graph based on the flow-sensitive pointer relationships and performs memory error detection. The value flow graph is a core data structure built upon the control flow graph, used to represent the flow of values ​​in a program. A node in the value flow graph represents an object at a program point, and each value flow edge represents the flow of value from an object at one program point to an object at another program point. When constructing the value flow graph, for allocation statements, edges are directly established from the heap allocation node to the target object; for assignment statements such as x=y, edges are established from the definition point of y to the definition point of x; for dereference assignment statements such as *x=y, it is necessary to traverse the pointer sets of x and y to establish corresponding indirect flow edges; for dereference load statements such as x=*y, it is necessary to traverse the pointer set of y and its internal pointers to establish deeper value flow relationships. To support path-sensitive memory error detection, this invention attaches path information to the value flow edges, abstracting the path as a set of edges on a directed acyclic graph of control flow. This lightweight path abstraction method can both retain key path-sensitive information and avoid the exponential complexity of exhaustively verifying all execution paths.

[0037] Memory leak detection, based on the value flow graph, can determine which paths each heap object was freed on at each program point. The principle behind memory leak detection is: at the end of a function, check whether each non-escaped heap object was freed on all paths from the allocation point to the deallocation point. The principle behind double leak detection (calling the free function twice on the same object 'o') is: when analyzing the free instruction `free(o)`, check if there is any overlap between the path where 'o' has already been freed and the current free path. The principle behind detecting post-free usage is: when analyzing statements using 'o', check if there is any overlap between the path where 'o' has already been freed and the current usage path.

[0038] The following are the specific implementation steps.

[0039] (1): The compiler commands in the build commands (make, cmake, ninja) captured by the open-source project whllvm are replaced with the front-end commands used in this embodiment to compile the source code into an IR file. This invention uses the MLIR-based vast-front front-end to compile C / C++ source code into an intermediate representation that preserves high-level semantic information. This intermediate representation adopts the SSA form and saves all high-level semantic information of C / C++, including variable names, structure field names, scope, etc. During the compilation process, an index thin file is also created for the definition location of each global symbol for subsequent symbol resolution and cross-file analysis.

[0040] (2): The analysis thread is started in parallel for each function, from the callee to the caller. This invention designs a function-level parallel analysis framework, which is transformed into a directed acyclic graph of calls by constructing a call graph and removing loops. The analysis threads are scheduled according to the reverse topological order of the call graph, ensuring that the analysis of the called function is completed before the calling function. Each function maintains an independent summary database to record the analysis results of the function for use by the caller. Through this design, multiple functions can be analyzed in parallel, while ensuring the correctness of the dependencies between functions.

[0041] (3): Construct the CFG and run optimization passes such as DCE. Based on the IR file generated in step 1, identify the control flow statements in the program and divide them into basic blocks, constructing control flow edges between the basic blocks. Run the loop-info pass to traverse the control flow graph and identify natural loop structures, including loop entry nodes, loop back edges, loop latch nodes, and loop header nodes, etc., maintaining the hierarchical structure information of each loop to provide loop-related program structure knowledge for subsequent analysis. Execute optimization passes such as dead code elimination (DCE) to remove nodes that are unreachable from the program entry point, reducing the amount of analysis required for subsequent analysis.

[0042] (4): Pointer Analysis and Value Flow Graph Construction. Flow-sensitive pointer analysis is performed using sparse program state representation techniques, storing only the state change relative to the previous program point at each program point. This is based on reachable definition functions. Dynamically calculate pointer relationships and return all reachable definitions from the program entry point to the target program point through a depth-first search on the control flow graph. Based on pointer analysis, a value flow graph is constructed, where value flow graph nodes represent pairings between program points and objects, and edges represent the flow of values. Path information is appended to the value flow edges, and paths are abstracted into sets of control flow edges to achieve lightweight path-sensitive analysis.

[0043] (5): Memory error detection is performed by calling a special analyzer as needed. Based on the results of value flow graph and flow-sensitive pointer analysis, memory errors such as memory leaks, double-frees, and use after free are detected. Memory leak detection is performed by tracing the control flow path after heap memory allocation to determine if there is a leak path that does not reach the free operation. Double-free detection is performed by determining if there is a duplicate free on the intersection of free paths. Use after free detection is performed by determining if there is an overlap between the memory access path and the free path. For memory errors across functions, context passing and instantiation analysis between the caller and the callee are implemented through a function digest mechanism.

[0044] (6): Print the source code corresponding to the error message. After analysis, the system outputs the detected memory errors, including the error type, the source code file and line number corresponding to the error location, and related control flow path information. The system outputs the potentially vulnerable source code and context in text form to help developers quickly locate and fix memory vulnerabilities.

[0045] The main functions of the system are as follows: Frontend and IR Generation Module: This module receives source code and converts it into an intermediate representation suitable for static analysis. It integrates the MLIR-based vast-front compiler, capable of compiling C / C++ source code into HighLevel dialect IR that preserves high-level semantics. HighLevel dialects retain important information from the original code, such as variable names, structure field names, and function pointer semantics, which are often lost in traditional LLVM IR. This module also constructs symbol indexes, creating definition location indexes for each global symbol, supporting global analysis and symbol resolution across files. During compilation, the module automatically identifies and replaces compilation commands in build systems such as make, cmake, and ninja, without requiring manual user intervention.

[0046] Pointer Analysis and Value Flow Graph Construction Module: This module implements the core innovation of this invention—a method based on lazy merging and data flow analysis. The module employs sparse program state representation, storing only the state change relative to the previous program point at each program point, reducing space complexity from O(N×|Obj|) to O(N). The module defines reachability definition functions. By dynamically finding the reachability definition of objects on the control flow graph through depth-first search, the overhead of pre-computing and propagating the complete program state in traditional methods is avoided. Based on this function, the module designs improved transition functions for five types of pointer operation statements. Furthermore, the module constructs a value flow graph based on the pointer analysis results, abstracting path information into a set of control flow edges to achieve lightweight path sensitivity, maintaining accuracy while avoiding the exponential overhead of path exhaustion.

[0047] The memory error detection and analysis result output module performs three types of memory error detection based on pointer analysis and value flow graph construction. Memory leak detection determines the existence of leaks by comparing the difference between the set of successor paths and the set of free paths in the heap memory. Double free detection identifies multiple frees of the same memory by calculating the intersection of free paths and comparing node out-degrees. Post-free use detection detects access behavior after free by judging the overlap between memory access paths and free paths. This module also supports inter-function analysis, achieving cross-function memory error tracing by maintaining a function summary database that records parameter aliases, allocation and release information, and residual pointers. Analysis results are printed in a structured format through a unified output interface, including detailed information such as source code location, control flow path, and error type, and supports integration with external tools.

[0048] The system implementation process and methods are the same, and will not be described in detail here. Obviously, those skilled in the art should understand that the steps of the memory vulnerability detection method based on lazy merging and data flow analysis, or the modules of the memory vulnerability detection system based on lazy merging and data flow analysis, as described in the above embodiments of the present invention, can be implemented using general-purpose computing devices. They can be centralized on a single computing device or distributed across a network of multiple computing devices. Optionally, they can be implemented using device-executable program code, thereby storing them in a storage device for execution by a computing device. In some cases, the steps shown or described can be performed in a different order than those presented here, or they can be fabricated as separate integrated circuit modules, or multiple modules or steps can be fabricated as a single integrated circuit module. Thus, the embodiments of the present invention are not limited to any particular hardware and software combination.

Claims

1. A data flow analysis and memory vulnerability detection method based on lazy merging, characterized in that, Includes the following steps: Step 1, Construct Control Flow Graph: Analyze the target program and construct the program's control flow graph (CFG), where nodes represent basic program blocks and edges represent control flow transitions; Step 2, define sparse program state representation: at each program point, only the change in program state relative to the previous program point is stored, not the complete program state. The program state at program point v is denoted as... For pointer analysis, It represents a change in pointer relationship relative to the previous program point, and is a mapping relationship from memory object to a collection of memory objects; Step 3, Define the reachable function and pointing relation function For object o at program point v, Returns all values ​​that can flow to object o at program point v, starting from the program entry point; for pointer analysis, Record It returns the set of all reachable objects that object o may point to from the program entry point to program point v; Step 4: Design transition functions based on reachability definitions: Design new transition functions for allocation, load, and store statements in pointer analysis, so that the transition functions do not depend on the complete program state of the predecessor program point, but depend on the reachability definition function. In pointer analysis, it is ; Step 5, construct an improved Worklist iterative algorithm: when the program state changes at a certain program point, only the statements that may be affected are put into the work queue; Step 6, Perform data flow analysis: Run the improved Worklist iterative algorithm until the program point is stationary, and obtain the flow-sensitive pointer relationships at each program point; Step 7: Construct a Value Flow Graph (VFG) based on the flow-sensitive pointer relationships: The VFG tracks which control flow paths each pointer value flows through to an object o; the VFG adds path information to flow-sensitive pointer analysis. Step 8, iterate through each instruction to detect memory vulnerabilities: When iterating to the free(ptr) or delete ptr statement, record that the object pointed to by ptr has been released on the corresponding control flow path, and check whether the object pointed to by ptr has already been released. If it has been released, report double release; when iterating to the *ptr / ptr->field / ptr[i] statement, check whether the object pointed to by ptr has already been released. If it has been released, report that it was used after release. After traversing the entire program, check whether all un-escaped heap objects have been released on all paths. If any un-released paths exist, report a memory leak.

2. The data flow analysis and memory vulnerability detection method based on lazy merging according to claim 1, characterized in that, The target program is parsed, its source code is compiled into an IR (Inverse Relationship), the IR is analyzed to obtain a control flow graph, and dead code is removed through DCE (Distributed Code Elimination).

3. The data flow analysis and memory vulnerability detection method based on lazy merging according to claim 1, characterized in that, The sparse program state representation method described in step 2 is used to model the memory state during program execution. A key-value pair set is used as the state representation structure, where the key represents the memory object or pointer variable identifier, and the value represents the set of target objects pointed to by the memory object at the current program point. During program execution or data flow propagation, the object and its updated set of pointers are only recorded in the state representation when the pointer relationship of a memory object changes. For objects that have not changed, their state is not explicitly stored again, but their pointer relationship at the previous program point is used by default.

4. The data flow analysis and memory vulnerability detection method based on lazy merging according to claim 1, characterized in that, The reachable definition function described in step 3 Implemented using a depth-first search algorithm on the control flow graph, it is defined as follows: in Represents the set of objects that object o points to at program point w. Reachable(o, w, v) is true if and only if the definition of object o can flow from w to v.

5. The data flow analysis and memory vulnerability detection method based on lazy merging according to claim 1, characterized in that, The reachability-based transfer function mentioned in step 4 includes: For the operation x = new type: ; For the operation y = &x: ; For the operation x = y: ; For the operation *x = y: ,in ; For the operation x = *y: .

6. The data flow analysis and memory vulnerability detection method based on lazy merging according to claim 1, characterized in that, In the improved Worklist iteration algorithm described in step 5, when object o changes in the program state, the statements that may be affected by using object o include: An assignment statement of type y = o; The dereference assignment statement y = *x is used, where... ; An assignment statement of type *x = y, where .

7. The data flow analysis and memory vulnerability detection method based on lazy merging according to claim 1, characterized in that, The improved Worklist iterative algorithm satisfies monotonicity, meaning that in each iteration... The program state of the entire control flow graph is monotonically increasing, thus ensuring the algorithm terminates.

8. The data flow analysis and memory vulnerability detection method based on lazy merging according to claim 1, characterized in that, It also includes memory error detection based on the flow-sensitive pointer relationship obtained in step 6, including: memory leak detection: tracing all control flow paths after heap memory allocation to determine if there are any leaky paths that have not reached the release operation; double release detection: when performing a release operation, determining whether the current release path intersects with the recorded release path, and reporting a double release if there are already released nodes on the intersecting path; and use after release detection: when performing a memory access operation, determining whether the release path and access path of the accessed memory overlap, and reporting use after release if access occurs on the path after release.

9. A computer device, characterized in that: The computer device includes a memory, a processor, and a computer program stored in the memory and executable on the processor. When the processor executes the computer program, it implements the steps of the data flow analysis and memory vulnerability detection method based on lazy merging as described in any one of claims 1-8.

10. A computer-readable storage medium having a computer program / instructions stored thereon, characterized in that: When the computer program / instruction is executed by the processor, it implements the steps of the data flow analysis and memory vulnerability detection method based on lazy merging as described in any one of claims 1-5.