A special control flow jump program verification method based on semantic interpretation and legal stack constraint

CN116561005BActive Publication Date: 2026-09-25NANJING UNIV OF AERONAUTICS & ASTRONAUTICS
View PDF 2 Cites 0 Cited by

Patent Information

Application Number
CN202310594235.7
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2023-05-24
Publication Date
2026-09-25
Estimated Expiration
2043-05-24

AI Technical Summary

Technical Problem

[0004]但是,程序语义到逻辑公式的转换是否准确对验证结果的影响很大,错误或不准确的编码转换可能使得验证结果与实际不符

Benefits of technology

[0041](1)支持了已有的同类工具不支持的特殊控制流跳转语义;

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN116561005B_ABST
    Figure CN116561005B_ABST
Patent Text Reader

Abstract

The application discloses a special control flow jump program verification method based on semantic interpretation and legal stack constraint. Special control flow statements in C language include setjmp which is used for recording the return point state of a program and longjmp function which is used for unconditionally jumping to the position recorded by setjmp. Using LLVM, a compiler framework providing a unified intermediate representation, the original program is converted, and the special control flow statements which cannot directly perceive semantics are replaced by synonymous intermediate codes, so that the verification program can support their special semantics. The application further filters the jump target of the longjmp function by recording the depth of function call, and requires the longjmp function to jump to the position where the stack has not been invalidated. The application can support the special control flow jump statements in C language, so that the verification tool can more accurately conform to the actual semantics.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This invention relates to the field of program verification technology, specifically to a special control flow jump program verification method based on semantic interpretation and legal stack constraints. Background Technology

[0002] With the widespread application of computer technology, the reliability and security of computer systems have become increasingly important. Formal methods are one of the important methods for ensuring the security and correctness of computer systems. By analyzing, verifying, and proving the properties of computer systems through mathematical logic modeling, errors and security risks can be avoided to the greatest extent possible.

[0003] Software verification is a common direction in formal methods, and a common approach is to model the program semantics into logical formulas and then use tools such as the SAT / SMT solver to verify the solution. By expanding the loop structure a finite number of times, the program's control flow graph can be transformed into a directed acyclic graph, thus facilitating verification. If the SAT / SMT solver finds a set of satisfying solutions, it indicates that there may be an error in the program that violates a specific property; otherwise, it indicates that such an error does not exist.

[0004] However, the accuracy of the conversion from program semantics to logical formulas has a significant impact on the verification results. Incorrect or inaccurate encoding conversions may lead to verification results that do not match reality. Current program verification tools have limited semantic support for library function calls, mostly implementing this through inlining, and are powerless to handle special control flow calls that cannot be inlined. Summary of the Invention

[0005] Objective: This invention proposes a method for verifying special control flow jump procedures based on semantic interpretation and legal stack constraints. This method enables verification tools to support the semantics of special control flow calls in the C language library. It includes `setjmp`, which records the program's return point state, and the `longjmp` function, which unconditionally jumps to the position recorded by `setjmp`. Furthermore, it supports detecting erroneous `longjmp` jump targets, making the encoding conversion of the verification tool more accurate and realistic.

[0006] Technical Solution: This invention presents a special control flow jump program verification method based on semantic interpretation and legal stack constraints, using LLVM, a compiler framework that provides a unified intermediate representation. It consists of three main parts: function call replacement, legal jump target filtering, and indirect jump encoding. Legal jump target filtering is an optional feature, primarily used for filtering at the function call replacement point. The function call replacement includes the following steps:

[0007] (1) After the function call in the program is inlined to several levels, all LLVM instructions that call the C language library functions setjmp and longjmp are retrieved and added to two instruction sets, denoted by the symbols S and L respectively. setjmp is used to record the return point status of the program, and longjmp is used to unconditionally jump to the position recorded by setjmp. LLVM is a compiler framework that provides a unified intermediate representation.

[0008] (2) Create two allocation instructions at the beginning of the program entry block to allocate temporary variables, which are used to represent the return value and the jump address, respectively, and are used to pass parameters when jumping between basic blocks. These two temporary variables are represented by R and P respectively.

[0009] (3) Replace the setjmp function. Specifically, iterate through each calling instruction I in the set S and perform the following semantic interpretation transformation on I to obtain the basic block set X of possible jump target points:

[0010] (31) Obtain the pointer to the address variable in the first operand of instruction I, and denote the pointer to the address variable by the symbol p;

[0011] (32) Create a storage instruction S1, which writes the constant 0 into R, where R refers to the temporary variable representing the return value defined in step (2);

[0012] (33) Split the basic block where instruction I is located, so that instruction I and the previous instruction are in two basic blocks, and denote the basic block where I is located as B;

[0013] (34) Add B to set X, where set X is the set of possible jump target point basic blocks in step (3);

[0014] (35) Create a storage instruction S2 before S1. The S2 instruction stores the identifier address of B into p. Here, the identifier address refers to the constant integer assigned to the basic block whose address is being taken, which is used to represent the address of a basic block. The identifier address is represented by the symbol L(B).

[0015] (36) Create a read instruction L1, which reads the return value from R as the result of the instruction;

[0016] (37) Replace all operands that previously used I with L1 and remove I.

[0017] (4) Replace the longjmp function. Specifically, iterate through each calling instruction I in the set S and perform the following semantic interpretation transformation on I:

[0018] (41) If the legal jump target filtering is not enabled, set Y to be equal to X and proceed to step (43); otherwise, continue to step (42). Set Y is the set of target basic blocks that the longjmp may jump to, and set X is the set of all jump target points provided by setjmp.

[0019] (42) Perform a valid jump target filtering on the longjmp instruction I, and use the filtering results as set Y;

[0020] (43) Obtain the corresponding jump intermediate block A for set Y. For the same set Y, their jump intermediate blocks are the same basic block. The jump intermediate block A is constructed by reading P and using the reading result as the target address to construct a non-direct jump instruction with Y as the jump target set. P is a temporary variable used in step (2) to represent the jump address.

[0021] (44) Obtain the pointer to the address variable in the first operand of instruction I, and denote the pointer to the address variable by the symbol p;

[0022] (45) Create a read instruction L1, which reads the address in p as the result;

[0023] (46) Create a storage instruction S1, which stores the address read by L1 into P, where P refers to the temporary variable used in step (2) to represent the jump address;

[0024] (47) Get the second operand of I, which is the return value of this longjmp call, denoted by the symbol r;

[0025] (48) Create a storage instruction S2, which stores r into R, where R refers to the temporary variable used in step (2) to represent the return value;

[0026] (49) Modify the I instruction to a jump instruction and jump to A. Here, A refers to the jump intermediate block obtained in step (43). Delete the subsequent redundant instructions.

[0027] Validating redirect targets is a recursive process that includes the following steps:

[0028] (5) By instrumenting before and after function calls and traversing the differential count, the call stack depth of each instruction can be obtained. In order to improve execution efficiency, this step can be executed only once, and the processing result can be retained so that the result can be shared in multiple processing.

[0029] (6) For the currently processed longjmp call instruction, using the depth of the call stack where the current instruction is located as the initial constraint parameter, recursively filter the sequence whose forward stack depth is not monotonically increasing according to the following steps:

[0030] (61) The limit depth of the valid stack passed to the current recursive call is denoted as D. If the current instruction I has not been processed, the following processing is performed, where I represents the longjmp call instruction in step (6).

[0031] (62) Initialize the local variable D' to infinity, representing the current stack limit depth;

[0032] (63) Starting from the position of instruction I, traverse the instructions I' in the current basic block in sequence, update D' to the minimum value of the depth of the corresponding instruction, and mark the instruction as visited;

[0033] (64) If the current basic block u belongs to set X and D'≤D, it indicates that the current stack is valid. Add u to set Y, where set X is the set of possible jump target point basic blocks obtained in step (3), and set Y is the set of valid jump targets obtained after the valid target filtering operation in step (7).

[0034] (65) Update D' to the smaller of D' and D;

[0035] (66) Traverse all predecessor blocks of the current basic block, and recursively call step (6) on the last instruction of each predecessor block, with the parameter D' passed in.

[0036] (7) Filter to obtain the set of legal targets that can be jumped to by the current longjmp, and denote the set by the symbol Y;

[0037] The purpose of indirect jump encoding is to encode the indirect jump instruction (indirectbr instruction) in LLVM into a corresponding logical formula. The steps are as follows:

[0038] (8) The transfer condition from the current non-direct jump instruction in the basic block u to its successor basic block is that the value of the jump address, represented by the symbol up, and the value of the identifier address of v, represented by the symbol L(v), are equal, and the execution condition of the current basic block u is true.

[0039] (9) The condition for a jump error is that up is not equal to any value in the jump list;

[0040] The present invention has the following beneficial effects:

[0041] (1) It supports special control flow jump semantics that are not supported by existing similar tools;

[0042] (2) Supports the verification of the legitimacy of such special control flow jump targets. Attached Figure Description

[0043] Figure 1This is a schematic diagram of the function call replacement step in this invention.

[0044] Figure 2 This is a schematic diagram of the legal jump target screening step in this invention.

[0045] Figure 3 This is a schematic diagram of the non-direct jump encoding step in this invention.

[0046] Figure 4 This is a comparison of the functions of this invention with other similar tools. Detailed Implementation

[0047] The present invention will now be described in further detail with reference to the accompanying drawings.

[0048] The implementation process of this invention consists of three parts. First, function call replacement; second, selection of legitimate jump targets; and third, encoding of indirect jumps.

[0049] (I) Function call replacement

[0050] Part One includes the following steps, as shown in the appendix. Figure 1 As shown:

[0051] (1) After the function call in the program is inlined to several levels, all LLVM instructions that call the C language library functions setjmp and longjmp are retrieved and added to two instruction sets, denoted by the symbols S and L respectively. setjmp is used to record the return point status of the program, and longjmp is used to unconditionally jump to the position recorded by setjmp. LLVM is a compiler framework that provides a unified intermediate representation.

[0052] (2) Create two allocation instructions at the beginning of the program entry block to allocate temporary variables, which are used to represent the return value and the jump address, respectively, and are used to pass parameters when jumping between basic blocks. These two temporary variables are represented by R and P respectively.

[0053] (3) Replace the setjmp function. Specifically, iterate through each calling instruction I in the set S and perform the following semantic interpretation transformation on I to obtain the basic block set X of possible jump target points:

[0054] (31) Obtain the pointer to the address variable in the first operand of instruction I, and denote the pointer to the address variable by the symbol p;

[0055] (32) Create a storage instruction S1, which writes the constant 0 into R, where R refers to the temporary variable representing the return value defined in step (2);

[0056] (33) Split the basic block where instruction I is located, so that instruction I and the previous instruction are in two basic blocks, and denote the basic block where I is located as B;

[0057] (34) Add B to set X, where set X is the set of possible jump target point basic blocks in step (3);

[0058] (35) Create a storage instruction S2 before S1. The S2 instruction stores the identifier address of B into p. Here, the identifier address refers to the constant integer assigned to the basic block whose address is being taken, which is used to represent the address of a basic block. The identifier address is represented by the symbol L(B).

[0059] (36) Create a read instruction L1, which reads the return value from R as the result of the instruction;

[0060] (37) Replace all operands that previously used I with L1 and remove I.

[0061] (4) Replace the longjmp function. Specifically, iterate through each calling instruction I in the set S and perform the following semantic interpretation transformation on I:

[0062] (41) If the legal jump target filtering is not enabled, set Y to be equal to X and proceed to step (43); otherwise, continue to step (42). Set Y is the set of target basic blocks that the longjmp may jump to, and set X is the set of all jump target points provided by setjmp.

[0063] (42) Perform a valid jump target filtering on the longjmp instruction I, and use the filtering results as set Y;

[0064] (43) Obtain the corresponding jump intermediate block A for set Y. For the same set Y, their jump intermediate blocks are the same basic block. The jump intermediate block A is constructed by reading P and using the reading result as the target address to construct a non-direct jump instruction with Y as the jump target set. P is a temporary variable used in step (2) to represent the jump address.

[0065] (44) Obtain the pointer to the address variable in the first operand of instruction I, and denote the pointer to the address variable by the symbol p;

[0066] (45) Create a read instruction L1, which reads the address in p as the result;

[0067] (46) Create a storage instruction S1, which stores the address read by L1 into P, where P refers to the temporary variable used in step (2) to represent the jump address;

[0068] (47) Get the second operand of I, which is the return value of this longjmp call, denoted by the symbol r;

[0069] (48) Create a storage instruction S2, which stores r into R, where R refers to the temporary variable used in step (2) to represent the return value;

[0070] (49) Modify the I instruction to a jump instruction and jump to A. Here, A refers to the jump intermediate block obtained in step (43). Delete the subsequent redundant instructions.

[0071] With attachment Figure 1 For example, without enabling valid target filtering, or considering the same set of longjmp calls for possible jump targets, the three longjmp calls in the diagram first jump to the intermediate block, obtain the jump address set on the temporary variable P in the intermediate block, and jump to the corresponding setjmp target jump point basic block according to the jump address. In the setjmp target jump point basic block, the return value in the temporary variable R is read as the return value after semantic interpretation of setjmp.

[0072] (II) Screening of Legitimate Redirect Targets

[0073] Part Two includes the following steps, as shown in the appendix. Figure 2 As shown:

[0074] (5) By instrumenting before and after function calls and traversing the differential count, the call stack depth of each instruction can be obtained. In order to improve execution efficiency, this step can be executed only once, and the processing result can be retained so that the result can be shared in multiple processing.

[0075] (6) For the currently processed longjmp call instruction, using the depth of the call stack where the current instruction is located as the initial constraint parameter, recursively filter the sequence whose forward stack depth is not monotonically increasing according to the following steps:

[0076] (61) The limit depth of the valid stack passed to the current recursive call is denoted as D. If the current instruction I has not been processed, the following processing is performed, where I represents the longjmp call instruction in step (6).

[0077] (62) Initialize the local variable D' to infinity, representing the current stack limit depth;

[0078] (63) Starting from the position of instruction I, traverse the instructions I' in the current basic block in sequence, update D' to the minimum value of the depth of the corresponding instruction, and mark the instruction as visited;

[0079] (64) If the current basic block u belongs to set X and D'≤D, it indicates that the current stack is valid. Add u to set Y, where set X is the set of possible jump target point basic blocks obtained in step (3), and set Y is the set of valid jump targets obtained after the valid target filtering operation in step (7).

[0080] (65) Update D' to the smaller of D' and D;

[0081] (66) Traverse all predecessor blocks of the current basic block, and recursively call step (6) on the last instruction of each predecessor block, with the parameter D' passed in.

[0082] (7) Filter to obtain the set of legal targets that can be jumped to by the current longjmp, and denote the set by the symbol Y;

[0083] With attachment Figure 2 For example, each node in the diagram is a basic block. The above steps are executed, where step (6) calculates the stack depth information marked in the diagram. Taking node E as another example, assuming that the node where longjmp is located is E, then its predecessors can be returned to nodes B2, B1, and A1, but it cannot return to node D or node F. The stack depth of all instructions in node E is 3. The recursive operation of step (7) is executed on the predecessor B2 of node E with 3 as the input parameter. At B2, since the stack depth of all instructions is 2, step (74) shows that B2 is a node that can be jumped to.

[0084] The predecessor of B2, C2, has a depth of 3 for all its instructions. Although it has the same depth as node E, C2 does not meet the requirement that the forward depth is monotonically increasing because the depth at B2 is 2. Therefore, C2 is not a node that can be jumped to. When the jump target is C2, the condition in step (10) will be true, thus discovering the illegal jump error.

[0085] (iii) Indirect jump encoding

[0086] Part Three includes the following steps, as shown in the appendix. Figure 3 As shown:

[0087] (8) The transfer condition from the current non-direct jump instruction in the basic block u to its successor basic block is that the value of the jump address, represented by the symbol up, and the value of the identifier address of v, represented by the symbol L(v), are equal, and the execution condition of the current basic block u is true.

[0088] (9) The condition for a jump error is that up is not equal to any value in the jump list;

[0089] The effects of this invention can be further illustrated by the following experiments.

[0090] The experiment tested the performance of PALBMC, a tool developed using the method proposed in this invention, and several similar tools, CBMC, ESBMC, LLBMC, and SEABMC, on specially constructed test cases. The experimental results are attached. Figure 4 As shown in the figure, Sat and Unsat indicate whether the program has the specified error. The results show that this invention provides the best support for special control flow jumps in C language, and can be used to verify this type of error, reducing errors caused by setjmp and longjmp in the program.

Claims

1. A special control flow jump procedure verification method based on semantic interpretation and legal stack constraints, characterized in that: It consists of three parts: function call replacement, filtering of valid jump targets, and encoding of indirect jumps. The function call replacement includes the following steps: (1) After the function call in the program is inlined to several levels, all LLVM instructions that call the C language library functions setjmp and longjmp are retrieved and added to two instruction sets, denoted by the symbols S and L respectively. setjmp is used to record the return point status of the program, and longjmp is used to unconditionally jump to the position recorded by setjmp. LLVM is a compiler framework that provides a unified intermediate representation. (2) Create two allocation instructions at the beginning of the program entry block to allocate temporary variables, which are used to represent the return value and the jump address, respectively, and are used to pass parameters when jumping between basic blocks. These two temporary variables are represented by R and P respectively. (3) Replace the setjmp function. Specifically, iterate through each calling instruction I in the set S, perform corresponding semantic interpretation transformation on I, and obtain the basic block set X of possible jump target points. (4) Replace the longjmp function. Specifically, iterate through each calling instruction I in the S set and perform the corresponding semantic interpretation conversion on I. Validating redirect targets is a recursive process that includes the following steps: (5) The call stack depth of each instruction is obtained by instrumenting before and after the function call and traversing the differential count. This step is executed only once, and the processing result is retained so that the result can be shared in multiple processing. (6) For the currently processed longjmp call instruction, recursively filter the sequence whose forward stack depth is not monotonically increasing, using the depth of the current instruction's call stack as the limiting parameter. (7) Filter to obtain the set of legal targets that can be jumped to by the current longjmp, and denote the set by the symbol Y; The purpose of indirect jump encoding is to encode the indirectbr instruction into a corresponding logical formula. The indirectbr instruction is a branch instruction in LLVM used for indirect jumps. It jumps to the basic block corresponding to a given address and provides a set of possible target basic blocks. The steps in this part are as follows: (8) The transfer condition from the current non-direct jump instruction in the basic block u to its successor basic block is that the value of the jump address, represented by the symbol up, and the value of the identifier address of v, represented by the symbol L(v), are equal, and the execution condition of the current basic block u is true. (9) The condition for a jump error is that up is not equal to any value in the jump list.

2. The special control flow jump program verification method based on semantic interpretation and legal stack constraints according to claim 1, characterized in that: The semantic interpretation and conversion of the setjmp call instruction I in step (3) specifically includes the following steps: (31) Obtain the pointer to the address variable in the first operand of instruction I, and denote the pointer to the address variable by the symbol p; (32) Create a storage instruction S1, which writes the constant 0 into R, where R refers to the temporary variable representing the return value defined in step (2); (33) Split the basic block where instruction I is located, so that instruction I and the previous instruction are in two basic blocks, and denote the basic block where I is located as B; (34) Add B to set X, where set X is the set of possible jump target point basic blocks in step (3); (35) Create a storage instruction S2 before S1. The S2 instruction stores the identifier address of B into p. Here, the identifier address refers to the constant integer assigned to the basic block whose address is being taken, which is used to represent the address of a basic block. The identifier address is represented by the symbol L(B). (36) Create a read instruction L1, which reads the return value from R as the result of the instruction; (37) Replace all operands that previously used I with L1 and remove I.

3. The special control flow jump program verification method based on semantic interpretation and legal stack constraints according to claim 1, characterized in that: The semantic interpretation and conversion of the longjmp call instruction I in step (4) specifically includes the following steps: (41) If the legal jump target filtering is not enabled, set Y to be equal to X and proceed to step (43); otherwise, continue to step (42). Set Y is the set of target basic blocks that the longjmp may jump to, and set X is the set of all jump target points provided by setjmp. (42) Perform a valid jump target filtering on the longjmp instruction I, and use the filtering results as set Y; (43) Obtain the corresponding jump intermediate block A for set Y. For the same set Y, their jump intermediate blocks are the same basic block. The jump intermediate block A is constructed by reading P and using the reading result as the target address to construct a non-direct jump instruction with Y as the jump target set. P is a temporary variable used in step (2) to represent the jump address. (44) Obtain the pointer to the address variable in the first operand of instruction I, and denote the pointer to the address variable by the symbol p; (45) Create a read instruction L1, which reads the address in p as the result; (46) Create a storage instruction S1, which stores the address read by L1 into P, where P refers to the temporary variable used in step (2) to represent the jump address; (47) Get the second operand of I, which is the return value of this longjmp call, denoted by the symbol r; (48) Create a storage instruction S2, which stores r into R, where R refers to the temporary variable used in step (2) to represent the return value; (49) Modify the I instruction to a jump instruction and jump to A. Here, A refers to the jump intermediate block obtained in step (43). Delete the subsequent redundant instructions.

4. The special control flow jump program verification method based on semantic interpretation and legal stack constraints according to claim 1, characterized in that: The recursive filtering operation in step (6) specifically includes the following steps: (61) The limit depth of the valid stack passed to the current recursive call is denoted as D. If the current instruction I has not been processed, the following processing is performed, where I represents the longjmp call instruction in step (6). (62) Initialize the local variable D' to infinity, representing the current stack limit depth; (63) Starting from the position of instruction I, traverse the instructions I' in the current basic block in sequence, update D' to the minimum value of the depth of the corresponding instruction, and mark the instruction as visited; (64) If the current basic block u belongs to set X and D'≤D, it indicates that the current stack is valid. Add u to set Y, where set X is the set of possible jump target point basic blocks obtained in step (3), and set Y is the set of valid jump targets obtained after the valid target filtering operation in step (7). (65) Update D' to the smaller of D' and D; (66) Traverse all predecessor blocks of the current basic block, and recursively call step (6) on the last instruction of each predecessor block, with the parameter D' passed in.

Citation Information

Patent Citations

  • Control flow integrity protection method, system and device and readable storage medium

    CN112966258A

  • A method making nonlocal skip tool imitated into exception mechanism by C programming language

    CN1952880A