A method for identifying data flows outside components based on static analysis

The static analysis method uses the identification of out-of-component data flow in C/C++ code, which solves the problem of difficulty in judging the data attribution of pointers, and improves the accuracy and efficiency of code partitioning.

CN120216329BActive Publication Date: 2025-08-15ZHEJIANG UNIV
View PDF 1 Cites 0 Cited by

Patent Information

Application Number
CN202510704041.7
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2025-05-29
Publication Date
2025-08-15
Estimated Expiration
2045-05-29

AI Technical Summary

Technical Problem

The prior art is difficult to effectively identify the data outside the component pointed to by pointers in C/C++ code, which leads to difficulty in identifying data access between components during code partitioning, which may lead to weakening the system's ability to resist data corruption or the components cannot work properly.

Method used

The method based on static analysis is adopted to generate an abstract syntax tree through lexical analysis and grammatical parsing, identify function attributes in the component source code, and judge the data classification of the data access target by traversing the abstract syntax tree to identify data flow outside the component.

Benefits of technology

It realizes accurate identification of out-of-component data flows in component source code, reduces the practical difficulty of code partitioning scheme, reduces manpower investment and reduces the missed reporting rate of cross-component data synchronization or authorization.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120216329B_ABST
    Figure CN120216329B_ABST
Patent Text Reader

Abstract

The present invention discloses a method for identifying component external data flows based on static analysis, comprising: reading a component source code file, performing lexical analysis and grammatical analysis on the component source code, obtaining token information contained in the component source code and generating an abstract syntax tree, and obtaining function properties in the component source code based on the information, including: whether it is a function defined in the component source code, whether it is a function imported from outside the component, and whether it is a function exported to outside the component; traversing the abstract syntax tree corresponding to the locally defined function, and maintaining the classification and pointing information of the nodes in the process; for statements containing data update operations, judging the data classification of the data access target, and if it is external component data, adding the source code position corresponding to the statement to the source code position set containing the external component data flow; and finally returning the source code position set containing the external component data flow. The present invention can identify the read and write operations on the external component data flow in the component source code to assist in code partitioning.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the field of information security technology, and in particular to a method for identifying component external data flows based on static analysis. Background Art

[0002] Code partitioning is a common method for improving the security and robustness of complex software. This approach divides security-sensitive systems into multiple independent components and enforces the principle of least privilege on these components, limiting access to resources necessary for their proper functioning and preventing arbitrary access to resources belonging to other components. Complex software systems, such as operating system kernels, inevitably contain components with relatively weak reliability. By isolating these components from the rest of the system, an attacker can limit the scope of damage they could inflict by exploiting a single software vulnerability.

[0003] To restrict component access to unauthorized resources, code partitioning practices typically rely on some sort of address space access restriction mechanism, such as running components in separate processes, assigning different permissions to data memory pages, and inserting restriction / check code for data access operations in the source code. To ensure proper functioning of partitioned components, it is necessary to identify the external resources that the components can legally access during runtime and move these resources into the component's legal data access area or add them to a data access whitelist to allow the component to legally access these resources. In software written in C / C++, data access and transfer are often performed through pointers. However, C pointers lack bounds, making it difficult to determine the size of the data they point to from the pointer itself. When using pointers, code often involves assignments and element-wise operations, making it difficult to identify the source of pointers and determine whether the code is manipulating external data. Furthermore, to determine the ownership of the data pointed to by a pointer, developers practicing code partitioning must have sufficient knowledge of the target software code. Misidentifying the ownership of data can weaken the system's resilience to data corruption or cause the component to malfunction. Summary of the Invention

[0004] In response to the shortcomings of the existing technology, the present invention proposes a component external data flow identification method based on static analysis, which is used to identify component external data flows in software components to assist in the practice of code partitioning and can also be used in scenarios such as program behavior analysis.

[0005] The specific technical solutions are as follows:

[0006] A method for identifying data flows outside a component based on static analysis, comprising the following steps:

[0007] Step 1: Read the component source code file, perform lexical and grammatical analysis on it, obtain the token information contained in the component source code and generate an abstract syntax tree;

[0008] Step 2: Based on the token information and abstract syntax tree, obtain the function attributes in the component source code. Function attributes include: whether it is a function defined in the component source code, whether it is a function imported from outside the component, and whether it is a function exported outside the component.

[0009] Step 3. Identify the external data flow contained in the component source code: traverse the abstract syntax tree corresponding to the locally defined function contained in the component source code, and maintain the classification and pointing information of the nodes during the traversal process; for statements containing data update operations in the abstract syntax tree, determine the data classification of its data access target. If it is external data, add the source code position corresponding to the statement to the source code position set containing the external data flow; after completing the traversal, return the source code position set containing the external data flow.

[0010] Furthermore, the step 2 is specifically implemented through the following sub-steps:

[0011] S2.1: Identify function definitions and macro definitions in the component source code, obtain and return the set of locally defined functions;

[0012] S2.2: First, initialize the imported component external function set and the exported component external function set to be empty; based on the locally defined function set, identify the non-component defined functions called by the component source code, obtain and return the imported component external function set;

[0013] Get and initialize the imported component external function set and the exported component external function set. For all locally defined functions in the locally defined function set, determine whether they have the possibility of being called by external components and whether they meet the characteristics of exported functions. If at least one of them is judged as yes, add it to the exported component external function set. Otherwise, ignore the locally defined function.

[0014] Furthermore, the S2.1 specifically obtains and returns the locally defined function set through the following operations:

[0015] Initialize the local definition function set to be empty; for each translation unit node generated based on the component source code, traverse all function declaration type nodes and macro definition type nodes contained in the translation unit node;

[0016] For a function declaration type node, determine whether it contains a compound statement type child node. If so, add the function name declared by the function declaration type node to the local definition function set. If not, ignore the function declaration type node.

[0017] For a macro definition type node, determine whether it is a macro function. If so, add the macro name corresponding to the macro function to the local definition function set. If not, ignore the macro definition type node.

[0018] Returns the set of locally defined functions.

[0019] Furthermore, the S2.2 specifically obtains and returns the imported component external function set through the following operations:

[0020] For each function in the locally defined function set, obtain its function body, collect all identifier category lexical units contained in the function body, and obtain the abstract syntax tree node corresponding to the lexical unit; for each abstract syntax tree node obtained, determine its category;

[0021] If the abstract syntax tree node is a function reference type node, the referenced object is a function declaration type node, and the function prototype declared by the function declaration type node is defined outside the component source code directory, then the function name is added to the set of imported external component functions;

[0022] If the abstract syntax tree node is a macro instantiation type node, if the macro defined by the macro definition type node it references is a macro function and the name of the macro function is not in the local definition function set, add it to the imported component external function set;

[0023] Finally, the set of imported component external functions is returned.

[0024] Furthermore, in S2.2, the features of exporting a function include: the function is included in the interface header file of the component; and for a Linux kernel module type component, the function is exported by a macro.

[0025] Furthermore, the step three is specifically implemented through the following sub-steps:

[0026] S3.1: Initialize the source code location set containing the component's external data stream and the local function return value classification dictionary to be empty;

[0027] S3.2: Get an unprocessed locally defined function and obtain its corresponding function declaration type abstract syntax tree node;

[0028] S3.3: Initialize the variable classification dictionary to be empty, which is used to record the abstract syntax tree node classification corresponding to each variable in the locally defined function;

[0029] S3.4: Identify the incoming parameter classification, and add the incoming parameter and its classification to the variable classification dictionary;

[0030] S3.5: Analyze the data operations contained in the function body and update the source code location set containing the data flow outside the component: First, obtain the compound statement type child node of the function declaration type abstract syntax tree node, and the content of this child node is the function body;

[0031] For each data operation type statement sub-node in the function body, identify its data access target, and determine the classification of the expression corresponding to each data operation type statement sub-node as the operation object through recursive deduction; if the expression includes access to data outside the component, then add the source code position range corresponding to the abstract syntax tree node to which it belongs to the source code position set containing the data flow outside the component; if the data operation type statement includes an operation to initialize a variable or change the variable classification, then update the variable classification dictionary according to the operation;

[0032] S3.6: Return a set of source locations containing data streams outside the component.

[0033] Furthermore, the S3.5 is specifically implemented through the following sub-steps:

[0034] (3.5.1) Get an unprocessed compound statement type child node of the current function declaration type abstract syntax tree node;

[0035] (3.5.2) Determine the type of each child node of the current compound statement type child node to determine whether the current child node contains a data operation, and filter to obtain a data operation type statement child node;

[0036] (3.5.3) Get an unprocessed data operation type statement child node;

[0037] (3.5.4) Identifying a data access target in the current subnode based on the type and identifier of the current data operation type statement subnode; the data access target includes a data read target and a data write target;

[0038] (3.5.5) For data read and write targets, perform recursive classification deduction based on classification rules. This means that shallow-level results are judged based on deep-level results to obtain the data classification for each data access target node.

[0039] (3.5.6) Determine whether the data access target is external data. If the security policy restricts reading external data and the data read target is classified as external data, add the source code location corresponding to the current abstract syntax tree node to the external data read location set; otherwise, do not add it. If the security policy restricts writing external data and the data write target is classified as external data, add the source code location corresponding to the current abstract syntax tree node to the external data write location set; otherwise, do not add it.

[0040] (3.5.7) Update or maintain the variable classification dictionary based on actual conditions. Specifically, update or maintain the data classification of the variable corresponding to the data write target. If the data classification of the data read target is an external component data pointer, an internal component data pointer, or a null pointer, update the data classification of the variable corresponding to the data write target in the variable classification dictionary to the same data classification as the data read target. Otherwise, maintain the original classification.

[0041] At the same time, if the current node type is a return declaration type, the local function return value classification dictionary is updated as needed: If the local function return value classification dictionary does not contain a record of the current function return value or the priority is lower than the priority of the current node type, the corresponding category of the current function return value in the local function return value classification dictionary is updated; the classification priority is ranked as follows: ① external component data pointer, ② local data pointer, ③ immediate value or other; If the local function return value classification dictionary does not contain a record of the current function return value, and the data classification of the current node is a classification other than pointer type, the data classification of the current function return value in the local function return value classification dictionary is updated to the immediate value classification; If the current node type is not a return declaration type, directly execute step (3.5.8);

[0042] (3.5.8) Determine whether there is any unprocessed data accessing the target node. If not, proceed to step (3.5.9). If so, jump to step (3.5.5).

[0043] (3.5.9) Determine whether the function body corresponding to the current compound statement type subnode contains any unprocessed data operation type statement subnodes. If not, proceed to step (3.5.10). If so, jump to step (3.5.3).

[0044] (3.5.10) Determine whether there are any unprocessed locally defined functions in the set of locally defined functions. If not, execute S3.6; if so, jump to S3.2.

[0045] Furthermore, in step (3.5.3), it is determined whether the current child node meets any of the following attribute requirements. If so, it is determined that the current child node contains data operations and the process proceeds to step (3.5.4). Otherwise, the current child node is ignored and the next child node is determined. The attribute requirements are as follows:

[0046] ① The type is variable declaration, compound assignment or conditional operation;

[0047] ②The type is a binary operation and the operator corresponding identifier is "=" or "==";

[0048] ③ The type is a unary operation and the operator corresponding identifier is "++" or "--";

[0049] ④Type is return statement;

[0050] In step (3.5.4), the data read target and data write target are determined according to the following rules:

[0051] ① For variable declaration type nodes, the data write target is the first child node, and the data read target is the last child node;

[0052] ②For compound assignment type nodes, the data write target is the first child node, and the data read target is the first and second child nodes;

[0053] ③For conditional operation type nodes, the data write target is the first child node, and the data read target is the remaining child nodes;

[0054] ④ For a binary operation node whose operator corresponding identifier is "=", its data write target is the first child node, and its data read target is the second child node;

[0055] ⑤For binary operation nodes whose operator corresponding identifier is "==", there is no data write target, and the data read target is all child nodes;

[0056] ⑥ For unary operation nodes whose operator corresponding identifier is "++" or "--", the data read and write targets are both the first child node;

[0057] ⑦ For the return statement type node, there is no data write target, and the data read target is the first child node;

[0058] In the above step (3.5.5), the classification rules for data read targets and write targets are as follows:

[0059] ① For variable declaration type nodes, if it is a pointer type and the initial value of the reference is defined in a source code file outside the component, the return category is a component external data pointer; if it is a pointer type and the initial value of the reference is defined in the current component source code directory, the return category is a local data pointer; if it is a pointer type and has no initial value, the return category is a null pointer. If it is a non-pointer type, the return category is local data;

[0060] ② For function call type nodes, if the referenced function has a corresponding key value in the local function return value classification dictionary, its key value is returned; if the referenced function does not appear in the local function return value classification dictionary, 1) if its return value is a pointer type and a function pointer type, if the referenced function is a local function, the return classification is a local function pointer, otherwise the return classification is an external component function pointer; 2) if its return value is a pointer type and not a function pointer type, if the referenced function is a local function, the return classification is a local data pointer, otherwise the return classification is an external component data pointer; 3) if its return value is not a pointer type, the return classification is an immediate value;

[0061] ③ For array index type nodes, if the child node used to refer to the parent variable element is classified as a component external data pointer, the return type is classified as component external data; otherwise, the return type is classified as local data;

[0062] ④ For member reference type nodes, if the child node used to refer to the parent variable element is classified as external component data or external component data pointer, the return classification is external component data; if the node used to refer to its parent variable element is classified as local data or local data pointer, the return classification is local data;

[0063] ⑤ For type conversion nodes, the classification of the last child node is returned first. If the classification of the last child node is not recognized, if the child node data type is a function pointer, the returned classification is an external component function pointer; if the child node data type is a pointer type but not a function pointer, the returned classification is an external component data pointer; if the child node data type is other non-pointer types, the returned classification is an immediate value;

[0064] ⑥ For a unary operation type node, if its operator is a unary arithmetic operation, the child node is external data and the security policy restricts external data writing, then the source code position corresponding to the current abstract syntax tree node is added to the external data write operation position set, and its child node classification is returned; if its operator is a reference operation, when it is classified as external data, the return classification is external data pointer, when it is classified as local data, the return classification is local data pointer, for other classifications, the return classification is external data pointer; if its operator is a dereference operation, when it is classified as external data pointer, the return classification is external data, when it is classified as local data pointer, the return classification is local data, for other classifications, the return classification is external data; if its operator is a unary logical operation, the return classification is immediate value;

[0065] ⑦ For a binary operation type node, if its operator is a binary arithmetic operation, the classification of its first child node is returned as the classification of the data access target node; if it is another type of binary operation node, the returned classification is an immediate value;

[0066] ⑧For a conditional operation type node, first obtain the categories of all its child nodes that are data read targets, and return the category with the highest priority among the node categories; the category priority is as follows: 1) external component data pointer; 2) local data pointer; 3) external component data; 4) local data; 5) immediate data;

[0067] ⑨For nodes that do not expose the expression type, return the same category as the child node.

[0068] Furthermore, in the step (3.5.5), for the expression node N as the data access target, the calculation function F(N) of its data classification is inferred, which is specifically implemented by the following sub-steps:

[0069] (3.5.5.1) Determine whether N is a leaf node. If N is a leaf node, directly infer N's classification according to the classification rules; otherwise, execute (3.5.5.2);

[0070] (3.5.5.2) N is a non-leaf node, and all its direct expression child nodes C1, C2…C n , calculate F(C1), F(C2)…F(C n );

[0071] (3.5.5.3) Derivation of result set {F(C1),F(C2),...,F(C n )}, infer the data classification of N according to the classification rules.

[0072] A component external data flow identification system based on static analysis, used to implement the component external data flow identification method based on static analysis, comprising: an abstract syntax tree generation module, a function attribute judgment module, and a component external data flow identification module;

[0073] The abstract syntax tree generation module is used to perform lexical analysis and grammatical analysis on the component source code file, obtain the token information contained in the component source code and generate an abstract syntax tree;

[0074] The function attribute judgment module is used to obtain the function attributes in the component source code according to the token information and the abstract syntax tree;

[0075] The external component data flow identification module is used to traverse the abstract syntax tree corresponding to the locally defined function contained in the component source code, and maintain the classification and pointing information of the nodes during the traversal process; for statements containing data update operations in the abstract syntax tree, the data classification of its data access target is judged, and if it is external component data, the source code position corresponding to the statement is added to the source code position set containing the external component data flow; after completing the traversal, the source code position set containing the external component data flow is returned.

[0076] The beneficial effects of the present invention are:

[0077] The method of the present invention can identify the read and write operations on the external data stream of the component in the component source code. The identification result can be used as a preliminary identification basis for the data that needs to be synchronized or authorized between different components in the code partitioning scheme, thereby reducing the practical difficulty of implementing the code partitioning scheme, reducing manpower investment and reducing the underreporting of cross-component data that needs to be synchronized or authorized. BRIEF DESCRIPTION OF THE DRAWINGS

[0078] Figure 1 This is a flowchart of a method for identifying external component data flows based on static analysis in an embodiment of the present invention.

[0079] Figure 2 It is a flowchart of obtaining function properties in component source code in an embodiment of the present invention.

[0080] Figure 3 It is a flowchart of identifying component external data flows contained in component source code in an embodiment of the present invention. DETAILED DESCRIPTION

[0081] The present invention will be described in detail below based on the accompanying drawings and preferred embodiments. The purpose and effects of the present invention will become more apparent. The present invention will be further described in detail below in conjunction with the accompanying drawings and embodiments. It should be understood that the specific embodiments described herein are only for explaining the present invention and are not intended to limit the present invention.

[0082] To avoid confusion among related concepts, the term "type" below refers to the data type of a variable (Type, such as int for signed integers, char for single characters, unsigned long for unsigned long integers, etc.); "kind" refers to the node type of abstract syntax tree analysis (CursorKind, such as VAR_DECL); "category" refers to the lexical unit type of lexical analysis (TokenKind, such as IDENTIFIER); and the term "classification" refers to a tag attribute dedicated to this method, that is, the data classification to which it belongs.

[0083] Furthermore, in the analysis, the abstract syntax tree nodes used to represent data can be classified into the following categories: ① local data; ② data outside the component; ③ local function; ④ function outside the component; ⑤ local data pointer; ⑥ data pointer outside the component; ⑦ local function pointer; ⑧ function pointer outside the component; ⑨ immediate value; ⑩ others.

[0084] like Figure 1 As shown, a method for identifying component external data flows based on static analysis includes the following steps:

[0085] Step 1: Read the component source code file, perform lexical and syntactic analysis on it, obtain the token information contained in the component source code and generate an Abstract Syntax Tree (AST).

[0086] Step 2: Based on the Token information and the abstract syntax tree, obtain the function attributes in the component source code. The function attributes include: whether it is a function defined in the component source code, whether it is a function imported from outside the component, and whether it is a function exported to outside the component. Figure 2As shown, step 2 is specifically implemented through the following sub-steps:

[0087] S2.1. Identify function definitions and macro definitions in the component source code, obtain and return a locally defined function set: First, initialize the locally defined function set to be empty. For each translation unit node generated based on the component source code, traverse all function declaration type nodes (as an embodiment, taking the abstract syntax tree generated by libclang as an example, it is FUNCTION_DECL, and the same applies to the types and category names listed in the brackets below) and macro definition type (MACRO_DEFINITION) nodes contained in the translation unit node; for the function declaration type node, determine whether it contains a compound statement type child node. If so, add the function name declared in the function declaration type node to the locally defined function set. If not, ignore the function declaration type node; for the macro definition type node, determine whether it is a macro function. If so, add the macro name corresponding to the macro function to the locally defined function set. If not, ignore the macro definition type node. Finally, return the locally defined function set.

[0088] S2.2: Based on the locally defined function set, obtain the imported component external function set and the exported component external function set. The acquisition of these two sets can be performed simultaneously, as follows.

[0089] (2.2.1) Identify non-component-defined functions called by the component source code, and obtain and return the set of imported external component functions. Specifically, first, initialize the set of imported external component functions to be empty. For each function in the set of locally defined functions, obtain its function body, collect all identifier-type (IDENTIFIER) lexical units contained in the function body, and obtain the corresponding abstract syntax tree node. For each obtained abstract syntax tree node, determine its type. If it is a function reference type node, the object referenced is a function declaration type node, and the function prototype declared in the function declaration type node is defined outside the component source code directory, then add the function name to the set of imported external component functions. If the abstract syntax tree node is a macro instantiation type (MACRO_INSTANTIATION) node, and the macro defined by the macro definition type node it references is a macro function and the macro function name is not in the set of locally defined functions, then add it to the set of imported external component functions. Finally, return the set of imported external component functions.

[0090] (2.2.2) Obtain the set of exported component external functions. Specifically, initialize the set of exported component external functions to be empty. For all locally defined functions in the set of locally defined functions, determine whether they are likely to be called by external components and whether they meet the characteristics of exported functions. If at least one of the conditions is yes, add them to the set of exported component external functions. Otherwise, ignore the locally defined function. Such characteristics that meet the requirements of exported functions include: the function is included in the component's interface header file; for Linux kernel module-type components, the function is exported by macros such as EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL(), etc.

[0091] Step 3: Identify external data flows contained in the component source code: Traverse the abstract syntax tree corresponding to the locally defined functions in the component source code, maintaining node classification and pointer information during the traversal. For statements containing data update operations, determine the data classification of the data access target. If the data is external to the component, add the source code location corresponding to the statement to the source code location set containing external data flows. Finally, return the source code location set containing external data flows.

[0092] like Figure 3 As shown, step three is implemented through the following sub-steps:

[0093] S3.1: Initialize the source code location set containing external component data flows to be empty. Specifically, if the inter-component data access policy restricts cross-component reads, this set contains the external component data read location set; if the inter-component data access policy restricts cross-component writes, this set contains the external component data write location set. Also, initialize the local function return value classification dictionary to be empty.

[0094] S3.2: Get an unprocessed locally defined function and obtain its corresponding function declaration type abstract syntax tree node.

[0095] S3.3: Initialize the variable classification dictionary to be empty. This dictionary is used to record the abstract syntax tree node classification corresponding to each variable in the locally defined function.

[0096] S3.4: Identify the incoming parameter classification and add the incoming parameter and its classification to the variable classification dictionary. The specific operations are as follows:

[0097] Traverse all parameter declaration type (PARM_DECL) child nodes in the current function declaration type abstract syntax tree node. If the type of the parameter declaration type child node is a pointer type (TypeKind.POINTER) and not a function pointer, mark the parameter classification as a local data pointer or an external data pointer based on whether the locally defined function is exported and its data type. For example, if the locally defined function exists in the set of exported external functions, all its pointer-type incoming parameters are classified as external data pointers by default. If the locally defined function is modified with the static attribute and the function pointer is not exported, all its pointer-type incoming parameters are classified as local data pointers by default. For data pointers whose classification cannot be confirmed, their incoming parameters are classified as external data pointers by default. Finally, each incoming parameter and its corresponding classification are added to the variable classification dictionary.

[0098] S3.5: Analyze the data operations contained in the function body and update the source code location set containing data flows outside the component. First, obtain the compound statement type (COMPOUND_STMT) child node of the current function declaration type abstract syntax tree node. The content of this child node is the function body of the function. For each data operation type statement child node in the function body, identify its data access target and determine the classification of the expression corresponding to each data operation type statement child node as the operation object through recursive deduction (i.e., starting from the bottom-level leaf node to determine its data classification, and based on the deep-level results, perform data classification judgment on shallow nodes, tracing back layer by layer until the data classification of all data access target child nodes is completed). If the expression contains access to data outside the component (including reading and writing), then add the source code location range corresponding to the abstract syntax tree node to which it belongs to the source code location set containing data flows outside the component. If the data operation type statement contains an operation to initialize a variable or an operation to change the variable classification, then update the variable classification dictionary according to the operation. S3.5 is specifically implemented through the following sub-steps:

[0099] (3.5.1) Gets the compound-statement child node (i.e., the function body) of the current function-declaration abstract syntax tree node.

[0100] (3.5.2) Determine the type of each child node of the current compound statement type child node to determine whether the current child node contains data operations, and filter out data operation type statement child nodes. Specifically, determine whether any of the following attribute requirements are met. If so, proceed to step (3.5.4); otherwise, ignore the current child node and proceed to the next child node. The attribute requirements are as follows:

[0101] ① The type is variable declaration (VAR_DECL), compound assignment (COMPOUND_ASSENTMENT_OPERATOR) or conditional operation (CONDITIONAL_OPERATOR).

[0102] ②The type is binary operation (BINARY_OPERATOR) and the operator corresponding identifier is "=" or "==".

[0103] ③The type is a unary operation (UNARY_OPERATOR) and the operator corresponding identifier is "++" or "--".

[0104] ④The type is return statement (RETURN_STMT).

[0105] (3.5.3) Get an unprocessed data operation type statement child node and continue to execute step (3.5.4).

[0106] (3.5.4) Based on the type and identifier of the current data operation type statement child node, identify the expression nodes in the current statement that serve as data access targets (i.e., data read targets and data write targets). Data read targets and data write targets are determined according to the following rules:

[0107] ① For a variable declaration type node, its data write target is the first child node, and its data read target is the last child node.

[0108] ②For compound assignment type nodes, the data write target is the first child node, and the data read target is the first and second child nodes.

[0109] ③For conditional operation type nodes, the data write target is the first child node, and the data read target is the remaining child nodes.

[0110] ④ For a binary operation node whose operator corresponding identifier is “=”, its data write target is the first child node, and its data read target is the second child node.

[0111] ⑤For the binary operation node whose operator corresponding identifier is “==”, there is no data write target, and the data read target is all child nodes.

[0112] ⑥ For unary operation nodes whose operator corresponding identifier is “++” or “--”, the data reading and writing targets are both the first child node.

[0113] ⑦ For the return statement type node, there is no data write target, and the data read target is the first child node.

[0114] (3.5.5) For expression nodes that are data access targets, perform recursive classification deduction based on the classification rules (i.e., determine shallow results based on deep results) to obtain the data classification of each expression node. Specifically, let the input expression node be N. The calculation function F(N) used to infer the data classification of N is executed as follows:

[0115] (3.5.5.1) Determine whether N is a leaf node. If N is a leaf node (i.e., does not contain an expression child node), directly infer the classification of N according to the classification rules; otherwise, execute (3.5.5.2).

[0116] (3.5.5.2) If N is a non-leaf node (i.e., contains an expression child node), then for all its direct expression child nodes C1, C2…C n , calculate F(C1), F(C2)…F(C n ).

[0117] (3.5.5.3) Derivation of result set {F(C1),F(C2),...,F(C n )}, infer the data classification of N according to the classification rules.

[0118] The classification rules for expression nodes that are data access targets are as follows:

[0119] ① For variable declaration (VAR_DECL) type nodes, if it is a pointer type and the initial value referenced is defined in a source code file outside the component, the return category is external data pointer; if it is a pointer type and the initial value referenced is defined in the current component source code directory, the return category is local data pointer; if it is a pointer type and has no initial value, the return category is null pointer. If it is not a pointer type, the return category is local data.

[0120] ② For a function call (CALL_EXPR) type node, if the referenced function has a corresponding key value in the local function return value classification dictionary, its key value is returned. If the referenced function does not appear in the local function return value classification dictionary, 1) if its return value is a pointer type and a function pointer type, if the referenced function is a local function, the return classification is a local function pointer; otherwise, it is an external function pointer; 2) if its return value is a pointer type and not a function pointer type, if the referenced function is a local function, the return classification is a local data pointer; otherwise, it is an external data pointer; 3) if its return value is not a pointer type, the return classification is an immediate value.

[0121] ③For array index (ARRAY_SUBSCRIPT_EXPR) type nodes, if the child node used to refer to the parent variable element (such as "a" in "a[i]") is classified as an external component data pointer, the return value is classified as external component data; otherwise, the return value is classified as local data.

[0122] ④ For member reference (MEMBER_REF_EXPR) type nodes, if the child node used to refer to the parent variable element (such as "a" in "a->b", "c" in "cd") is classified as external component data or external component data pointer, the return is classified as external component data; if the node used to refer to its parent variable element is classified as local data or local data pointer, the return is classified as local data.

[0123] ⑤ For type conversion (CSTYLE_CAST_EXPR) type nodes, the category of the last child node is returned first. When the category of the last child node is not recognized, if the child node data type is a function pointer, the return category is an external component function pointer; if the child node data type is a pointer type but not a function pointer, the return category is an external component data pointer; if the child node data type is other non-pointer types, the return category is an immediate value.

[0124] ⑥ For a node of the unary operation (UNARY_OPERATOR) type, if its operator is a unary arithmetic operation ("++", "--"), first obtain its child node classification. If the child node is external data and the security policy restricts external data writing, add the source code location corresponding to the current abstract syntax tree node to the external data write operation location set; then, return its child node classification. If its operator is a reference operation ("&"), when the classification is external data or local data, return an external data pointer or a local data pointer, respectively. For other classifications, return a pointer classified as external data. If its operator is a dereference operation ("*"), when the classification is external data pointer or local data pointer, return an external data pointer or a local data pointer, respectively. For other classifications, return a pointer classified as external data. If its operator is a unary logical operation (such as "!"), return an immediate value.

[0125] ⑦ For a BINARY_OPERATOR type node, if its operator is a binary arithmetic operation (such as "+", "-", etc.), the classification of its first child node is returned; if it is a binary logical operation (such as "&&") or other type of binary operation node, the returned classification is an immediate value.

[0126] ⑧ For a CONDITIONAL_OPERATOR node, first obtain the categories of all its child nodes that are data read targets and return the category with the highest priority. The category priority is as follows: 1) External data pointer; 2) Local data pointer; 3) External data; 4) Local data; 5) Immediate data.

[0127] ⑨ For nodes of the unexposed expression (UNEXPOSED_EXPR) type, such nodes are usually references to child expression nodes, type conversions, etc., and return the same classification as the child node.

[0128] (3.5.6) Determine whether the data access target is external data. If the security policy restricts reading of external data and the data read target is classified as external data, add the source code location corresponding to the current expression node to the external data read location set, otherwise do not add it. If the security policy restricts writing of external data and the data write target is classified as external data, add the source code location corresponding to the current expression node to the external data write location set, otherwise do not add it.

[0129] (3.5.7) Update or maintain the variable classification dictionary based on actual conditions, specifically update or maintain the data classification of the variable corresponding to the data write target: If the data classification of the data read target is an external component data pointer, an internal component data pointer, or a null pointer, then update the data classification of the variable corresponding to the data write target in the variable classification dictionary to the same data classification as the data read target; otherwise, maintain the original classification unchanged.

[0130] At the same time, if the current node type is a return declaration type, the local function return value classification dictionary is updated as needed: If the local function return value classification dictionary does not contain a record of the current function return value or its priority is lower than the priority of the current node type, the corresponding category of the current function return value in the local function return value classification dictionary is updated. The classification priority is: ① External component data pointer, ② Local data pointer, ③ Immediate value or other. If there is no record of the current function return value in the local function return value classification dictionary, and the data classification of the current node is a classification other than pointer type, the data classification of the current function return value in the local function return value classification dictionary is updated to the immediate value classification. If the current node type is not a return declaration type, directly execute step (3.5.8).

[0131] (3.5.8) Determine whether there are any unprocessed expression nodes (i.e., data access targets). If not, execute step (3.5.9); if so, jump to step (3.5.5).

[0132] (3.5.9) Determine whether the function body corresponding to the current compound statement type subnode contains any unprocessed data operation type statement subnodes. If not, execute step (3.5.10); if so, jump to step (3.5.3).

[0133] (3.5.10) Determine whether there are any unprocessed locally defined functions in the set of locally defined functions. If not, execute S3.6; if so, jump to S3.2.

[0134] S3.6: Return a set of source locations containing data streams outside the component.

[0135] The following is an example of the analysis process of S3.1-S3.6. Taking the separation of the Dummy network card driver and the Linux kernel as an example, the following is the source code fragment of the dummy_xmit function of the Dummy network card driver:

[0136] 1: static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)

[0137] 2: {

[0138] 3: struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);

[0139] 4: u64_stats_update_begin(&dstats->syncp);

[0140] 5: dstats->tx_packets++;

[0141] 6: dstats->tx_bytes += skb->len;

[0142] 7: u64_stats_update_end(&dstats->syncp);

[0143] 8: skb_tx_timestamp(skb);

[0144] 9: dev_kfree_skb(skb);

[0145] 10: return NETDEV_TX_OK;

[0146] 11:}

[0147] The following is an excerpt of the textual representation of the function after it is converted into an abstract syntax tree in step 1 (hereinafter referred to as the AST textual representation fragment):

[0148] 1: ---FUNCTION_DECL netdev_tx_t dummy_xmit(struct sk_buff *, structnet_device *)

[0149] 2: |---TYPE_REF netdev_tx_t

[0150] 3: |---PARM_DECL struct sk_buff * skb

[0151] 4: | |---TYPE_REF struct sk_buff

[0152] 5: |---PARM_DECL struct net_device *dev

[0153] 6: | |---TYPE_REF struct net_device

[0154] 7: |---COMPOUND_STMT

[0155] (Lines 8 to 29 omitted)

[0156] 30: | |---COMPOUND_ASSIGNMENT_OPERATOR unsigned long long

[0157] 31: | | |---MEMBER_REF_EXPR unsigned long long dstats->tx_bytes

[0158] 32: | | | |---UNEXPOSED_EXPR struct pcpu_dstats * dstats

[0159] 33: | | | | |---DECL_REF_EXPR struct pcpu_dstats * dstats

[0160] 34: | | |---UNEXPOSED_EXPR unsigned long long skb->len

[0161] 35: | | | |---UNEXPOSED_EXPR unsigned int skb->len

[0162] 36: | | | | |---MEMBER_REF_EXPR unsigned int skb->len

[0163] 37: | | | | | |---UNEXPOSED_EXPR struct sk_buff * skb

[0164] 38: | | | | | | |---DECL_REF_EXPR struct sk_buff * skb

[0165] (Omitted below)

[0166] Each line of the AST text representation fragment represents an abstract syntax tree node, and the parent-child relationship between the nodes is represented by the indentation relationship. In this example, it is assumed that after the analysis of S2.2, the dummy_xmit function is judged to be an exported component external function in the exported component external function set. The method of S3.4 is used to identify the classification of the incoming parameters: all the parameter declaration type child nodes in the abstract syntax tree node of the function are traversed, and it is found that it contains two pointer type parameters that are not function pointers (lines 3-6 of the AST text representation fragment). Since the type of the pointer reference is a data type (struct sk_buff and struct net_device), and dummy_xmit is an exported component external function, the incoming parameters skb and dev are judged to be component external data pointers.

[0167] Assume the current analysis process reaches the statement "dstats->tx_bytes += skb->len" on line 6 of the function source code fragment, corresponding to lines 30-38 of the AST text representation. Furthermore, the analysis of lines 8-29 of the AST text representation has confirmed that the variable dstats is a pointer to data outside the component. Using the recursive deduction method of S3.5, based on line 30 of the AST text representation, we determine that this statement is a compound assignment (COMPOUND_ASSIGNMENT_OPERATOR) with the operator "+=". Therefore, its first child node, dstats->tx_bytes, is the data read / write target, and its second child node, skb->len, is the data read target (step 3.5.4).

[0168] According to line 31 of the AST text representation fragment, the data read and write target dstats->tx_bytes in this statement is a member reference (MEMBER_REF_EXPR) type node. Because the node dstats, which is used to refer to the parent variable element, has been confirmed in previous analysis to be an external data pointer, dstats->tx_bytes is external data, and this expression includes external reads and writes.

[0169] The data read target skb->len of this statement was originally of type unsigned int (line 34 of the AST literal representation fragment), and was changed to type unsigned long through implicit type conversion (lines 34-36 of the AST literal representation fragment). The node representing the result of the implicit type conversion belongs to the unexposed expression type node (line 35 of the AST literal representation fragment), which inherits the classification deduction result of the member reference type node on line 36 of the AST literal representation fragment. Since skb has been confirmed to be classified as an external data pointer in the previous analysis, skb->len is external data, and this expression contains an external read.

[0170] Based on the analysis of the statement on line 6 of the function source code snippet, add the source code locations corresponding to the "dstats->tx_bytes" and "skb->len" strings to the external component data read location set, and add the source code location corresponding to "dstats->tx_bytes" to the external component data write location set.

[0171] Those skilled in the art will understand that the foregoing descriptions are merely preferred embodiments of the invention and are not intended to limit the invention. Although the invention has been described in detail with reference to the foregoing examples, those skilled in the art will still be able to modify the technical solutions described in the foregoing examples or substitute equivalents for some of the technical features therein. Any modifications, equivalent substitutions, etc. made within the spirit and principles of the invention shall be included within the scope of protection of the invention.

Claims

1. A method for identifying data flows outside a component based on static analysis, characterized in that: The following steps are involved: Step 1: Read the component source code file, perform lexical and grammatical analysis on it, obtain the token information contained in the component source code and generate an abstract syntax tree; Step 2: Based on the token information and abstract syntax tree, obtain the function attributes in the component source code. Function attributes include: whether it is a function defined in the component source code, whether it is a function imported from outside the component, and whether it is a function exported outside the component. Step 3: Identify external component data flows contained in the component source code: Traverse the abstract syntax tree corresponding to the locally defined functions contained in the component source code, and maintain the classification and pointing information of the nodes during the traversal process; for statements in the abstract syntax tree that contain data update operations, determine the data classification of their data access targets; if the data is external component data, add the source code location corresponding to the statement to the source code location set containing external component data flows; after completing the traversal, return the source code location set containing external component data flows; The step 2 is specifically implemented through the following sub-steps: S2.1: Identify function definitions and macro definitions in the component source code, obtain and return the set of locally defined functions; S2.2: First, initialize the imported component external function set and the exported component external function set to be empty; based on the locally defined function set, identify the non-component defined functions called by the component source code, obtain and return the imported component external function set; Get and initialize the imported component external function set and the exported component external function set. For all locally defined functions in the locally defined function set, determine whether they have the possibility of being called by external components and whether they meet the characteristics of exported functions. If at least one of them is judged as yes, add it to the exported component external function set. Otherwise, ignore the locally defined function.

2. The method for identifying external component data flows based on static analysis according to claim 1, characterized in that: S2.1 specifically obtains and returns a set of locally defined functions through the following operations: Initialize the local definition function set to be empty; for each translation unit node generated based on the component source code, traverse all function declaration type nodes and macro definition type nodes contained in the translation unit node; For a function declaration type node, determine whether it contains a compound statement type child node. If so, add the function name declared by the function declaration type node to the local definition function set. If not, ignore the function declaration type node. For a macro definition type node, determine whether it is a macro function. If so, add the macro name corresponding to the macro function to the local definition function set. If not, ignore the macro definition type node. Returns the set of locally defined functions.

3. The method for identifying external component data flows based on static analysis according to claim 1, characterized in that: S2.2 specifically obtains and returns the imported component external function set through the following operations: For each function in the locally defined function set, obtain its function body, collect all identifier category lexical units contained in the function body, and obtain the abstract syntax tree node corresponding to the lexical unit; for each abstract syntax tree node obtained, determine its category; If the abstract syntax tree node is a function reference type node, the referenced object is a function declaration type node, and the function prototype declared by the function declaration type node is defined outside the component source code directory, then the function name is added to the set of imported external component functions; If the abstract syntax tree node is a macro instantiation type node, if the macro defined by the macro definition type node it references is a macro function and the name of the macro function is not in the local definition function set, add it to the imported component external function set; Finally, the set of imported component external functions is returned.

4. The method for identifying external component data flows based on static analysis according to claim 1, characterized in that: In S2.2, the features of exporting a function include: the function is included in the interface header file of the component; for a Linux kernel module type component, the function is exported by a macro.

5. The method for identifying external component data flows based on static analysis according to claim 1, characterized in that: The step three is specifically implemented through the following sub-steps: S3.1: Initialize the source code location set containing the component's external data stream and the local function return value classification dictionary to be empty; S3.2: Get an unprocessed locally defined function and obtain its corresponding function declaration type abstract syntax tree node; S3.3: Initialize the variable classification dictionary to be empty, which is used to record the abstract syntax tree node classification corresponding to each variable in the locally defined function; S3.4: Identify the incoming parameter classification, and add the incoming parameter and its classification to the variable classification dictionary; S3.5: Analyze the data operations contained in the function body and update the source code location set containing the data flow outside the component: First, obtain the compound statement type child node of the function declaration type abstract syntax tree node, and the content of this child node is the function body; For each data operation type statement sub-node in the function body, identify its data access target, and determine the classification of the expression corresponding to each data operation type statement sub-node as the operation object through recursive deduction; if the expression includes access to data outside the component, then add the source code position range corresponding to the abstract syntax tree node to which it belongs to the source code position set containing the data flow outside the component; if the data operation type statement includes an operation to initialize a variable or change the variable classification, then update the variable classification dictionary according to the operation; S3.6: Return a set of source locations containing data streams outside the component.

6. The method for identifying external component data flows based on static analysis according to claim 5, characterized in that: S3.5 is specifically implemented through the following sub-steps: (3.5.1) Get an unprocessed compound statement type child node of the current function declaration type abstract syntax tree node; (3.5.2) Determine the type of each child node of the current compound statement type child node to determine whether the current child node contains a data operation, and filter to obtain a data operation type statement child node; (3.5.3) Get an unprocessed data operation type statement child node; (3.5.4) Identifying a data access target in the current subnode based on the type and identifier of the current data operation type statement subnode; the data access target includes a data read target and a data write target; (3.5.5) For data read and write targets, perform recursive classification deduction based on classification rules. This means that shallow-level results are judged based on deep-level results to obtain the data classification for each data access target node. (3.5.6) Determine whether the data access target is external data. If the security policy restricts reading external data and the data read target is classified as external data, add the source code location corresponding to the current abstract syntax tree node to the external data read location set; otherwise, do not add it. If the security policy restricts writing external data and the data write target is classified as external data, add the source code location corresponding to the current abstract syntax tree node to the external data write location set; otherwise, do not add it. (3.5.7) Update or maintain the variable classification dictionary based on actual conditions. Specifically, update or maintain the data classification of the variable corresponding to the data write target. If the data classification of the data read target is an external component data pointer, an internal component data pointer, or a null pointer, update the data classification of the variable corresponding to the data write target in the variable classification dictionary to the same data classification as the data read target. Otherwise, maintain the original classification. At the same time, if the current node type is a return declaration type, the local function return value classification dictionary is updated as needed: If the local function return value classification dictionary does not contain a record of the current function return value or the priority is lower than the priority of the current node type, the corresponding category of the current function return value in the local function return value classification dictionary is updated; the classification priority is ranked as follows: ① external component data pointer, ② local data pointer, ③ immediate value or other; If the local function return value classification dictionary does not contain a record of the current function return value, and the data classification of the current node is a classification other than pointer type, the data classification of the current function return value in the local function return value classification dictionary is updated to the immediate value classification; If the current node type is not a return declaration type, directly execute step (3.5.8); (3.5.8) Determine whether there is any unprocessed data accessing the target node. If not, proceed to step (3.5.9). If so, jump to step (3.5.5). (3.5.9) Determine whether the function body corresponding to the current compound statement type subnode contains any unprocessed data operation type statement subnodes. If not, proceed to step (3.5.10). If so, jump to step (3.5.3). (3.5.10) Determine whether there are any unprocessed locally defined functions in the set of locally defined functions. If not, execute S3.6; if so, jump to S3.

2.

7. The method for identifying external component data flows based on static analysis according to claim 6, characterized in that: In step (3.5.3), determine whether the current child node meets any of the following attribute requirements. If so, determine that the current child node contains data operations and proceed to step (3.5.4); otherwise, ignore the current child node and proceed to the next child node. The attribute requirements are as follows: ① The type is variable declaration, compound assignment or conditional operation; ② The type is a binary operation and the operator corresponding identifier is "=" or "=="; ③ The type is a unary operation and the operator corresponding identifier is "++" or "--"; ④Type is return statement; In step (3.5.4), the data read target and data write target are determined according to the following rules: ① For variable declaration type nodes, the data write target is the first child node, and the data read target is the last child node; ②For compound assignment type nodes, the data write target is the first child node, and the data read target is the first and second child nodes; ③For conditional operation type nodes, the data write target is the first child node, and the data read target is the remaining child nodes; ④ For a binary operation node whose operator corresponding identifier is "=", its data write target is the first child node, and its data read target is the second child node; ⑤For binary operation nodes whose operator corresponding identifier is "==", there is no data write target, and the data read target is all child nodes; ⑥ For unary operation nodes whose operator corresponding identifier is "++" or "--", the data read and write targets are both the first child node; ⑦ For the return statement type node, there is no data write target, and the data read target is the first child node; In the above step (3.5.5), the classification rules for data read targets and write targets are as follows: ① For variable declaration type nodes, if they are pointer types and the initial value of the reference is defined in a source code file outside the component, the return classification is external component data pointer; If it is a pointer type and the referenced initial value is defined in the current component source code directory, the return type is a local data pointer; If it is a pointer type and has no initial value, the return type is a null pointer; if it is a non-pointer type, the return type is local data; ② For function call type nodes, if the referenced function has a corresponding key value in the local function return value classification dictionary, its key value is returned; if the referenced function does not appear in the local function return value classification dictionary, 1) if its return value is a pointer type and a function pointer type, if the referenced function is a local function, the return classification is a local function pointer, otherwise the return classification is an external component function pointer; 2) if its return value is a pointer type and not a function pointer type, if the referenced function is a local function, the return classification is a local data pointer, otherwise the return classification is an external component data pointer; 3) if its return value is not a pointer type, the return classification is an immediate value; ③ For array index type nodes, if the child node used to refer to the parent variable element is classified as a component external data pointer, the return type is classified as component external data; otherwise, the return type is classified as local data; ④ For member reference type nodes, if the child node used to refer to the parent variable element is classified as external component data or external component data pointer, the return classification is external component data; if the node used to refer to its parent variable element is classified as local data or local data pointer, the return classification is local data; ⑤ For type conversion nodes, the classification of the last child node is returned first. If the classification of the last child node is not recognized, if the child node data type is a function pointer, the returned classification is an external component function pointer; if the child node data type is a pointer type but not a function pointer, the returned classification is an external component data pointer; if the child node data type is other non-pointer types, the returned classification is an immediate value; ⑥ For a unary operation type node, if its operator is a unary arithmetic operation, the child node is external data and the security policy restricts external data writing, then the source code position corresponding to the current abstract syntax tree node is added to the external data write operation position set, and its child node classification is returned; if its operator is a reference operation, when it is classified as external data, the return classification is external data pointer, when it is classified as local data, the return classification is local data pointer, for other classifications, the return classification is external data pointer; if its operator is a dereference operation, when it is classified as external data pointer, the return classification is external data, when it is classified as local data pointer, the return classification is local data, for other classifications, the return classification is external data; if its operator is a unary logical operation, the return classification is immediate value; ⑦ For a binary operation type node, if its operator is a binary arithmetic operation, the classification of its first child node is returned as the classification of the data access target node; if it is another type of binary operation node, the returned classification is an immediate value; ⑧For a conditional operation type node, first obtain the categories of all its child nodes that are data read targets, and return the category with the highest priority among the node categories; the category priority is as follows: 1) external component data pointer; 2) local data pointer; 3) external component data; 4) local data; 5) immediate data; ⑨For nodes that do not expose the expression type, return the same category as the child node.

8. The method for identifying external component data flows based on static analysis according to claim 6, characterized in that: In the step (3.5.5), for the expression node N that is the data access target, the calculation function F(N) of its data classification is inferred, which is specifically implemented through the following sub-steps: (3.5.5.1) Determine whether N is a leaf node. If N is a leaf node, directly infer N's classification according to the classification rules; otherwise, execute (3.5.5.2); (3.5.5.2) N is a non-leaf node, and all its direct expression child nodes C1, C2…C n , calculate F(C1), F(C2)…F(C n ); (3.5.5.3) Derivation of result set {F(C1),F(C2),...,F(C n )}, infer the data classification of N according to the classification rules.

9. A component external data flow identification system based on static analysis, used to implement the component external data flow identification method based on static analysis according to any one of claims 1 to 8, characterized in that: include: Abstract syntax tree generation module, function attribute judgment module, component external data flow identification module; The abstract syntax tree generation module is used to perform lexical analysis and grammatical analysis on the component source code file, obtain the token information contained in the component source code and generate an abstract syntax tree; The function attribute judgment module is used to obtain the function attributes in the component source code according to the token information and the abstract syntax tree; The component external data flow identification module is used to traverse the abstract syntax tree corresponding to the locally defined function contained in the component source code, and maintain the classification and pointing information of the node during the traversal process; For statements in the abstract syntax tree that contain data update operations, determine the data classification of its data access target. If it is external component data, add the source code position corresponding to the statement to the source code position set containing external component data flows. After the traversal is completed, return the source code position set containing external component data flows.

Citation Information

Patent Citations

  • Stain tracking analysis method based on syntax tree

    CN115758347A