A method for analyzing memory safety in C code using data flow analysis algorithm
Through data flow analysis algorithm and static single-valued assignment technology, memory security analysis of C code is solved, and the problem of difficulty in detecting memory security issues in the existing technology is solved, and effective detection and prevention of memory leaks, cross-border problems are achieved.
Patent Information
- Application Number
- CN202111201254.6
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2021-10-15
- Publication Date
- 2025-04-29
- Estimated Expiration
- 2041-10-15
AI Technical Summary
It is difficult for the prior art to effectively analyze and detect memory security issues in C code, especially in C languages that manually manage memory, which are prone to memory leakage, out-of-bounds and other security issues.
Using the data flow analysis algorithm, the C code is converted into an abstract syntax tree (AST), and static single assignment (SSA) and data flow analysis are performed on it, permission mapping tables are generated, and the legality and security of memory instructions are checked.
It realizes effective detection of memory security issues in C code, can detect memory leaks, out-of-bounds and other security issues, and improves the memory security of the code.
Abstract
Description
Technical Field
[0001] The present invention relates to the field of data flow analysis algorithms and static analysis tool development, and in particular to a method for analyzing memory safety in C code using a data flow analysis algorithm. Background Art
[0002] There are two ways for modern programming languages to recycle memory space on the heap: one is for the user to explicitly call the memory recycling function in the code to manually release the memory; the other is to introduce an automatic garbage collection mechanism. The core of Rust memory management is through ownership, which stipulates that each piece of memory on the heap has only one owner at the same time. Rust uses static analysis methods to accurately analyze the scope of each variable. When the scope of the owner ends, the memory space on the heap will be automatically released; while C needs to manually solve the application and release of memory space on the heap, which is easy to cause many memory safety issues.
[0003] Rust is relatively better than C in terms of memory safety, but most Linux kernel code is written in C and will not be changed to Rust in the short term. Existing analysis technologies include Plural, but it mainly targets Java references. Another memory analysis tool for C is Microsoft's Checked-c, but it targets array or buffer out-of-bounds issues rather than variable ownership. Summary of the invention
[0004] In order to solve the above technical problems, the present invention discloses a method for analyzing memory safety in C code using a data flow analysis algorithm. The technical solution of the present invention is implemented as follows:
[0005] A method for analyzing memory safety in C code using a data flow analysis algorithm defines C language memory instructions as a formalized instruction set, and then performs the following operations:
[0006] Static analysis finds out where the code needs to be marked and adds markers to the corresponding pointers, and automatically adds markers to the code;
[0007] Convert the above code into an abstract syntax tree and perform type checking on each instruction. At the same time, modify the pointer permission transfer or borrowing statements involved to distinguish them from static single assignments.
[0008] Linearize the abstract syntax tree to obtain a control flow graph in the form of a static single assignment, perform data flow analysis, and obtain the result of a converged permission mapping table;
[0009] The data flow analysis algorithm is used to iterate the stable results, and the error checking function is used to check whether there are any memory safety issues.
[0010] Preferably, the pointer includes two types: having ownership and not having ownership.
[0011] Preferably, the instruction set includes memory allocation, memory release, memory ownership transfer, memory ownership borrowing, forced type conversion, pointer leaving scope, instruction fetch, store instruction, merge instruction and function call instruction.
[0012] Preferably, the error detection methods include memory leak detection, multiple release checks, transfer or release checks when borrowed, and use after free.
[0013] Preferably, the abstract syntax tree includes information about function parameters and return values, and based on this, a pointer permission mapping table corresponding to the function is established, and the pointer permission mapping table contains all mappings from variables to the pointer permissions they have.
[0014] Preferably, before analysis, the incoming file is preprocessed, the code of the entire file is traversed, all pointers therein are found and the behavior of the pointers is observed, and whether the pointers have memory allocation or release behavior is analyzed, and different pointer tags are added; if there is memory release or allocation, or the behavior of transferring an owned pointer, it means that it has ownership of a piece of memory, and a tag with ownership should be added to this pointer; otherwise, it is considered that this pointer has only borrowed ownership, and a tag with no ownership is added.
[0015] Preferably, for each function in the abstract syntax tree, for each instruction therein, if it involves ownership transfer, such as transferring a pointer that owns a block of space to another pointer that owns the space, a comment is added that the pointer ownership needs to be transferred; if it involves ownership lending, such as a pointer without ownership borrowing the permissions of another pointer, a comment is added that the pointer ownership is borrowed.
[0016] Preferably, the specific steps of data analysis are as follows:
[0017] Analyze each function one by one and record the permission types of their parameters and return values, that is, whether they have ownership or not;
[0018] If the parameters and return values are owned, the ownership is transferred when the function is called;
[0019] If the parameters and return values are not owned, since the internal situation of the function is unknown, the permission is recorded as "*" when the function is called;
[0020] If it is not a pointer and does not involve a change in ownership, it is recorded as "non-pointer";
[0021] Then, for each instruction involving memory, the transfer equation of the permission mapping table is defined, that is, the pointer permission that a pointer permission may be transformed into after an instruction, as well as the merging operation of different permission mapping tables;
[0022] Convert the abstract syntax tree into a static single assignment and analyze each function separately.
[0023] Preferably, the specific algorithm for memory error checking is as follows:
[0024] (a) Initialize the pointer permission mapping table of the function entry point to the function parameter permissions, and initialize the pointer permission mapping table of the entry point of each other basic block to empty;
[0025] (b) Sequentially analyze each instruction of each basic block, obtain the pointer permission mapping table after the end of an instruction and pass it to the next instruction until the exit of the basic block. At the same time, record whether the pointer permission mapping table of the basic block has changed;
[0026] (c) If the pointer permission mapping table changes, merge the exit pointer permission mapping table of each basic block at the parent node of each basic block and pass it to this block as the entry permission mapping table of the basic block. Repeat operations (b) and (c);
[0027] (d) If the pointer permission mapping table does not change, the iteration ends, and the result obtained at this time is a converged pointer permission mapping table;
[0028] (e) Re-traverse each instruction and the pointer permission mapping table before executing this instruction, and use the memory error detection mechanism to determine whether unsafe behavior occurs.
[0029] The technical solution of the present invention can solve the technical problem that the memory detection technology in the prior art still has drawbacks; the technical solution of the present invention defines a formalized instruction set based on a series of common memory-related instructions in the C language, and defines a series of memory error detection methods, which is convenient for detecting memory security. BRIEF DESCRIPTION OF THE DRAWINGS DETAILED DESCRIPTION
[0030] The technical solutions in the embodiments of the present invention are described clearly and completely below. Obviously, the described embodiments are only part of the embodiments of the present invention, not all of the embodiments. Based on the embodiments of the present invention, all other embodiments obtained by ordinary technicians in this field without creative work are within the scope of protection of the present invention.
[0031] Example
[0032] A method for analyzing memory safety in C code using a data flow analysis algorithm defines C language memory instructions as a formalized instruction set, and then performs the following operations:
[0033] Static analysis is performed to find out where the code needs to add marks to corresponding pointers, and the marks are automatically added to the code; the pointers include two types: owned and non-owned.
[0034] Convert the C code into an abstract syntax tree (AST), perform type checking on each instruction in the AST, and make different modifications to the pointer authority transfer / borrowing statements involved in the AST to distinguish them in the static single assignment (SSA). This step is called annotation.
[0035] Linearize the abstract syntax tree to obtain a control flow graph in the form of a static single assignment, perform data flow analysis, and obtain the result of a converged permission mapping table;
[0036] The data flow analysis algorithm is used to iterate the stable results, and the error checking function is used to check whether there are any memory safety issues.
[0037] This embodiment defines a formalized instruction set based on a series of common memory-related instructions in C language. These include: memory allocation malloc, which allocates a space on the heap for an owned pointer; memory release free, which releases the space on the heap pointed to by the pointer; memory ownership transfer move, which transfers the permission of an owned pointer to another owned pointer; memory ownership borrowing borrow, which temporarily lends the permission of an owned pointer to another unowned pointer; forced type conversion ptrcast, which forces a pointer to be converted into another pointer of a different type; pointer leaving scope dead, which means the scope of a pointer ends and is no longer used; fetch instruction load, which takes out a certain field of a pointer and stores it in another pointer of the same type, and the pointer alias needs to be analyzed at this time; store instruction store, which stores the space of a certain pointer in the same type field of another pointer, and the pointer alias needs to be analyzed at this time; merge instruction phi, the memory space of a certain pointer has multiple sources, namely (phi,1), (phi,2)...; function call instruction call f, which passes the memory space permissions of parameters and return values respectively.
[0038] This instruction set contains the instruction types that may affect the permissions of pointers. During the data flow analysis, each instruction in this instruction set is analyzed.
[0039] Preferably, the error detection methods include memory leak detection, multiple release checks, transfer or release checks when borrowed, and use after free.
[0040] The abstract syntax tree includes information about function parameters and return values, and based on this, a pointer permission mapping table corresponding to the function is established.
[0041] The pointer permission map contains all the mappings from variables to the pointer permissions they have.
[0042] The user passes the C language code to be analyzed as input into the detection system.
[0043] Before analysis, the incoming file is preprocessed, the code of the entire file is traversed, all pointers in it are found and the behavior of the pointers is observed, and whether the pointers have memory allocation or release behavior is analyzed, and different pointer tags are added; if there is memory release or allocation, or the behavior of transferring an owned pointer, it means that it owns a piece of memory, and an ownership tag should be added to this pointer; otherwise, it is considered that this pointer has only borrowed ownership, and a non-ownership tag is added.
[0044] Perform lexical and grammatical analysis on the code to generate an abstract syntax tree. For each function in the abstract syntax tree, for each instruction in it, if it involves ownership transfer, such as transferring a pointer that owns a space to another pointer that owns it, add a comment that the pointer ownership needs to be transferred; if it involves ownership lending, such as a pointer that does not own the space borrows the permission of another pointer, add a comment that the pointer ownership is borrowed. The purpose of this step is to show the difference between the two in static single assignment. At the same time, this step also performs type checking to analyze whether there are any incorrect permission conversions, such as transferring a pointer to a pointer that does not own the space to a pointer to a pointer that owns the space.
[0045] Perform data flow analysis on the code. This step is the key step.
[0046] First, traverse the abstract syntax tree, where each function is a node. The abstract syntax tree contains information about function parameters and return values, so a function permission mapping table is established. Each function is analyzed one by one, and the types of permissions for their parameters and return values are recorded, that is, whether they have ownership or not; if they are owned parameters and return values, the ownership is transferred when the function is called; if they are unowned parameters and return values, since the internal situation of the function is unknown, the permission is recorded as "*" when the function is called; if it is not a pointer, it does not involve changes in ownership and is recorded as "non-pointer".
[0047] Secondly, for each instruction involving memory, define the transfer equation of the permission mapping table, that is, the pointer permission that a pointer permission may be transformed into after an instruction, and the merging operation of different permission mapping tables. Convert the abstract syntax tree into a static single assignment and analyze each function separately. The static single assignment is expressed as a control flow graph, which consists of jump connections between multiple basic blocks. The initial permission mapping table of the function entry point is defined as the mapping set of the function parameters and their pointer permissions, and the initial permission mapping tables of the remaining basic blocks are defined as empty. Inside each basic block, traverse each instruction sequentially, and continuously pass and update the pointer permission mapping table. After the first iteration inside the basic block is completed, for the basic blocks with parent nodes, traverse the parent nodes and merge the permission mapping tables at their exits and pass them to the basic block. Repeat the iteration within the block and the merging operation outside the block until convergence, and obtain the final stable permission mapping table result.
[0048] The specific algorithm for memory error checking is as follows:
[0049] (a) Initialize the pointer permission mapping table of the function entry point to the function parameter permissions, and initialize the pointer permission mapping table of the entry point of each other basic block to empty;
[0050] (b) Sequentially analyze each instruction of each basic block, obtain the pointer permission mapping table after the end of an instruction and pass it to the next instruction until the exit of the basic block. At the same time, record whether the pointer permission mapping table of the basic block has changed;
[0051] (c) If the pointer permission mapping table changes, merge the exit pointer permission mapping table of each basic block at the parent node of each basic block and pass it to this block as the entry permission mapping table of the basic block. Repeat operations (b) and (c);
[0052] (d) If the pointer permission mapping table does not change, the iteration ends, and the result obtained at this time is a converged pointer permission mapping table;
[0053] (e) Re-traverse each instruction and the pointer permission mapping table before executing this instruction, and use the memory error detection mechanism to determine whether unsafe behavior occurs.
[0054] The error detection of this embodiment defines the rules that instructions and pointer permission tables need to meet. If these rules are violated, it is judged that an error occurs in the program. For example, for memory leak checks, it is defined that the pointer permission table at the program exit should be empty (that is, all memory allocated in the program has been released after the program ends). If it is not empty, a memory leak problem occurs; for multiple release checks, if a pointer in the pointer permission table is recorded as not having ownership (that is, it has been released), and the pointer is released again in the next instruction, it is judged as multiple releases. For borrowed transfer or release checks, when a pointer in the pointer permission mapping table is recorded as being borrowed, and the ownership of this pointer is transferred to another pointer or the memory of this pointer is released in the next instruction (including other instructions that require pointer ownership), a dangling pointer will be caused, and it is judged that such an error has occurred; for post-release use checks, if a pointer that is shown as not having ownership (that is, it has been released) in the pointer permission table is used in an instruction, such as dereferencing, it is judged that a post-release use error has occurred.
[0055] It should be pointed out that the above is only a preferred embodiment of the present invention and is not intended to limit the present invention. Any modifications, equivalent substitutions, improvements, etc. made within the spirit and principles of the present invention should be included in the protection scope of the present invention.
Claims
1. A method for analyzing memory safety in C code using a data flow analysis algorithm, characterized in that: Define the C language memory instructions as a formalized instruction set, and then perform the following operations: Static analysis finds the location where the code corresponds to the pointer to add a mark, and automatically adds a mark to the code; Before analysis, preprocess the incoming file, traverse the code of the entire file, find all the pointers in it and observe the behavior of the pointers, analyze whether the pointers have memory allocation or release behavior, and add different pointer tags; If there is a behavior of releasing or allocating memory, or transferring an owned pointer, it means that it owns a piece of memory, and a mark of ownership should be added to the pointer; otherwise, it is considered that the pointer has only borrowed the ownership, and a mark of non-ownership should be added; Convert the above code into an abstract syntax tree and perform type checking on each instruction. At the same time, modify the pointer permission transfer or borrowing statements involved to distinguish them from static single assignments. For each function in the abstract syntax tree, traverse each instruction in it. If it involves ownership transfer, that is, transferring a pointer that owns a space to another pointer that owns it, add a comment that the pointer ownership needs to be transferred; if it involves ownership lending, that is, a pointer without ownership borrows the permissions of another pointer, add a comment that the pointer ownership is borrowed; Linearize the abstract syntax tree to obtain a control flow graph in the form of a static single assignment, perform data flow analysis, and obtain the result of a convergent pointer permission mapping table; The abstract syntax tree includes information about function parameters and return values. The data flow analysis algorithm calculates a pointer permission mapping table corresponding to the function based on the abstract syntax tree. The pointer permission mapping table includes all mappings from variables to the pointer permissions they have. Using the data flow analysis algorithm to iterate and stabilize the results, the memory error detection method is used to check whether there are memory safety issues; The instruction set includes memory allocation, memory release, memory ownership transfer, memory ownership borrowing, forced type conversion, pointer leaving scope, instruction fetch, instruction store, merge instruction and function call instruction; The pointers include two types: ownership and non-ownership; The specific steps of data flow analysis are as follows: Analyze each function one by one and record the permission types of their parameters and return values, that is, whether they have ownership or not; If the parameters and return values are owned, the ownership is transferred when the function is called; If the parameters and return values are not owned, since the internal situation of the function is unknown, the permission is recorded as "*" when the function is called; If it is not a pointer and does not involve a change in ownership, it is recorded as "non-pointer"; Then, for each instruction involving memory, a transfer equation of the pointer permission mapping table is defined, that is, a pointer permission transformed from a pointer permission after an instruction and a merging operation of different pointer permission mapping tables; Convert the abstract syntax tree into a static single assignment and analyze each function separately.
2. The method for analyzing memory safety in C code using a data flow analysis algorithm according to claim 1, characterized in that: Memory error detection methods include memory leak detection, multiple release checking, transfer or release when borrowed checking, and use after free checking.
3. The method for analyzing memory safety in C code using a data flow analysis algorithm according to claim 2, characterized in that: The specific algorithm of the memory error detection method is as follows: (a) Initialize the pointer permission mapping table of the function entry point to the function parameter permissions, and initialize the pointer permission mapping table of the entry point of each other basic block to empty; (b) Sequentially analyze each instruction of each basic block, obtain the pointer permission mapping table after the end of an instruction and pass it to the next instruction until the exit of the basic block. At the same time, record whether the pointer permission mapping table of any basic block has changed; (c) If the pointer permission mapping table changes, merge the exit pointer permission mapping table of each basic block at the parent node of each basic block and pass it to this block as the entry pointer permission mapping table of the basic block, and repeat operations (b) and (c); (d) If the pointer permission mapping table does not change, the iteration ends, and the result obtained at this time is a converged pointer permission mapping table; (e) Re-traverse each instruction and the pointer permission mapping table before executing this instruction, and use the memory error detection mechanism to determine whether unsafe behavior occurs.
Citation Information
Patent Citations
Method for detecting memory leakage of heap operational program
CN102662825A
Android application privilege disclosure vulnerability detection method based on static stain analysis
CN108846282A