Service scheduling method and system of modular network controller
By injecting information flow isolation and dynamic gatekeeper code during the class loading phase of the modular network controller, a formal model is constructed for model checking, which solves the reflection blind spot problem in cross-module service scheduling and achieves complete isolation of information flow and compatibility with dependency injection frameworks.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- CHINA UNICOM INTERNET OF THINGS CO LTD
- Filing Date
- 2026-06-02
- Publication Date
- 2026-07-14
AI Technical Summary
Existing modular network controllers have reflection blind spots in cross-module service scheduling, resulting in incomplete information flow control, inability to effectively isolate malicious modules from object injection and internal reference theft, and dependency injection frameworks cannot function properly.
By rewriting bytecode to identify cross-module interface call points, injecting information flow isolation code and dynamic gatekeeper code, constructing a formal model for model checking, ensuring the completeness of information flow operations, and injecting minimum-overhead dynamic gatekeeper code during class loading, the system achieves tag verification and isolation for cross-module service scheduling.
It achieves the elimination of reflection blind spots in cross-module service scheduling while retaining the reflection mechanism, ensuring the integrity of information flow control and the normal function of the dependency injection framework, and preventing the transfer of objects by malicious modules.
Smart Images

Figure CN122394956A_ABST
Abstract
Description
Technical Field
[0001] This invention belongs to the field of computer technology, and in particular relates to a service scheduling method and system for a modular network controller. Background Technology
[0002] Modular network controllers based on Java commonly rely on frameworks like Spring to implement service dependency injection and dynamic proxy calls via reflection when integrating third-party modules. Existing cross-module security isolation solutions fall into two categories: one eliminates the dynamic call blind spot by blocking the reflection API, but this prevents dependency injection frameworks from functioning correctly, resulting in poor practicality; the other uses static bytecode analysis to inject isolation code during class loading, but the target method of the reflection call point cannot be determined at the static stage, causing information flow tracing to be interrupted at the reflection boundary. Malicious modules can still inject private objects into other modules or steal internal references through reflection, creating a reflection blind spot. Furthermore, implicit data flow channels such as method handle calls and exception propagation and thread-local variable passing are also difficult to cover by existing static solutions due to the lack of static call targets. Therefore, how to eliminate reflection blind spots and achieve mandatory control over the information flow of all cross-module object passing paths while retaining the reflection mechanism to maintain compatibility with mainstream dependency injection frameworks has become a pressing technical problem. Summary of the Invention
[0003] This disclosure provides a service scheduling method and system for a modular network controller. In order to solve the problem of how to retain the reflection mechanism to be compatible with the dependency injection framework, while ensuring that the information flow of cross-module service scheduling in the modular network controller is isolated without reflection blind spots, this disclosure provides a service scheduling method and system for a modular network controller.
[0004] This application first provides a service scheduling method for a modular network controller, including: When loading the class of the module in the network controller, cross-module interface call points are identified by bytecode rewriting and information flow isolation code is injected. The information flow isolation code is used to apply transmission control based on module tags to the call parameters or return values. For the reflection invocation instructions and method handle invocation instructions in the bytecode of the class, dynamic gatekeeper code is generated and injected based on formal methods; Based on the injected information flow isolation code and the dynamic gatekeeper code, service scheduling between modules in the network controller is performed, wherein the object passing in the cross-module service request is subject to tag verification and isolation processing via the injected information flow isolation code and the dynamic gatekeeper code.
[0005] Optionally, for the reflection invocation instructions and method handle invocation instructions in the bytecode of the class, dynamic gatekeeper code is generated and injected based on formal methods, including: Construct a formal model of information flow operations that covers reflection calls, method handle calls, and implicit data flow channels; Convert the current module's bytecode into an abstract state diagram that reflects tag propagation; The abstract state diagram is model checked to verify the completeness of the information flow control strategy in the reflection call and method handle call, and the uncovered injection points are filled in using counterexample paths until the completeness proof is passed. Redundancy identification is performed on the label verification of the injected points based on the proven state diagram. Verifications that can be proven to be true are removed, records and isolation actions are retained, the final dynamic gatekeeper code is synthesized, and injected into the class bytecode. The formal model of information flow operation is a semantic model that defines the rules of label state change under reflection call, method handle call and implicit data flow operation. The abstract state diagram is a finite state diagram extracted from the bytecode that represents the relationship between control flow and label propagation. Optionally, the step of identifying cross-module interface call points and injecting information flow isolation code through bytecode rewriting includes: Extract the method signatures of cross-module service interfaces based on the module dependency descriptor, and build a whitelist; Traverse the class bytecode, identify the call instructions for methods in the whitelist, and mark them as static cross-module entry or exit points; Depending on how the receiving module uses the incoming object, select to inject read-only proxy to generate code, copy-on-write to generate code, or deep copy to generate code.
[0006] Optionally, the step of selecting to inject read-only proxy generated code, copy-on-write generated code, or deep copy generated code based on the receiving module's usage of the incoming object includes: Analyze the field access and method call behavior of the incoming object within the receiving module. If only read operations are involved, inject read-only proxy to generate code. If local modification operations are involved, inject copy-on-write to generate code. If cross-module propagation occurs, inject deep copy to generate code.
[0007] Optionally, the construction of a formal model for information flow operations encompassing reflection calls, method handle calls, and implicit data flow channels includes: Reflection calls, method handle calls, exception propagation, and thread-local variable passing operations are categorized as information flow operations. Pre-label conditions and post-label effects are defined for each type of operation, forming a formal semantic rule set.
[0008] Optionally, the step of converting the current module bytecode into an abstract state diagram reflecting tag propagation includes: Perform context-sensitive pointer analysis and control flow analysis on module bytecode to identify reflection call points and implicit data flow channels; Create a control flow graph for each method, and add abstract label variables to the control flow graph for parameters and return values; The abstract label variable is propagated along the control flow graph to generate a finite state graph with the label state as the node.
[0009] Optionally, the step of performing model checking on the abstract state diagram to verify the coverage completeness of the information flow control strategy on the reflection call and method handle call, and using counterexample paths to fill in the uncovered injection points until the completeness proof passes, includes: The label verification and isolation actions required by the information flow control strategy are expressed as computation tree logical properties; Model checks are performed in the abstract state diagram to find counterexample paths that violate the logical properties of the computation tree; Based on the counterexample path, the missing information flow control injection point is identified, supplementary injection rules are automatically generated, and the abstract state graph is updated. The check is repeated until no violation is found.
[0010] Optionally, the step of performing redundant identification on the label verification of the injected points based on the proven state diagram and removing verifications that can be proven to be always true includes: For each tag verification point, the parameter tag abstract values reaching that verification point are collected in reverse. If the parameter label meets the allowed conditions of the information flow policy on all paths, the verification point is marked as redundant, and the verification instruction is removed when synthesizing the dynamic gatekeeper code, while retaining the label record and object isolation instruction.
[0011] Optionally, the process of generating and injecting dynamic gatekeeper code based on formal methods further includes: Identify whether the caller class contains a framework dependency injection pattern; When the aforementioned pattern exists, the corresponding reflection call point is marked as a trusted assembly, and the tag verification is skipped in the generated dynamic gatekeeper code, while retaining read-only proxy or deep copy processing of the return value.
[0012] Optionally, the process of performing service scheduling between modules in the network controller further includes: A pre-check instruction is injected into the modification method of the container class used within the module. The pre-check instruction obtains the container's owning module and the tag of the value to be written. When the tag is not allowed to flow to the owning module, the modification operation is blocked.
[0013] This application further provides a service scheduling system for a modular network controller, including a module class loader and a bytecode processing component. The module class loader is used to load the class files of all functional modules in the network controller, and the bytecode processing component is used to execute the method as described above.
[0014] As can be seen from the above technical solution, this application identifies cross-module interface call points and injects information flow isolation code by rewriting bytecode during class loading, so that statically declared cross-module calls are strengthened at the compiled bytecode level without the need for additional runtime detection. For reflection calls and method handle calls, a formal model of information flow operations covering implicit data flow channels such as reflection, method handle calls, and exception propagation is first constructed. Then, the module bytecode is converted into an abstract state diagram reflecting label propagation, thereby abstracting the complex control flow and data flow in the actual bytecode into a finite state model. Subsequently, the abstract state diagram is model checked, and the coverage completeness of the information flow control strategy on all reflection call and method handle call paths is mathematically verified using the logical properties of computational trees. The uncovered injection points are automatically filled in according to the counterexample paths until the proof is passed, thereby eliminating the reflection blind spot. Based on the proof completeness, by analyzing the abstract values of the parameter labels of each injection point on all feasible paths, label checks that can be proven to be true are identified and removed, and only necessary records and isolation actions are retained to synthesize dynamic gatekeeper code with minimal overhead. When performing service scheduling, the statically injected isolation code handles cross-module interface calls directly, while the synthesized dynamic gatekeeper code precisely intercepts object transmission on all reflection and implicit flow paths. Both share a unified module label and information flow strategy, which forces label verification and isolation processing for any cross-module object transmission regardless of the calling method used, thereby achieving information flow control without reflection blind spots, while fully preserving the normal functions of the reflection mechanism and dependency injection framework. Attached Figure Description
[0015] To more clearly illustrate the technical solutions in the embodiments of this disclosure or the prior art, the drawings used in the description of the embodiments or the prior art will be briefly introduced below. Obviously, the drawings described below are some embodiments of this disclosure. For those skilled in the art, other drawings can be obtained based on these drawings without creative effort.
[0016] Figure 1 This is a flowchart of a service scheduling method for a modular network controller according to an embodiment of this disclosure; Figure 2 This is a flowchart of one of the sub-steps of a service scheduling method for a modular network controller in an embodiment of this disclosure; Figure 3 This is the second flowchart of a sub-step of a service scheduling method for a modular network controller in an embodiment of this disclosure; Figure 4 This is the third flowchart of a sub-step of a service scheduling method for a modular network controller in an embodiment of this disclosure; Figure 5This is the fourth flowchart of a sub-step of a service scheduling method for a modular network controller in an embodiment of this disclosure; Figure 6 This is the fifth flowchart of a sub-step of a service scheduling method for a modular network controller in an embodiment of this disclosure; Figure 7 This is a schematic diagram of a service scheduling system for a modular network controller in an embodiment of this disclosure. Detailed Implementation
[0017] In the following description, specific details such as particular system architectures and techniques are set forth for illustrative purposes and not for limitation, so as to provide a thorough understanding of the embodiments of this disclosure. However, those skilled in the art will understand that this disclosure may also be implemented in other embodiments without such specific details. In other instances, detailed descriptions of well-known systems, apparatuses, circuits, and methods have been omitted so as not to obscure the description of this disclosure with unnecessary detail.
[0018] This embodiment provides a service scheduling method for a modular network controller, such as... Figure 1 As shown, it includes: S1: When loading the class of the module in the network controller, the cross-module interface call point is identified by bytecode rewriting and information flow isolation code is injected. The information flow isolation code is used to apply the transmission control based on module tag to the call parameters or return values.
[0019] The modules in the network controller refer to the log management module, configuration management module, alarm handling module, and traffic scheduling module. Each module is an independent JAR file, which is dynamically loaded and run through the module class loader.
[0020] S2: Generate dynamic gatekeeper code based on formal methods and inject the reflection invocation instructions and method handle invocation instructions in the bytecode of the class; S3: Based on the injected information flow isolation code and the dynamic gatekeeper code, perform service scheduling between modules in the network controller, wherein the object transmission in the cross-module service request is subject to tag verification and isolation processing via the injected information flow isolation code and the dynamic gatekeeper code.
[0021] In this embodiment, the service scheduling method for a modular network controller is applied to a virtual machine-based modular network controller architecture. This network controller employs a layered and decoupled modular design, with each functional module existing as an independent module unit. Modules interact through standardized service interfaces. The core operating environment of the network controller is a standard virtual machine, and module loading and initialization are uniformly managed by the network controller's built-in module class loader. When loading the class file of each module, the module class loader calls a bytecode processing component to preprocess the class bytecode, injecting information flow isolation code and dynamic gatekeeper code.
[0022] It should be noted that the bytecode processing component can be implemented using a bytecode manipulation framework, which parses and modifies bytecode through a bytecode manipulation toolkit. The bytecode processing component performs a rewrite operation when a class is first loaded. Once the class is loaded into the virtual machine, subsequent use of the class will directly use the class object that has already been injected with isolation code, without the need for repeated processing.
[0023] In this embodiment, the module class loader is responsible for loading the class files of all functional modules in the network controller. When the module class loader receives a request to load a class, it first reads the bytecode data of that class from the module's archive file, and then passes the bytecode data to the bytecode processing component. The bytecode processing component parses and modifies the bytecode data, injects information flow isolation code and dynamic gatekeeper code, and then returns the modified bytecode data to the module class loader. The module class loader uses the modified bytecode data to define a class object and loads the class object into the virtual machine. This method of bytecode rewriting during the class loading stage allows the information flow isolation logic to be transparently embedded into the module's code without modifying the module's source code or affecting the module's normal compilation process. Bytecode rewriting allows for instruction-level modification, insertion, or replacement of the .class bytecode file generated by Java compilation during the class loading stage, injecting custom logic before runtime without modifying the source code; this is a static enhancement technique. For example, using tools like ASM and Javassist, a tag verification bytecode instruction can be inserted before the invokeinterface instruction during class loading to complete isolated logic injection.
[0024] In this embodiment, when loading the class of a module in the network controller, cross-module interface call points are identified and information flow isolation code is injected through bytecode rewriting. The bytecode instruction location where module A calls the exposed service interface of module B is a boundary point of inter-module interaction, a statically identifiable cross-module interaction entry / exit point. For example, when module A calls module B's getConfig(String key) interface, the corresponding bytecode location of the invokestatic / invokeinterface instruction is the cross-module interface call point. The information flow isolation code is used to apply module tag-based transmission control to call parameters or return values. Module tags are used to identify the source module of an object and the set of modules to which the object is allowed to flow. Each object is assigned an initial tag upon creation, which identifies that the object belongs to the module that created it and, by default, is only allowed to be passed within that module. When an object is passed to another module through a cross-module interface, the information flow isolation code checks whether the object's tag allows flow to the target module according to the information flow policy. If allowed, the object's tag is updated, recording the module to which the object has flowed. If not allowed, the transmission operation is blocked and an exception is thrown.
[0025] Specifically, dynamic gatekeeper code is generated and injected based on formal methods for reflection invocation instructions and method handle invocation instructions in the class bytecode. Reflection invocation instructions include calls to methods in the standard reflection API, such as method calls, constructor instantiation, field setting, and field getting. Method handle invocation instructions include calls to methods such as method handle invocation, precise method handle invocation, variable handle setting, and variable handle getting. These invocation instructions do not appear as direct target method calls at the bytecode level; their targets are only determined at runtime. Therefore, they cannot be directly identified and isolated through static bytecode analysis.
[0026] In this embodiment, a formal model of information flow operations is constructed, encompassing reflection calls, method handle calls, and implicit data flow channels. This formal model defines the semantic model of label state change rules under reflection calls, method handle calls, and implicit data flow operations. For example, a reflection call rule could be: Preconditions caller = module A; target = module B; param.allow = {B}; Post-effect return.source = B; Isolation action deny → throw SecurityException. This model abstracts all operations in the virtual machine that could lead to object propagation across module boundaries into formalized operational semantics. Each operation is described by a transformation rule from precondition to post-effect.
[0027] It's important to note that the current module's bytecode is converted into an abstract state graph reflecting label propagation. The abstract state graph is a finite state graph extracted from the bytecode, representing the relationship between control flow and label propagation. For example, in the abstract state graph, node S0 (label = module A) → call reflection → node S1 (label = module B), with edges annotating the call type and label change rules. The construction process of the abstract state graph includes context-sensitive pointer analysis and control flow analysis of the module's bytecode, identifying reflection call points and implicit data flow channels. For example, module A throws an exception, and module B catches and reads data from the exception object; or objects are passed via ThreadLocal, both of which are implicit data flow channels. A control flow graph is created for each method, and abstract label variables are added to the control flow graph for parameters and return values. These abstract label variables are propagated along the control flow graph, generating a finite state graph with label states as nodes.
[0028] Specifically, a model check is performed on the abstract state diagram to verify the completeness of the information flow control strategy in reflection calls and method handle calls. It then uses counterexample paths to fill in any uncovered injection points until the completeness proof is passed. Model checking is an automated formal verification technique that verifies whether the system satisfies a given security property by exhaustively traversing all reachable states of the system. In this embodiment, the model checker traverses all reachable states and paths of the abstract state diagram, checking whether the information flow control strategy is satisfied one by one. If a property is found to be violated in a certain state or path, the model checker generates a counterexample path, which records the complete state transition sequence from the initial state to the state violating the property. Based on this counterexample path, the specific injection point of the missing information flow control can be accurately located. For example, in the counterexample path: Module A → Reflection Call → Module B → Unlabeled Validation → Object Leakage, the reflection call point is identified as the missing injection point. The system automatically generates supplementary injection rules accordingly, bringing this injection point into the coverage of the dynamic gatekeeper. The abstract state diagram is then updated and the model is re-checked. This closed-loop process of checking, completing, and re-checking is repeated until all security properties are verified as true on all reachable paths. Injection points are specific locations in the bytecode where isolation / verification code is inserted. These include static interface call points, reflection / method handle call points, and implicit stream trigger points. For example, the area before a reflection call instruction, the method handle call entry point, and the beginning of a container modification method are all injection points.
[0029] Furthermore, based on the proven state diagram, redundancy identification is performed on the label verification of injected points. Verifications that can be proven to be always true are removed, records and isolation actions are retained, and the final dynamic gatekeeper code is synthesized and injected into the class bytecode. The redundancy identification process utilizes the complete state diagram information already constructed during model checking. To prove completeness, model checking has traversed the label states on all reachable paths within the module. This state information can be used to identify which verifications are redundant. This process, starting from the results of formal verification, reduces the runtime overhead of the dynamic gatekeeper without sacrificing security. Redundancy identification analyzes the verification logic of injected points, identifies verifications that are always true and do not need to be executed on all paths, removes redundant code, and reduces runtime overhead. For example, if a parameter label is an allowed value on all paths, and the verification logic `if(param.allow(target))` is always true, it is marked as redundant.
[0030] In this embodiment, service scheduling between modules in the network controller is performed based on injected information flow isolation code and dynamic gatekeeper code. Object passing in cross-module service requests undergoes tag verification and isolation processing via the injected code. When the first module initiates a service request to the second module, if the call path is a statically declared cross-module interface, the information flow isolation code injected during class loading takes effect directly. If the service request is converted to a reflection call by the framework, the dynamic gatekeeper code intervenes at runtime. If the service request is triggered via a dynamic method handle, the same tag verification and isolation logic is embedded in the guard method handle chain.
[0031] In some embodiments, such as Figure 2 As shown, for the reflection invocation instructions and method handle invocation instructions in the bytecode of the class, dynamic gatekeeper code is generated and injected based on a formal method, including: S201: Construct a formal model of information flow operations covering reflection calls, method handle calls, and implicit data flow channels; S202: Convert the current module bytecode into an abstract state diagram that reflects tag propagation; S203: Perform a model check on the abstract state diagram to verify the completeness of the information flow control strategy in the reflection call and method handle call, and use counterexample paths to fill in the uncovered injection points until the completeness proof is passed; S204: Based on the proven state diagram, perform redundancy identification on the label verification of the injected points, remove verifications that can be proven to be always true, retain records and isolation actions, synthesize the final dynamic gatekeeper code, and inject it into the class bytecode; wherein, the formal model of information flow operation is a semantic model that defines the rules of label state change under reflection call, method handle call and implicit data flow operation, and the abstract state diagram is a finite state diagram extracted from bytecode that represents the relationship between control flow and label propagation.
[0032] In this embodiment, a formal model of information flow operations is constructed, encompassing reflection calls, method handle calls, and implicit data flow channels. The process of constructing this formal model includes classifying reflection calls, method handle calls, exception propagation, and thread-local variable passing operations as information flow operations, defining pre-label conditions and post-label effects for each type of operation, and forming a set of formal semantic rules. Reflection calls include calls to methods in the standard reflection API, such as method calls, constructor instantiation, field setting, and field retrieval. Method handle calls include calls to methods such as method handle invocation, precise method handle invocation, variable handle setting, and variable handle retrieval. Implicit data flow channels include the module traversal path of exception objects between throwing and catching, and the value propagation path of thread-local variables in threads crossing module boundaries.
[0033] It should be noted that for each type of operation, the formal semantic rule set defines three elements: Preconditions for the operation, describing the label state that the parameter object should satisfy before the operation is executed; Post-operation effects, describing the label changes of the parameter object and return value object after the operation is executed; and Isolation actions triggered by the operation, describing the safety measures to be taken when label validation fails. Through this formal modeling, all operation paths in the virtual machine that may lead to cross-module information flow are completely included in a semantic rule set, providing a benchmark for subsequent completeness verification.
[0034] Specifically, the current module bytecode is converted into an abstract state graph reflecting tag propagation. The construction of this abstract state graph involves context-sensitive pointer analysis and control flow analysis of the module bytecode, identifying reflection call points and implicit data flow channels. A control flow graph is created for each method, and abstract tag variables are added to the control flow graph for parameters and return values. These abstract tag variables are propagated along the control flow graph, generating a finite state graph with tag states as nodes. The values of the abstract tag variables are not specific object values, but rather elements representing the abstract domain of object tags, such as the source module identifier and the set of modules to which the object is allowed to flow. Through this abstraction, complex concrete program states are compressed into abstract states related only to information flow, allowing the state space to be reduced to a finite size, thus enabling model checking to be completed in a finite amount of time.
[0035] In this embodiment, a model check is performed on the abstract state diagram to verify the completeness of the information flow control strategy in reflection calls and method handle calls. Missing injection points are filled in using counterexample paths until the completeness proof passes. The model check process includes expressing the label verification and isolation actions required by the information flow control strategy as computational tree logical properties. A model check is performed on the abstract state diagram to find counterexample paths that violate the computational tree logical properties. Missing information flow control injection points are determined based on the counterexample paths, supplementary injection rules are automatically generated, and the abstract state diagram is updated. The check is repeated until no properties are violated.
[0036] It should be noted that computation tree logic is a branch-time logic that describes the path properties in a state transition system. In the embodiments of this application, the computation tree logic properties verified by the model checker include at least the following: for all reachable states, if the current instruction is a reflection call point, its next state must undergo a label verification action. For all method handle call points, the next state must enter the execution of the guarded handle chain. When there is a path for an exception object to propagate across modules, label removal or isolation processing must have been completed on that path.
[0037] Specifically, the model checker exhaustively traverses all reachable states and paths in the abstract state graph, verifying whether the logical properties of the computation tree are satisfied one by one. If a property is found to be violated in a certain state or path, the model checker generates a counterexample path, which records the complete state transition sequence from the initial state to the state violating the property. Based on this counterexample path, the specific injection point of the missing information flow control can be precisely located, including the class name, method name, and bytecode offset. The system automatically generates supplementary injection rules accordingly, bringing the injection point into the coverage of the dynamic gatekeeper. Subsequently, the abstract state graph is updated and the model check is performed again, repeating this closed-loop process of checking, supplementing, and re-checking until all logical properties of the computation tree are verified to be true on all reachable paths. At this point, it means that for all feasible execution paths of this module, the information flow control strategy has achieved full coverage in reflection calls and method handle calls.
[0038] Furthermore, based on the proven state diagram, redundancy identification is performed on the label verification of the injected points. Verifications that can be proven to be tautologically true are removed, while records and isolation actions are retained. The final dynamic gatekeeper code is then synthesized and injected into the bytecode class. The redundancy identification process involves, for each label verification point, collecting the abstract values of the parameter labels arriving at that verification point in reverse. If the parameter label satisfies the allowed conditions of the information flow policy on all paths, the verification point is marked as redundant, and the verification instruction is removed when synthesizing the dynamic gatekeeper code, while the label record and object isolation instruction are retained.
[0039] In this embodiment, the process of synthesizing the final dynamic gatekeeper code refers to generating a customized sequence of recording instructions, verification instructions, and isolation instructions for each reflection call point and method handle call point based on a simplified injection scheme determined after redundancy analysis. For verification points marked as redundant, only tag recording instructions and object isolation instructions are generated; no verification instructions are generated. For verification points not marked as redundant, complete recording, verification, and isolation instructions are generated according to the normal process. The synthesized dynamic gatekeeper code is then injected into the corresponding position in the class bytecode using a bytecode manipulation tool.
[0040] In some embodiments, such as Figure 3 As shown, the step of identifying cross-module interface call points and injecting information flow isolation code through bytecode rewriting includes: S301: Extract the method signatures of cross-module service interfaces based on the module dependency descriptor and build a whitelist; S302: Traverse the class bytecode, identify the call instructions for methods in the whitelist, and mark them as static cross-module entry or exit points; S303: Based on how the receiving module uses the incoming object, select to inject read-only proxy generated code, copy-on-write generated code, or deep copy generated code.
[0041] In this embodiment, method signatures of cross-module service interfaces are extracted based on the module dependency descriptor to construct a whitelist. The module dependency descriptor is a configuration file that records module dependencies, exposed interfaces, and dependent interfaces. It records the other modules that the current module depends on, as well as the service interfaces exposed by these dependent modules. During the construction of each functional module, its externally provided service interfaces and the service interfaces of other dependent modules can be declared in the dependency descriptor. When processing the class bytecode of a module, the bytecode processing component first reads the module's dependency descriptor, parses out the method signatures of the service interfaces of all other modules that the module depends on, and adds these method signatures to the whitelist. For example, method signature = method name + parameter type + return value type; whitelist = a set of signatures allowed for cross-module calls, where only calls within the whitelist can pass static validation. For example, the method signature is `String getConfig(String key)`; the whitelist contains this signature, allowing cross-module calls.
[0042] It's important to note that the whitelist is built based on explicit module dependencies. Only exported interfaces of modules that the current module explicitly depends on are added to the whitelist. This ensures that interactions between modules can only occur through explicitly declared interfaces, preventing implicit interactions between modules through undeclared interfaces.
[0043] Specifically, the bytecode processing component iterates through the class bytecode, identifies call instructions to methods in the whitelist, and marks them as static cross-module entry or exit points. During bytecode traversal, the bytecode processing component parses the class's constant pool, method table, and code attributes. For each bytecode method call instruction, the component retrieves the signature of the called method from the constant pool and compares it with signatures in the whitelist. If the signature of the target method in the method call instruction exists in the whitelist, the instruction is marked as a static cross-module entry or exit point. An entry point indicates that the current module, as a service provider, receives calls from other modules; an exit point indicates that the current module, as a caller, initiates a service request to other modules. Here, entry point = interface point receiving calls from external modules; exit point = interface point initiating calls to external modules, statically identifiable.
[0044] For example, module B's getConfig() is called by module A → B is the entry point and A is the exit point.
[0045] In this embodiment, depending on how the receiving module uses the input object, it selects to inject read-only proxy generated code, copy-on-write generated code, or deep copy generated code. Specifically, the read-only proxy intercepts modification methods, allowing only reading; copy-on-write copies the object upon the first modification, without affecting the original object; and deep copy recursively copies all references, providing complete isolation. For example, the read-only proxy intercepts `setX()` and throws an exception; copy-on-write copies the object upon the first call to `setX()`; and deep copy copies the object and all nested objects.
[0046] This selection process is based on static analysis of the receiving module's bytecode. Static analysis includes control flow and data flow analysis of all methods in the receiving module that receive the object as a parameter. For each instruction to access a field of the passed-in object, it is determined whether the access is a read or write operation. For each method call instruction to the passed-in object, the bytecode of the called method is recursively analyzed to determine whether the called method will modify the state of the passed-in object. Furthermore, the bytecode processing component tracks the passing of the passed-in object within methods. If the passed-in object is passed as a parameter to other methods, assigned to other variables, or stored in a container object, further analysis of subsequent usage is conducted to determine whether the passed-in object will be passed to other modules.
[0047] In some embodiments, selecting to inject read-only proxy generated code, copy-on-write generated code, or deep copy generated code based on the receiving module's usage of the incoming object includes: Analyze the field access and method call behavior of the incoming object within the receiving module. If only read operations are involved, inject read-only proxy to generate code. If local modification operations are involved, inject copy-on-write to generate code. If cross-module propagation occurs, inject deep copy to generate code.
[0048] In this embodiment, the field access and method call behavior of the input object within the receiving module are analyzed. The bytecode processing component performs control flow and data flow analysis on all methods in the receiving module that receive the object as a parameter. For each field access instruction of the input object, it determines whether the access is a read or write operation. For each method call instruction of the input object, the bytecode of the called method is recursively analyzed to determine whether the called method will modify the state of the input object. In addition, the bytecode processing component also tracks the propagation of the input object within methods. If the input object is passed as a parameter to other methods, assigned to other variables, or stored in a container object, further analysis of subsequent usage is conducted to determine whether the input object will be passed to other modules.
[0049] It should be noted that if the analysis results show that the input object only contains read operations within the receiving module, i.e., only field reads and read-only method calls, then read-only proxy generation code is injected. Before calling the target method, the read-only proxy generation code uses a dynamic proxy mechanism to generate a read-only proxy object for the input object. The read-only proxy object holds a reference to the original object. For all read method calls, the read-only proxy object forwards the call to the original object and returns the result. For all modify method calls, the read-only proxy object throws an access denied exception, preventing modification of the original object.
[0050] Specifically, if the analysis results show that the input object contains partial modifications within the receiving module—meaning the input object is modified within the receiving module but the modified object is not passed to other modules—then copy-on-write generation code is injected. This code generates a copy-on-write proxy object for the input object, which initially holds a reference to the original object. When the receiving module calls the modification method for the first time, the proxy object creates a copy of the original object and then forwards all subsequent method calls to the copy object. In this way, modifications made to the object by the receiving module only affect the copy object and not the original object.
[0051] In this embodiment, if the analysis results show that the input object is propagated across modules, meaning the modified object will be passed to other modules, then deep copy generation code is injected. Before calling the target method, the deep copy generation code creates a deep copy object for the input object, recursively copying all other objects referenced by the input object to ensure that there are no shared references between the copy and the original object. The deep copy object's tag is set to a private tag of the receiving module.
[0052] For example, suppose module A depends on a service interface provided by module B. This interface contains a method that processes data, accepting a parameter of type data object and returning a value of type result object. Module A's class file contains a call instruction for this method. When processing module A's class file, the bytecode processing component extracts the method's signature from module A's dependency descriptor and adds it to a whitelist. When iterates through this call instruction, the bytecode processing component recognizes that it belongs to a call to a method in the whitelist and therefore marks it as a static cross-module exit. When injecting the information flow isolation code, the bytecode processing component analyzes how the data processing method in module B uses the data object parameter. If the analysis finds that module B only reads the data object's fields without modifying them, read-only proxy generation code is injected. If module B modifies the data object's fields but the modified data object is not passed out of module B, copy-on-write generation code is injected. If the modified data object is passed by module B to other modules, deep copy generation code is injected.
[0053] In some embodiments, the construction of a formal model for information flow operations encompassing reflection calls, method handle calls, and implicit data flow channels includes: Reflection calls, method handle calls, exception propagation, and thread-local variable passing operations are categorized as information flow operations. Pre-label conditions and post-label effects are defined for each type of operation, forming a formal semantic rule set.
[0054] In this embodiment, reflection calls, method handle calls, exception propagation, and thread-local variable passing are categorized as information flow operations. Pre-label conditions and post-label effects are defined for each type of operation, forming a formal semantic rule set. Reflection calls include calls to methods in the standard reflection API, such as method calls, constructor instantiation, field setting, and field retrieval. Method handle calls include calls to methods such as method handle invocation, precise method handle invocation, variable handle setting, and variable handle retrieval. Implicit data flow channels include the module traversal path of exception objects between throwing and catching, and the value propagation path of thread-local variables in threads crossing module boundaries.
[0055] It should be noted that for each type of operation, the formal semantic rule set defines three elements: Preconditions for the operation, describing the label state that the parameter object should satisfy before the operation is executed; Post-operation effects, describing the label changes of the parameter object and return value object after the operation is executed; and Isolation actions triggered by the operation, describing the safety measures to be taken when label validation fails. Through this formal modeling, all operation paths in the virtual machine that may lead to cross-module information flow are completely included in a semantic rule set, providing a benchmark for subsequent completeness verification.
[0056] Specifically, for the reflection operation of method invocation, the preconditions are that the current thread's module context is identified as the calling module, the method object's label is an access-allowed label for the callee module, and the parameter object's label is an access-allowed label for the target method's module. The post-processing effect is that the return value object's label is set to a private label of the target method's module, and the parameter object's label is updated accordingly based on the method's execution. The isolation action is to block the method invocation and throw a safety exception when the parameter object's label does not allow access to the target method's module.
[0057] In this embodiment, for the reflection operation of constructor instantiation, the preconditions are that the current thread's module context is identified as the calling module, the constructor object's label is a label that allows access by the called module, and the parameter object's label is a label that allows flow to the module where the constructor resides. The post-processing effect is that the newly created object's label is set to a private label of the module where the constructor resides, and the parameter object's label is updated accordingly based on the constructor's execution. The isolation action is that when the parameter object's label does not allow flow to the module where the constructor resides, the constructor call is blocked and a safety exception is thrown.
[0058] Furthermore, for the reflection operation of setting a field, the preconditions are that the current thread's module context is identified by the calling module, the field object's label is a label that allows access by the called module, and the value object to be set is a label that allows flow to the module to which the field object belongs. The post-processing effect is that the label of the field object is updated accordingly based on the label of the value object being set. The isolation action is to block the field setting operation and throw a safety exception when the label of the value object to be set does not allow flow to the module to which the field object belongs.
[0059] In this embodiment, the preconditions for the field retrieval reflection operation are that the current thread's module context is identified as the calling module, and the field object's label is a label that allows the called module to access it. The post-processing effect is that the return value object's label is set to a private label of the module to which the field object belongs. The isolation action is to block the field retrieval operation and throw a security exception when the field object's label does not allow access by the calling module.
[0060] It's important to note that the preconditions for method handle invocation are: the current thread's module context is identified as the calling module, the method handle object's label is set to allow access by the called module, and the parameter object's label is set to allow access to the module containing the target method. The post-implementation effect is that the return value object's label is set to a private label of the module containing the target method, and the parameter object's label is updated accordingly based on the method's execution. The isolation action is to block the method handle invocation and throw a safety exception when the parameter object's label does not allow access to the module containing the target method.
[0061] Specifically, for the implicit data flow operation of exception propagation, the prerequisite is that the exception object's label contains the identifier of the module that threw the exception. The post-event effect is that when the exception object is caught by the exception handler of another module, the exception object's label is updated to include the identifier of the module that caught the exception. The isolation action involves clearing sensitive labels from the exception object that do not belong to the throwing module before the exception is thrown, when the exception object's label is not allowed to flow to the module that caught the exception.
[0062] In this embodiment, for the implicit data stream operation of passing thread-local variables, the precondition is that the label of the value object of the thread-local variable contains the module identifier that sets the value. The post-condition is that when code from another module reads the value of the thread-local variable, the label of the value object is updated to include the module identifier that reads the value. The isolation action is to return null or throw a safety exception when the label of the value object of the thread-local variable does not allow flow to the module reading the value.
[0063] In some embodiments, the conversion of the current module bytecode into an abstract state diagram reflecting tag propagation, such as... Figure 4 As shown, it includes: S401: Performs context-sensitive pointer analysis and control flow analysis on module bytecode to identify reflection call points and implicit data flow channels; S402: Create a control flow graph for each method and add abstract label variables to the control flow graph for parameters and return values; S403: Propagate abstract label variables along the control flow graph to generate a finite state graph with label states as nodes.
[0064] In this embodiment, context-sensitive pointer analysis and control flow analysis are performed on the module bytecode to identify reflection call points and implicit data flow channels. Context-sensitive pointer analysis is a pointer analysis technique that can distinguish different call contexts and more accurately determine the object pointed to by the pointer. Control flow analysis is a technique for analyzing the execution order of instructions in a program and can construct the program's control flow graph. Through context-sensitive pointer analysis and control flow analysis, all reflection call points and implicit data flow channels in the module bytecode can be accurately identified. For example, pointer analysis traces the flow of `obj` from module A to module B; control flow analysis identifies reflection call points in if-else branches.
[0065] It should be noted that a control flow graph is created for each method, and abstract label variables are added to the control flow graph for parameters and return values. Abstract labels are symbolic variables representing object labels; they do not store concrete values but only represent the label state, used for constructing abstract state graphs. For example, the abstract label variable L1 represents the label state "from module A, flow to module B is allowed".
[0066] A control flow graph is a directed graph representing the control flow of a program, where nodes represent basic blocks and edges represent control flow transfers between basic blocks. A basic block is a continuous sequence of instructions with only one entry point and one exit point, and execution can only proceed from the entry point to the exit point. Abstract label variables are added to parameters and return values in the control flow graph to track the propagation of these labels throughout the program.
[0067] Specifically, abstract label variables are propagated along the control flow graph, generating a finite state graph with label states as nodes. The propagation of abstract label variables follows the rules defined in the formal semantic rule set. For each basic block in the control flow graph, the value of the abstract label variable is updated according to the instruction type and operands in the basic block. When a branch instruction is encountered, the value of the abstract label variable is split according to the branch condition. When a merge node is encountered, the value of the abstract label variable is merged. In this way, a finite state graph with label states as nodes can be generated, which fully describes the propagation of object labels along all feasible execution paths within the module.
[0068] In this embodiment, the value of the abstract label variable is not a specific object value, but rather an element in the abstract domain representing the object label, such as the source module identifier and the set of modules to which the object is allowed to flow. Through this abstraction, complex specific program states are compressed into abstract states that are only related to the information flow, allowing the state space to be reduced to a finite size, thereby enabling model checking to be completed in a finite amount of time.
[0069] Furthermore, during the construction of the abstract state graph, the state space can be further compressed by merging equivalent labeled states. Equivalent labeled states refer to those labeled states that exhibit the same behavior under the information flow control strategy. By merging equivalent labeled states, the number of nodes in the state graph can be significantly reduced, improving the efficiency of model checking.
[0070] In some embodiments, the abstract state diagram is model-checked to verify the completeness of the information flow control strategy's coverage of reflection calls and method handle calls, and counterexample paths are used to fill in uncovered injection points until the completeness proof passes. Figure 5 As shown, it includes: S501: Express the tag verification and isolation actions required by the information flow control strategy as computation tree logic properties; S502: Perform model checks in the abstract state diagram to find counterexample paths that violate the logical properties of the computation tree; S503: Determine the missing information flow control injection point based on the counterexample path, automatically generate supplementary injection rules, update the abstract state graph, and repeat the check until there are no violations.
[0071] In this embodiment, the label verification and isolation actions required by the information flow control strategy are expressed as computation tree logic properties. Computation tree logic is a branch-time logic that can describe the path properties in a state transition system. For example, the CTL formula AG(reflection call → label verification) means that label verification must be performed before all paths and all reflection calls. Computation tree logic uses path quantifiers and temporal operators to describe the properties of the system. Path quantifiers include universal path quantifiers and existential path quantifiers, which respectively represent all paths and the existence of a certain path. Temporal operators include next operator, always operator, final operator, until operator, etc., which respectively represent the next state, all subsequent states, a certain subsequent state, and until a certain state.
[0072] It should be noted that model checking is performed in the abstract state graph to find counterexample paths that violate the logical properties of the computation tree. The model checker traverses all reachable states and paths in the abstract state graph, checking whether the logical properties of the computation tree are satisfied one by one. For properties modified by universal path quantifiers, the model checker needs to verify that all paths starting from the initial state satisfy the property. For properties modified by path quantifiers, the model checker only needs to verify that there exists at least one path starting from the initial state that satisfies the property.
[0073] Specifically, the missing information flow control injection point is identified based on the counterexample path. Supplementary injection rules are automatically generated, and the abstract state graph is updated. This process is repeated until no violations are found. If a property is violated in a certain state or path, the model checker generates a counterexample path, which records the complete state transition sequence from the initial state to the state violating the property. Based on this counterexample path, the specific injection point location of the missing information flow control can be precisely located, including the class name, method name, and bytecode offset. The system automatically generates supplementary injection rules to include this injection point within the coverage of the dynamic gatekeeper. The abstract state graph is then updated, and the model check is performed again. This closed-loop process of checking, supplementing, and re-checking is repeated until all computation tree logical properties are verified as true on all reachable paths.
[0074] In this embodiment, the computational tree logic properties verified by the model checker include at least the following: for all reachable states, if the current instruction is a reflection call point, its next state must undergo a label verification action. For all method handle call points, the next state must enter the execution of the guard handle chain. When there is a path for the propagation of an abnormal object across modules, label removal or isolation processing must have been completed on that path. These properties ensure that all reflection calls and implicit data flow channels are covered by dynamic gatekeeper code, and there are no blind spots in information flow control.
[0075] Furthermore, the model checking process is completed offline during the module building phase, without increasing the system's runtime burden. After the module is built, the generated dynamic gatekeeper code has undergone completeness verification and can be directly deployed to the production environment.
[0076] In some embodiments, such as Figure 6 As shown, the step of performing redundant identification on the label verification of the injected points based on the proven state diagram and removing verifications that can be proven to be always true includes: S601: For each tag verification point, collect the abstract values of the parameter tags that reach that verification point in reverse; S602: If the parameter label meets the allowed conditions of the information flow policy on all paths, then mark the verification point as redundant and remove the verification instruction when synthesizing the dynamic gatekeeper code, while retaining the label record and object isolation instruction.
[0077] In this embodiment, for each tag verification point, the abstract values of the parameter tags reaching that verification point are collected in reverse. Reverse collection refers to starting from the tag verification point and traversing the control flow graph backwards, collecting the abstract values of the parameter tags on all paths leading to that verification point. Through reverse collection, the set of possible values for the parameter tags on all feasible paths can be obtained.
[0078] It should be noted that if the parameter tag meets the allowed conditions of the information flow policy on all paths, the verification point is marked as redundant, and the verification instruction is removed when synthesizing the dynamic gatekeeper code, while the tag record and object isolation instruction are retained. Meeting the allowed conditions of the information flow policy for a parameter tag means that the parameter tag is allowed to flow to the target module and will not lead to unauthorized data flow. If the parameter tag meets the allowed conditions on all feasible paths, the verification instruction at that verification point will never trigger a blocking operation at runtime, and therefore can be safely removed to reduce runtime overhead.
[0079] Specifically, when synthesizing dynamic gatekeeper code, for checkpoints marked as redundant, only tag recording instructions and object isolation instructions are generated; no verification instructions are generated. Tag recording instructions are used to record parameter tag information for offline auditing. Object isolation instructions are used to apply isolation processing to return values to prevent unauthorized modification. For checkpoints not marked as redundant, complete recording, verification, and isolation instructions are generated according to the normal process.
[0080] In this embodiment, redundancy analysis utilizes the complete state graph information already constructed during model checking. To prove completeness, model checking traverses the label states on all reachable paths within the module; this state information can be directly used for redundancy analysis without requiring re-analysis of the data flow. This makes redundancy analysis highly efficient and ensures the correctness of the analysis results.
[0081] Furthermore, redundancy analysis can be further optimized by considering object usage patterns. For example, if the analysis reveals that a parameter object is only used for read operations within the receiving module, the isolation strategy can be optimized from deep copy to read-only proxy, further reducing runtime overhead.
[0082] In some embodiments, the process of generating and injecting dynamic gatekeeper code based on formal methods further includes: Identify whether the caller class contains a framework dependency injection pattern; When the aforementioned pattern exists, the corresponding reflection call point is marked as a trusted assembly, and the tag verification is skipped in the generated dynamic gatekeeper code, while retaining read-only proxy or deep copy processing of the return value.
[0083] In this embodiment, the existence of a framework dependency injection pattern in the calling class is identified. Dependency injection patterns can be identified by scanning annotation information in the class bytecode, such as checking whether the class fields have annotations used to mark injection points. Dependency injection frameworks typically use specific annotations to mark fields, constructors, or methods that need to be injected. By scanning these annotations, the dependency injection pattern present in the module can be identified.
[0084] It's important to note that when dependency injection is present, the corresponding reflection call point is marked as trusted assembly, and tag validation is skipped in the generated dynamic gatekeeper code, preserving read-only proxy or deep copy processing of the return value. The reason for this is that the dependency injection framework injects service instances into module fields via reflection at runtime, which is normal framework initialization behavior, and the service instances themselves usually come from a trusted module context. Skipping tag validation avoids unnecessary disruption to the framework's initialization process, but preserving return value isolation ensures that the injected service instances are not modified by the module through non-interface methods. Specifically, dependency injection involves frameworks like Spring injecting service instances via reflection, while trusted assembly is a reflection call during the framework's initialization phase, marked as trusted and skipped for validation. For example, Spring's `@Autowired` annotation marks a field, and the framework injects the instance via reflection; this call is a trusted assembly.
[0085] Specifically, after identifying the dependency injection pattern, the bytecode processing component records the location of the corresponding reflection call point. When generating dynamic gatekeeper code, for these reflection call points marked as trusted assemblies, no tag verification instructions are generated; only tag recording instructions and return value isolation instructions are generated. The tag recording instructions are used to record the tag information of the injected service instance for offline auditing. The return value isolation instructions are used to generate a read-only proxy or deep copy object for the injected service instance, preventing the module from modifying the internal state of the service instance.
[0086] In this embodiment, the identification of dependency injection patterns can also be combined with the module's dependency descriptor. The module's dependency descriptor records the service interfaces that the module depends on, which are typically injected through a dependency injection framework. By comparing the module's dependency descriptor with the annotation information in the class bytecode, the reflection call point corresponding to the dependency injection pattern can be identified more accurately.
[0087] Furthermore, a similar approach can be used for certain special dependency injection patterns, such as constructor injection and method injection. The corresponding reflection call points are marked as trusted assemblies, tag validation is skipped, and isolation of return values is maintained.
[0088] In some embodiments, performing service scheduling between modules in the network controller further includes: A pre-check instruction is injected into the modification method of the container class used within the module. The pre-check instruction obtains the container's owning module and the tag of the value to be written. When the tag is not allowed to flow to the owning module, the modification operation is blocked.
[0089] In this embodiment, pre-check instructions are injected into the modification methods of container classes used within the module. Container classes include commonly used collection types, such as lists, maps, and collections. Modification methods of container classes include methods for adding, deleting, and modifying elements. These methods may lead to cross-module data pollution, therefore pre-checks are required.
[0090] It's important to note that the pre-check instruction retrieves the container's owning module and the tag of the value to be written. If the tag of the value to be written does not allow flow to the container's owning module, the modification operation is blocked. The container's owning module refers to the module that created the container object. When the container object is created, the information flow isolation code stores the identifier of the module that created the container in the object tag mapping table as the container object's owning module tag. The module tag is a metadata marker attached to the object, uniquely identifying the object's source module, the set of allowed modules, and its security level, used for permission verification during cross-module transfer. The tag of the value to be written refers to the tag of the object to be written to the container; this tag identifies the object's source module and the set of allowed modules.
[0091] Specifically, when a module executes a modification method of a container class, the pre-check instruction first obtains the container object's owning module tag, and then obtains the tag of the value to be written. The pre-check instruction checks whether the tag of the value to be written is allowed to flow to the container's owning module according to the information flow policy. If allowed, the modification operation is allowed to continue. If not allowed, a security exception is thrown, blocking the modification operation.
[0092] In this embodiment, the pre-check of the modification method of the container class can prevent cross-module data pollution. For example, if module A creates a container object, and module B obtains a reference to that container object through a cross-module interface and attempts to add a private object of module B to it, the pre-check instruction will detect that the tag of the value to be written is not allowed to flow to module A, thereby blocking the addition operation and preventing module B's private object from being leaked into module A.
[0093] Furthermore, pre-check instructions can prevent malicious modules from affecting the behavior of other modules by modifying the contents of a shared container object. For example, if multiple modules share a container object, a malicious module might add malicious objects to it, thus affecting the normal operation of other modules. Pre-check instructions ensure that only objects authorized to flow to the container's owning module can be written to the container, thereby improving system security.
[0094] This application also provides a service scheduling system for a modular network controller, such as Figure 7As shown, it includes a module class loader 10 and a bytecode processing component 20. The module class loader 10 is used to load the class files of all functional modules in the network controller, and the bytecode processing component 20 is used to execute the method described in the above embodiments.
[0095] It's important to note that the module class loader is responsible for loading the class files of all functional modules within the network controller. When the module class loader receives a request to load a class, it first reads the bytecode data of that class from the module's archive file, and then passes the bytecode data to the bytecode processing component. The bytecode processing component parses and modifies the bytecode data, injects information flow isolation code and dynamic gatekeeper code, and then returns the modified bytecode data to the module class loader. The module class loader uses the modified bytecode data to define a class object and loads the class object into the virtual machine.
[0096] Specifically, the bytecode processing components include a static injection module, a formal modeling module, a model checking module, a redundancy analysis module, and a code synthesis module. The static injection module identifies cross-module interface call points through bytecode rewriting and injects information flow isolation code. The formal modeling module constructs a formal model of information flow operations covering reflection calls, method handle calls, and implicit data flow channels, and converts the current module's bytecode into an abstract state diagram reflecting label propagation. The model checking module performs model checks on the abstract state diagram, verifies the coverage completeness of the information flow control strategy, and uses counterexample paths to complete uncovered injection points. The redundancy analysis module identifies redundancy in the label verification of injected points based on the proven state diagram and removes verifications that can be proven to be tautologically true. The code synthesis module synthesizes the final dynamic gatekeeper code and injects it into the class bytecode.
[0097] In this embodiment, the service scheduling system of the modular network controller further includes a runtime execution module. The runtime execution module is used to perform service scheduling between modules in the network controller based on injected information flow isolation code and dynamic gatekeeper code. The runtime execution module is responsible for managing the module context of threads, maintaining an object label mapping table, and performing label verification and isolation processing.
[0098] In addition, the modular network controller's service scheduling system also includes an audit module. This module records all information passed between modules, including the caller module identifier, the callee module identifier, object tags, and operation types. This audit information can be used for post-event analysis and security auditing, helping administrators identify security issues in the system.
[0099] The technical solution of this application embodiment will be further described below with reference to a specific application scenario. It should be noted that this case is only used to exemplify the operation of the solution of this application and does not constitute a limitation on the scope of protection of this application.
[0100] In this case, an operations and maintenance platform based on a modular architecture has a main controller module responsible for overall system scheduling and management. It loads a third-party log analysis module to analyze and process the system's log data. The platform uses a dependency injection framework to inject an implementation instance of the alarm service interface into the log analysis module, enabling it to send alarms when abnormal logs are detected. Simultaneously, the log analysis module calls the configuration service interface's get-configuration method to obtain runtime parameters; this method returns a mutable configuration object. Internally, the log analysis module uses expressions to filter alarm events and ultimately calls the alarm service's send-alarm method. The underlying implementation of the expressions calls the interface methods through method handles.
[0101] In this scenario, because the log analysis module is a third-party module, there is a risk of unauthorized data access or data corruption through cross-module object passing. Without a flow control mechanism, the log analysis module could potentially obtain internal references to other modules via reflection or influence the behavior of the main controller module by modifying the state of shared objects.
[0102] The technical solution of this application's embodiments intervenes when loading the class of the log analysis module. The module class loader passes the class bytecode to the bytecode processing component. The bytecode processing component first reads the dependency descriptor of the log analysis module, extracts the service interface method signatures of the main controller module that the module depends on, and constructs a whitelist. Then, the bytecode processing component traverses the class bytecode, identifies the call instructions for methods in the whitelist, and marks them as static cross-module entry or exit points.
[0103] For the call path where the log analysis module calls the configuration service interface's "get configuration" method, the bytecode processing component performs static analysis. The analysis shows that the log analysis module only calls the configuration object's read method to obtain configuration parameters, without calling any modification methods or passing the configuration object to other modules. Therefore, the bytecode processing component injects read-only proxy generation code at this call point. When the log analysis module calls the "get configuration" method, the read-only proxy generation code generates a read-only proxy object for the returned configuration object and then returns this read-only proxy object to the log analysis module. The log analysis module can normally read the configuration parameters through this read-only proxy object, but when attempting to call the configuration object's modification method, the read-only proxy object throws an access denied exception, preventing the modification operation.
[0104] Meanwhile, the bytecode processing component identifies an alert service field with an injection annotation in the log analysis module, indicating a dependency injection pattern. Therefore, the corresponding reflection call point is marked as a trusted assembly. When the dependency injection framework injects the alert service instance into this field at runtime via reflection, the dynamic gatekeeper code skips label verification, allowing the injection operation, but imposes read-only proxy processing on the alert service instance. The log analysis module can call the alert service's send alert method through this proxy object, but cannot modify the internal state of the alert service instance.
[0105] For expressions used internally by the log analysis module, the underlying mechanism involves calling interface methods via method handles. When loading the log analysis module's classes, the bytecode processing component performs formal modeling of the class bytecode. First, it constructs a formal model of information flow operations covering all reflection calls and method handle calls within the module, incorporating the formal semantics of operations such as precise method handle calls into the model. Second, it converts the log analysis module's bytecode into an abstract state graph, marking state nodes and transition arcs related to cross-module information flow. Third, it performs model checks on the abstract state graph to verify the completeness of the information flow control strategy across all method handle call paths.
[0106] During this verification process, the model checker traverses the abstract state graph, checking whether all method handle call points at the underlying level of the expression are covered by the dynamic gatekeeper. If a method handle call path is found to be uncovered, the model checker generates a counterexample path, indicating the precise location of the missing injection point. The system automatically generates supplementary injection rules based on the counterexample path, bringing that method handle call point into the coverage of the dynamic gatekeeper, and then re-performs the model check. This process is repeated until the completeness proof of all method handle call points passes.
[0107] It's important to note that, for the formal verification of method handle calls in this case, the model checker can automatically identify method handle call variants that are not easily identifiable through pattern matching at the bytecode level. For example, an expression might be linked to a target method handle via dynamic instructions, and its call path in the bytecode might represent a precise call to the method handle object. Identifying such call points requires parsing the bootstrap method and the corresponding constant pool entries. Through formal modeling and model checking, it can be ensured that all such call variants are included in the verification scope, avoiding omissions that might occur if only instruction pattern matching is relied upon.
[0108] After the completeness proof passes, redundancy analysis is performed. The necessity of tag verification at each injected point is evaluated. In this case, the event object invoked by the expression is created internally by the log analysis module, and its tag is marked as private to the log analysis module on all feasible paths. If the information flow policy allows objects with private tags from the log analysis module to flow to the alarm service of the main controller module, then the tag verification at this call point will always be true on all paths and can be marked as redundant. The final synthesized dynamic gatekeeper code only retains parameter tag recording instructions and object isolation instructions, and does not include tag verification instructions.
[0109] After the completeness proof passes and redundancy analysis is completed, the final dynamic gatekeeper code is synthesized and injected into the class bytecode. When the log analysis module executes the expression, the dynamic gatekeeper code intervenes, records the current thread's module context as the log analysis module, obtains the event object's tag, and then performs a copy-on-write operation on the event object, generating a copy-on-write proxy object. It then calls the original alarm sending method, passing the copy-on-write proxy object as a parameter to the main controller module. When the log analysis module continues to modify the event object after sending an alarm, it modifies the copy of the copy-on-write proxy object, without affecting the original event object already submitted to the main controller module.
[0110] Furthermore, during system operation, the list objects used internally by the log analysis module are created by the log analysis module, and their classifying label is the identifier of the log analysis module. When the log analysis module adds an element to this list object, a pre-check instruction is executed. The pre-check instruction obtains the classifying label of the list object as the log analysis module and retrieves the label of the element to be added. Since the element to be added is created internally by the log analysis module, the label is allowed to flow to the log analysis module, so the pre-check instruction allows the add operation. If the log analysis module attempts to add an element to a list object created by the main controller module, and the pre-check instruction detects that the classifying label of the list object is the main controller module, but the label of the element to be added is not allowed to flow to the main controller module, a safety exception is thrown, blocking the add operation.
[0111] As can be seen from the above examples, the technical solution of this application combines static bytecode rewriting with a dynamic gatekeeper mechanism generated based on formal methods, forming an information flow control system covering all cross-module data transmission paths. For statically declared cross-module interface calls, information flow isolation code is injected during class loading through bytecode rewriting. For reflection calls, method handle calls, and implicit data flow channels, dynamic gatekeeper code is generated and injected through formal methods. Both paths share the same information flow strategy and tag model, ensuring that object transmission in any cross-module service scheduling process, regardless of whether static interface calls, reflection calls, or method handle calls are used, is covered by a unified information flow strategy. Tag verification and object isolation are consistently implemented without omissions, as has been proven.
[0112] It should be noted that the construction of the formal model of information flow operations provides a semantic benchmark for completeness verification, enabling all possible information flow channels to be systematically included in the verification scope. The transformation of the abstract state diagram abstracts the complex bytecode control flow and data flow into a finite state model, allowing model checking to be completed within a finite time. The model checking and counterexample-driven completion process ensures the complete coverage of the information flow control strategy across the entire path with mathematical rigor, eliminating the reliance on the developer's experience and judgment. Redundancy analysis and dynamic gatekeeper synthesis utilize the global data flow information accumulated during the verification process to remove tautology checks without sacrificing security, reducing runtime overhead. The above steps are progressively sequential: the formal model defines what needs to be covered, the abstract state diagram describes what the program actually looks like, the model checking verifies whether the coverage is complete, and the redundancy analysis ensures that the coverage is not redundant. These four stages are interconnected, ultimately generating a complete yet concise dynamic gatekeeper code, which, together with the static information flow isolation code, constitutes a mandatory information flow control system for cross-module object transfer. Among them, tautology verification refers to verification logic where the condition is always true on all feasible execution paths. It has no actual interception function and is a redundant verification. For example, verifying source == source, true == true, or ensuring that parameter labels always allow flow to the target module are all examples of tautology verification.
[0113] In this embodiment, the combination of static bytecode rewriting and a dynamic gatekeeper mechanism solves the problem that static injection cannot cover reflection calls in traditional solutions. Traditional static bytecode injection schemes can only identify and process statically declared cross-module interface calls. For reflection calls and method handle calls, since their targets are only determined at runtime, effective identification and injection cannot be performed in the static phase. This application, by introducing a dynamic gatekeeper mechanism, intercepts and processes reflection calls and method handle calls at runtime, thus overcoming the shortcomings of static injection.
[0114] Meanwhile, the introduction of formal methods solves the problem of unguaranteed coverage in dynamic gatekeeper mechanisms. Traditional dynamic gatekeeper mechanisms rely on developers manually enumerating reflection APIs and injecting gatekeeper code. This approach is prone to missing some hidden call paths, such as field access through underlying unsafe classes, cross-module propagation of exception objects along the call stack, and value passing of thread-local variables between cross-module threads. This application constructs a formal model and abstract state diagram, and uses model checking techniques to exhaustively verify all feasible execution paths, ensuring that the dynamic gatekeeper mechanism fully covers all reflection calls and implicit data flow channels.
[0115] Furthermore, redundancy analysis and dynamic gatekeeper synthesis technology address the issue of high operational overhead in traditional dynamic gatekeeper mechanisms. Traditional dynamic gatekeeper mechanisms inject a unified security encapsulation at all reflection points, including complete tag acquisition, verification, and isolation logic, where many verifications are redundant for specific call points. This application utilizes global data flow information accumulated during model checking to perform necessity analysis on tag verification at each injection point, removing verifications that can be proven to be always true and retaining only necessary records and isolation actions, significantly reducing the operational overhead of the dynamic gatekeeper.
[0116] Those skilled in the art will understand that the above description is merely a preferred embodiment of this application and is not intended to limit the scope of protection of this application. Any modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of this application should be included within the scope of protection of this application.
Claims
1. A service scheduling method for a modular network controller, characterized in that, include: When loading the class of the module in the network controller, cross-module interface call points are identified by bytecode rewriting and information flow isolation code is injected. The information flow isolation code is used to apply transmission control based on module tags to the call parameters or return values. For the reflection invocation instructions and method handle invocation instructions in the bytecode of the class, dynamic gatekeeper code is generated and injected based on formal methods; Based on the injected information flow isolation code and the dynamic gatekeeper code, service scheduling between modules in the network controller is performed, wherein the object passing in the cross-module service request is subject to tag verification and isolation processing via the injected information flow isolation code and the dynamic gatekeeper code.
2. The method according to claim 1, characterized in that, For the reflection invocation instructions and method handle invocation instructions in the bytecode of the aforementioned class, dynamic gatekeeper code is generated and injected based on formal methods, including: Construct a formal model of information flow operations that covers reflection calls, method handle calls, and implicit data flow channels; Convert the current module's bytecode into an abstract state diagram that reflects tag propagation; The abstract state diagram is model checked to verify the completeness of the information flow control strategy in the reflection call and method handle call, and the uncovered injection points are filled in using counterexample paths until the completeness proof is passed. Redundancy identification is performed on the label verification of the injected points based on the proven state diagram. Verifications that can be proven to be always true are removed, records and isolation actions are retained, the final dynamic gatekeeper code is synthesized, and injected into the class bytecode. The formal model of information flow operation is a semantic model that defines the rules of label state change under reflection call, method handle call and implicit data flow operation. The abstract state diagram is a finite state diagram extracted from the bytecode that represents the relationship between control flow and label propagation.
3. The method according to claim 2, characterized in that, The method of identifying cross-module interface call points and injecting information flow isolation code through bytecode rewriting includes: Extract the method signatures of cross-module service interfaces based on the module dependency descriptor, and build a whitelist; Traverse the class bytecode, identify the call instructions for methods in the whitelist, and mark them as static cross-module entry or exit points; Depending on how the receiving module uses the incoming object, select to inject read-only proxy to generate code, copy-on-write to generate code, or deep copy to generate code.
4. The method according to claim 3, characterized in that, The step of selecting to inject read-only proxy generated code, copy-on-write generated code, or deep copy generated code based on how the receiving module uses the incoming object includes: Analyze the field access and method call behavior of the incoming object within the receiving module. If only read operations are involved, inject read-only proxy to generate code. If local modification operations are involved, inject copy-on-write to generate code. If cross-module propagation occurs, inject deep copy to generate code.
5. The method according to claim 2, characterized in that, The construction of the formal model for information flow operations, encompassing reflection calls, method handle calls, and implicit data flow channels, includes: Reflection calls, method handle calls, exception propagation, and thread-local variable passing operations are categorized as information flow operations. Pre-label conditions and post-label effects are defined for each type of operation, forming a formal semantic rule set.
6. The method according to claim 2, characterized in that, The process of converting the current module bytecode into an abstract state diagram reflecting tag propagation includes: Perform context-sensitive pointer analysis and control flow analysis on module bytecode to identify reflection call points and implicit data flow channels; Create a control flow graph for each method, and add abstract label variables to the control flow graph for parameters and return values; The abstract label variable is propagated along the control flow graph to generate a finite state graph with the label state as the node.
7. The method according to claim 2, characterized in that, The process of performing model checks on the abstract state diagram to verify the completeness of the information flow control strategy's coverage of reflection calls and method handle calls, and using counterexample paths to fill in uncovered injection points until the completeness proof passes, includes: The label verification and isolation actions required by the information flow control strategy are expressed as computation tree logic properties; Model checks are performed in the abstract state diagram to find counterexample paths that violate the logical properties of the computation tree; Based on the counterexample path, the missing information flow control injection point is identified, supplementary injection rules are automatically generated, and the abstract state graph is updated. The check is repeated until no violation is found.
8. The method according to claim 2, characterized in that, The step of performing redundant identification on the label verification of the injected points based on the proven state diagram, and removing verifications that can be proven to be always true, includes: For each tag verification point, the parameter tag abstract values reaching that verification point are collected in reverse. If the parameter label meets the allowed conditions of the information flow policy on all paths, the verification point is marked as redundant, and the verification instruction is removed when synthesizing the dynamic gatekeeper code, while retaining the label record and object isolation instruction.
9. The method according to claim 1, characterized in that, The process of generating and injecting dynamic gatekeeper code based on formal methods also includes: Identify whether the caller class contains a framework dependency injection pattern; When the aforementioned pattern exists, the corresponding reflection call point is marked as a trusted assembly, and the tag verification is skipped in the generated dynamic gatekeeper code, while retaining read-only proxy or deep copy processing of the return value.
10. The method according to claim 1, characterized in that, The execution of service scheduling between modules in the network controller further includes: A pre-check instruction is injected into the modification method of the container class used within the module. The pre-check instruction obtains the container's owning module and the tag of the value to be written. When the tag is not allowed to flow to the owning module, the modification operation is blocked.
11. A service scheduling system for a modular network controller, characterized in that, It includes a module class loader and a bytecode processing component, wherein the module class loader is used to load class files of all functional modules in the network controller, and the bytecode processing component is used to execute the method as described in any one of claims 1 to 10.