A kernel dynamic verification method and system
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- CHINA UNICOM INTERNET OF THINGS CO LTD
- Filing Date
- 2026-05-26
- Publication Date
- 2026-07-21
Smart Images

Figure CN122261675B_ABST
Abstract
Description
Technical Field
[0001] This application belongs to the field of Linux kernel technology, and in particular relates to a kernel dynamic verification method and system. Background Technology
[0002] Existing Linux operating system kernel verification schemes mostly employ function hooking or persistent execution to monitor kernel functions. Hooking inserts fixed verification logic into the execution path of the target function, performing verification operations regardless of whether the function's execution state is abnormal. Persistently executed verification logic continuously consumes processor resources and memory space. Continuous monitoring of kernel hot path functions increases processor utilization. The storage and execution of verification logic require a fixed memory area, making it impossible to reduce resource consumption while performing full call monitoring. Furthermore, the switching of verification logic depends on interrupt masking or lock synchronization operations, which can easily interfere with the kernel execution flow and fail to meet the resource constraints required for continuous kernel function verification. Summary of the Invention
[0003] To address the challenge of both monitoring full calls to kernel functions and reducing processor and memory usage during the verification process.
[0004] This application proposes a kernel dynamic verification method, including: Based on kernel static branching, the verification logic of the target kernel function is configured by default as a processor no-operation instruction, and the call information and exception characteristics of the target kernel function are collected through per-CPU dynamic counting; Based on the statistical results of anomaly characteristics and call information, the execution target of the kernel static branch is atomically switched to execute the verification logic. Here, the kernel static branch is a branch switching component provided by the kernel based on jump tags, the per-CPU dynamic count is a lock-free numerical statistical operation based on processor-independent variables, and the atomic switch is an operation that modifies the execution target through a single processor atomic instruction.
[0005] Optionally, configuring the verification logic of the target kernel function as a processor no-operation instruction by default based on kernel static branches includes: Initialize the branch key for the kernel's static branches; Bind the execution target of the branch key to the processor no-operation instruction; The kernel static branch is associated with the execution entry point of the target kernel function, and the branch key is a variable used to identify the switching state of the kernel static branch.
[0006] Optionally, binding the execution target of the branch key to a processor no-operation instruction includes: Read the memory address of the processor's no-operation instruction; Configure the branch key's jump address to the memory address of the processor's no-operation instruction; Locking the initial configuration state of the branch key is a memory protection operation that prevents non-switch operations from modifying the branch key jump address.
[0007] Optionally, collecting call information and exception characteristics of target kernel functions through per-CPU dynamic counting includes: Configure an independent counter variable for each processor; The number of times the target kernel function is called is counted using a counter variable: The number of times an exception is triggered in the target kernel function is counted by a counter variable, which is a numerical storage unit stored in the processor's local memory.
[0008] Optionally, counting the number of exceptions triggered by the target kernel function using a counter variable includes: Detect the return value of the target kernel function. Detect the input parameter boundaries of the target kernel function; The value of the counter variable is updated based on the detection results of the return value and the parameter boundary. The input parameter boundary is the range of parameter values required for the execution of the target kernel function.
[0009] Optionally, atomically switching the execution target of the kernel static branch to execute verification logic based on statistical results of anomaly characteristics and call information includes: Calculate the ratio of the number of exceptions triggered to the number of calls; The ratio is compared with a preset threshold, and the execution target of the kernel static branch is atomically modified based on the comparison result. The preset threshold is a pre-configured branch switching trigger value.
[0010] Optionally, the execution target of the kernel static branch can be atomically modified based on the comparison results, including: When the ratio is greater than a preset threshold, an atomic instruction is executed to modify the jump address of the branch key. An atomic instruction is a single-cycle, uninterruptible instruction supported by the processor. Switch the jump address to the storage address of the verification logic and mark the activation status of the kernel static branch.
[0011] Optional, also includes: After the verification logic is completed, the execution target of the kernel static branch is atomically switched to the processor no-operation instruction, and the value of the counter variable is reset to the initial value.
[0012] Optionally, the method further includes: The call information of the target kernel function is stored in a singly linked list through RCU. The linked list nodes are allocated based on the processor's local Slab cache. The call information is read in batches and verified within the RCU grace period. RCU singly linked lists are lock-free linked list structures based on read-copy-update mechanisms, while Slab caches are memory object reuse components provided by the kernel.
[0013] This application also discloses a kernel dynamic verification system, including a branch configuration module, a count acquisition module, and a switching execution module; The branch configuration module is used to configure the verification logic of the target kernel function as the processor no-operation instruction by default based on the kernel static branch. The kernel static branch is a branch switching component provided by the kernel based on the jump label. The counting and acquisition module is used to collect call information and exception characteristics of target kernel functions through per-CPU dynamic counting. Per-CPU dynamic counting is a lock-free numerical statistical operation based on processor-independent variables. The execution switching module is used to atomically switch the execution target of the kernel static branch to execute the verification logic based on the statistical results of the exception characteristics and call information. Atomic switching is an operation that modifies the execution target through a single processor atomic instruction.
[0014] As can be seen from the above technical solution, the kernel dynamic verification method provided in this application configures the verification logic as a processor no-operation instruction by default through kernel static branches. This ensures that the verification logic is not executed when the target function is normally running, reducing the processor's instruction execution overhead. Per-CPU dynamic counting relies on processor-independent variables to collect call information and abnormal features. The collection process is lock-free and only executes a single value update instruction, which does not interfere with the execution flow of the target function. The switching condition is determined based on the statistical results of the collected values. The execution target of the static branch is switched only in abnormal states through atomic instructions. The execution process of atomic instructions is uninterrupted and without synchronization waiting. The initial configuration can be restored after the verification logic is executed. The overall solution, through the sequential action of no-operation normal configuration, lock-free counting collection, and atomic condition switching, reduces processor and memory usage while continuously collecting all call features of the target function. When the collected abnormal features meet the triggering conditions, deep verification logic can be executed on demand through atomic switching, realizing fine-grained monitoring of call information without interfering with the kernel execution flow. Attached Figure Description
[0015] To more clearly illustrate the technical solutions in the embodiments of this application 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 application. 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 illustrating a kernel dynamic verification method in an embodiment of this application; Figure 2 This is a flowchart illustrating a kernel dynamic verification method in this application embodiment, which configures the verification logic of the target kernel function as the processor no-operation instruction by default based on the kernel static branch. Figure 3 This is a flowchart illustrating the process of binding the execution target of a branch key to a processor no-operation instruction in a kernel dynamic verification method according to an embodiment of this application. Figure 4 This is a flowchart illustrating a kernel dynamic verification method in this application, which collects call information and abnormal characteristics of target kernel functions through Per-CPU dynamic counting. Figure 5 This is a flowchart illustrating a kernel dynamic verification method in this application, which uses a counter variable to count the number of exceptions triggered by a target kernel function. Figure 6 This is a flowchart illustrating the process of a kernel dynamic verification method in this application, which atomically switches the execution target of a kernel static branch to execute verification logic based on statistical results of abnormal characteristics and call information. Figure 7 This is a flowchart illustrating the process of atomically modifying the execution target of a kernel static branch based on the comparison result in a kernel dynamic verification method according to an embodiment of this application. Figure 8 This is a flowchart illustrating the remaining steps of a kernel dynamic verification method in an embodiment of this application; Figure 9 This is a schematic diagram of the structure of a kernel dynamic verification system in an embodiment of this application. Detailed Implementation
[0017] In the following description, specific details such as particular system architectures and techniques are set forth for illustrative purposes and not limiting, in order to provide a thorough understanding of the embodiments of this application. However, those skilled in the art will understand that this application can also be implemented in other embodiments without such specific details. In other instances, detailed descriptions of well-known systems, apparatuses, circuits, and methods are omitted so as not to obscure the description of this application with unnecessary detail.
[0018] In this embodiment, existing kernel verification schemes typically embed verification logic using function hooks when continuously monitoring kernel hot path functions. Taking the verification of kernel page allocation functions as an example, existing schemes insert a kprobe hook at the function execution entry point. Each time the function is called, the hook logic triggers verification execution. The verification logic includes operations such as parameter detection, return value verification, and status determination. These operations are continuously executed with function calls. The registration and unloading of hooks require modification of the kernel execution path, and the storage of verification data requires a separate memory area. Continuously executed verification operations will increase processor utilization, and the fixed allocation of memory areas will increase memory consumption. At the same time, the execution of hook logic depends on interrupt masking or spinlock synchronization, which will interfere with the kernel's native execution flow, resulting in a decrease in the execution efficiency of kernel hot paths. It is impossible to meet the requirements of full call monitoring and low resource consumption.
[0019] It should be noted that this application provides a kernel dynamic verification method, such as... Figure 1 As shown, the method includes: S100: Based on kernel static branches, the verification logic of the target kernel function is configured by default as a processor no-operation instruction, and the call information and exception characteristics of the target kernel function are collected through per-CPU dynamic counting.
[0020] S200: Based on the statistical results of the exception characteristics and call information, the execution target of the kernel static branch is atomically switched to execute the verification logic. Here, the kernel static branch is a branch switching component provided by the kernel based on jump tags, the per-CPU dynamic count is a lock-free numerical statistical operation based on processor-independent variables, and the atomic switch is an operation that modifies the execution target through a single processor atomic instruction.
[0021] The kernel dynamic verification method provided in this application configures the verification logic as a processor no-operation instruction by default through kernel static branches. This prevents the verification logic from being executed during normal execution of the target function, reducing processor instruction execution overhead. Per-CPU dynamic counting relies on processor-independent variables to collect call information and exception characteristics. The collection process is lock-free and executes only a single value update instruction, without interfering with the execution flow of the target function. The switching condition is determined based on the statistical results of the collected values. The execution target of the static branch is switched only in abnormal states through atomic instructions. The execution of atomic instructions is uninterrupted and without synchronization wait. The initial configuration can be restored after the verification logic is executed. The overall solution, through the sequential action of no-operation normal configuration, lock-free counting collection, and atomic condition switching, reduces processor and memory usage while completing full call monitoring of the target function, and does not interfere with the kernel execution flow.
[0022] It should be noted that the concept of this application specifically relies on the kernel's native static branch component to configure the verification logic as a processor no-operation instruction by default, and relies on processor-independent variables to implement per-CPU dynamic counting, collect the call information and exception characteristics of the target kernel function, determine the triggering condition through the statistical results of exception characteristics and call information, use a single processor atomic instruction to complete the switching of the static branch execution target, execute the verification logic in the exception state, and maintain the no-operation state in the normal state. The combination of lock-free counting and atomic switching realizes the continuous verification of the kernel function, while adapting to the resource constraints of kernel execution, without modifying the kernel source code and target function instructions, without introducing additional lock synchronization mechanisms, and maintaining the stability of the kernel execution process.
[0023] The embodiments of this application will be described in detail below.
[0024] Specifically, kernel static branches are branch switching components provided by the kernel based on jump tags. This component relies on the kernel jump tag mechanism to switch execution targets without requiring additional hardware or software components, directly reusing the native kernel runtime environment. The kernel jump tag mechanism completes instruction layout during the kernel compilation phase, reserving the jump instructions for static branches as modifiable long jump instructions. There's no need to modify the main execution logic of the function at runtime; branch switching is completed simply by modifying the target address of the jump instruction. It doesn't modify the native instruction sequence of the target kernel function, adapting to different kernel versions without requiring adjustments to the function's instruction layout for different kernel versions. Processor no-operation instructions are instructions executed by the processor that involve no computation or memory access. When executed, these instructions do not change the values of the processor's general-purpose registers, status registers, or memory space, and do not incur additional overhead such as pipeline refresh or cache invalidation. The execution time of a single instruction matches the processor's base clock cycle, without increasing the execution latency of the target kernel function.
[0025] The branch key is implemented in the kernel as a composite structure containing a `struct static_key` kernel object and additional state fields. In this embodiment, the branch key is initialized by calling the kernel `static_key_init()` or a similar interface, setting the default jump target of `static_key` to a no-operation instruction sequence. Switching the branch key's jump address is achieved by calling atomic operation interfaces such as `static_key_modify()`, which uses processor atomic instructions to modify the jump offset of the code segment at the underlying level.
[0026] Per-CPU dynamic counting is a lock-free numerical statistical operation based on processor-independent variables. Each processor corresponds to an independent statistical variable, and the statistical process does not require lock synchronization, avoiding contention issues in multi-core environments. The storage area of the per-CPU variable is initialized during kernel startup, and each processor corresponds to an independent physical memory area. Different variable storage addresses are isolated from each other, preventing concurrent access to the same memory address by multiple cores. Therefore, numerical updates can be completed without the need for synchronization mechanisms such as spinlocks and mutexes. A single numerical update operation only requires a single processor addition instruction and will not have a perceptible impact on the execution flow of the target kernel function.
[0027] Atomic switching is an operation that modifies the execution target using a single processor atomic instruction. This atomic instruction completes execution within a single processor cycle, and the execution process cannot be interrupted, thus not affecting the kernel execution flow. Processor atomic instructions possess the characteristic of indivisible execution; their execution process cannot be interrupted by kernel interrupts, process scheduling, exception handling, or other operations. There is no possibility that intermediate states will be read by other kernel processes during the modification process, ensuring the consistency of the branch switching process and preventing kernel execution anomalies caused by half-modification of branch jump addresses.
[0028] For example, when the target kernel function is in a normal execution state, the kernel static branch directs the verification logic to a processor no-operation instruction. The execution flow of the target kernel function is not interrupted by the verification logic; the processor only executes the native instructions of the target kernel function, with no additional verification instructions involved. When the target kernel function is called, the per-CPU dynamic counter synchronously collects call information and exception characteristics. The collection process only updates the values of local variables on the processor, without memory access or lock operations. When the statistical results of the collected exception characteristics and call information meet the switching conditions, an atomic switching operation modifies the execution target of the kernel static branch, causing the verification logic to be loaded and executed. After the verification logic is executed, the kernel static branch is restored to its initial configuration, and the target kernel function returns to its normal execution state.
[0029] Those skilled in the art will understand that the jump label mechanism of the kernel static branch has been adapted for a long time in the main kernel version. The configuration can be completed by directly calling the native interface without modifying the kernel source code. The per-CPU dynamic counting variable management interface is a general interface provided by the kernel natively. The atomic switching operation is implemented by atomic instructions natively supported by the processor architecture. All operations of the entire solution reuse the kernel native runtime environment and processor native features. There is no need to introduce third-party components or modify the kernel logic. It can be directly deployed in the standard kernel runtime environment.
[0030] In alternative implementations, such as Figure 2 As shown, the verification logic of the target kernel function is configured by default as a processor no-operation instruction based on the kernel static branch, including: S110: Initialize the branch key for the kernel static branch.
[0031] S120: Bind the execution target of the branch key to the processor no-operation instruction.
[0032] S130: Associates the kernel static branch with the execution entry point of the target kernel function. The branch key is a variable used to identify the kernel static branch switching state.
[0033] Specifically, initializing the branch key for a kernel static branch involves configuring an identifier variable for the branch switching component through the kernel-provided initialization interface. The branch key is a variable used to identify the kernel static branch switching state; it stores the current jump address and execution state of the kernel static branch and serves as the identifier for branch switching. The kernel static branch initialization interface allocates a fixed storage area for the branch key in the kernel memory space. This storage area has read-write properties and is accessible only to privileged kernel-mode operations. User-mode processes cannot read or modify the values in this area, ensuring the security of the branch key configuration. The initialization process sets the branch key to an initial inactive state, marking that the branch is not currently executing verification logic, and initializes the default value of the jump address to ensure that the branch will not jump to an invalid memory address when inactive.
[0034] Binding the execution target of a branch key to a processor no-operation instruction establishes an association between the branch key's jump address and the memory address of the processor no-operation instruction. This ensures that when a static branch in the kernel is triggered, it prioritizes instructions with no execution overhead. The binding process writes the physical address of the processor no-operation instruction into the branch key's jump address field. When the branch jump instruction is executed, it directly jumps to the memory address of the no-operation instruction. After execution, it returns directly to the native execution flow of the target kernel function without executing any additional verification logic. After the binding operation is complete, every execution of the target kernel function will go through the static branch jump instruction, normally only executing no-operation instructions without incurring any additional overhead.
[0035] Associating a static kernel branch with the entry point of a target kernel function involves attaching a branch switching component to the location where the target kernel function begins execution. This ensures that each execution of the target kernel function is checked by the branch switching component. The association process is achieved through instrumentation at the kernel function's header. This instrumentation operation only adds a static branch jump instruction at the target kernel function's entry point; it does not modify any instructions in the function body, alter the function's stack layout or register usage rules, or affect the function's native execution logic. After the association is complete, each call to the target kernel function will first execute the static branch jump instruction, determining whether to execute a no-operation instruction or verification logic based on the branch key's configuration.
[0036] For example, when initializing a target kernel function related to kernel memory management, the kernel static branch initialization interface is called to complete the initial state configuration of the key. After configuration, the branch key is in an inactive state, and the target no-operation instruction is executed. After the binding operation is completed, the kernel static branch is mounted to the entry address of the target kernel function. When the target kernel function executes, it first reads the configuration state of the branch key and then determines the subsequent execution instructions. When the target kernel function is called by other kernel modules, the static branch jump instruction at the entry point is executed first, the jump address of the branch key is read, and the jump is made to the storage address of the processor no-operation instruction. After the no-operation is performed, the function returns to its native execution flow. The entire process does not involve any additional verification logic and does not increase the execution latency of the function.
[0037] In alternative implementations, such as Figure 3 As shown, binding the execution target of the branch key to the processor no-operation instruction includes: S121: Read the memory address of the processor no-operation instruction.
[0038] S122: Configure the jump address of the branch key to the storage address of the processor no-operation instruction.
[0039] S123: Lock the initial configuration state of the branch key. Locking the initial configuration state of the branch key is a memory protection operation that prevents non-switch operations from modifying the branch key jump address.
[0040] Specifically, reading the storage address of the processor no-operation instruction involves retrieving the physical address of the no-operation instruction from the kernel instruction storage area. This address is a fixed address allocated during kernel startup and requires no dynamic allocation. The kernel instruction storage area is a read-only memory region reserved during kernel startup to store all executable instructions of the kernel, including the general implementation of the processor no-operation instruction. The memory address of this area does not change after kernel startup and remains fixed throughout the entire kernel runtime, requiring no dynamic allocation or modification. The reading process is completed through the kernel's native symbol lookup interface, directly obtaining the starting address of the no-operation instruction implementation function. This address is the storage address of the processor no-operation instruction, requiring no additional address translation or memory mapping operations.
[0041] Configuring the jump address of a branch key to the storage address of a processor no-operation instruction involves assigning the jump target field in the branch key the physical address of the no-operation instruction, allowing a direct jump to that address during branch switching. The configuration process is completed using a single memory write instruction from the processor, which directly writes the read no-operation instruction's storage address into the branch key's jump address field. This write operation only modifies the corresponding field of the branch key and does not change the values in other kernel memory areas, thus not affecting other kernel execution flows. After configuration, static branch jump instructions will directly use this address as the jump target, and under normal circumstances, will always jump to the storage address of the no-operation instruction.
[0042] The initial configuration state of locking the branch key is a memory protection operation that prohibits non-switch operations from modifying the branch key jump address. Specifically, in this embodiment, the kernel memory page containing the branch key is marked as read-only by modifying the permission bits of the page table entry, thereby intercepting any illegal write operations in the kernel page fault handling process. Simultaneously, the atomic switch operation executed in the switch execution module temporarily elevates the write permission of the target address through a kernel-reserved write operation interface (such as text_poke_bp() or a static branch-specific modification interface). After a single atomic instruction completes the jump address update, read-only protection is immediately restored. This mechanism ensures that the branch key jump address is not accidentally tampered with by other kernel paths under normal circumstances, preventing accidental modification of the branch configuration. The kernel memory protection mechanism is implemented through the page table attribute configuration of the memory management unit, setting the memory page containing the branch key to only allow specific atomic operations to perform writes. All other write operations will trigger a memory access exception, be intercepted by the kernel's exception handling process, and will not modify the value of the branch key. Locking operations do not affect the modification of branch keys by atomic switch operations. Atomic switch operations complete the write through privileged interfaces reserved by the kernel, which can bypass memory protection mechanisms to complete legitimate address modifications and ensure the normal execution of branch switches.
[0043] Specifically, in this embodiment, the page containing the branch key is marked as read-only by modifying the permission bits of the page table entry, thereby intercepting any illegal write operations during the kernel page fault handling process. Simultaneously, the atomic switch operation performed in the switch execution module temporarily elevates the writable permission of the target address through a kernel-reserved write operation interface. After a single atomic instruction completes the update of the jump address, read-only protection is immediately restored. This mechanism ensures that the branch key's jump address is not accidentally tampered with by other kernel paths under normal circumstances.
[0044] Those skilled in the art will understand that the storage address of the processor no-operation instruction remains unchanged during kernel execution. After the branch key's jump address is configured, the locking operation ensures the stability of the branch configuration under normal conditions, prevents interference from other kernel execution processes, and ensures that the target kernel function always points to the no-operation instruction during normal execution. The locking operation does not impose any restrictions on atomic switching operations; it only intercepts illegal write operations, thus ensuring the security of the branch configuration without affecting the normal execution of branch switching.
[0045] In alternative implementations, such as Figure 4 As shown, the call information and anomaly characteristics of the target kernel function collected through per-CPU dynamic counting include: S140: Configure an independent counting variable for each processor.
[0046] S150: Count the number of times the target kernel function is called using a counter variable. S160: The number of exceptions triggered by the target kernel function is counted by a counter variable, which is a numerical storage unit stored in the processor's local memory.
[0047] Specifically, configuring an independent counting variable for each processor involves allocating a numerical storage unit based on the processor's local memory. This counting variable is stored in a unit within the processor's local memory, and this unit is bound to the processor. Different counting variables are independent of each other, with no data sharing or contention. The configuration process for per-CPU counting variables is completed through the kernel's native per-CPU variable allocation interface. The kernel allocates an independent numerical storage unit for each online processor. The memory address of each unit is only visible to the corresponding processor; other processors cannot directly access the value at that address. This prevents concurrent writing to the same memory address by multiple cores, thus eliminating the need for any lock synchronization mechanism to complete value updates. The configuration process sets an initial zero value for each counting variable, ensuring that the statistical process starts from the initial state and avoids statistical errors caused by abnormal initial values.
[0048] Counting the number of times a target kernel function is called involves incrementing the variable at the entry point of the target kernel function. Each time the target kernel function is called, the corresponding count variable is incremented by one. This counting operation is performed at the entry point of the target kernel function, adjacent to the jump instruction of a static branch, requiring only a single processor addition instruction and not increasing the function's execution latency. When the target kernel function is called on a processor, only the corresponding call count variable is updated; other count variables remain unchanged. This avoids multi-core contention, and the counting process is completely lock-free, having no impact on the kernel's scheduling flow.
[0049] Counting the number of exceptions triggered by a target kernel function involves incrementing the corresponding counter variable only when an exception occurs during the execution of the target kernel function. This statistical operation is performed at the execution exit point of the target kernel function; the increment operation is only performed when an exception is detected during function execution. Normal function calls do not update the counter variable's value. Similar to call count statistics, the exception trigger count only updates the counter variable corresponding to the currently executing function. There is no multi-core contention, no lock synchronization, and the operational overhead is extremely low, without affecting the function's execution flow.
[0050] For example, when running the kernel in a multi-core environment, each processor is assigned an independent call count variable and an exception trigger count variable. When the target kernel function is called on the first processor, the call count variable for the first processor is incremented by one. If an exception occurs during this call, the exception trigger count variable for the first processor is incremented by one, while the values of other count variables remain unchanged. The entire statistical process involves no cross-data interaction and no lock synchronization operations. When the target kernel function is called on the second processor, only the corresponding count variable for the second processor is updated, completely isolated from the count variable for the first processor. There will be no data overwriting or contention, ensuring accurate and reliable statistical results.
[0051] In alternative implementations, such as Figure 5 As shown, the number of exception triggers in the target kernel function is counted using a counter variable, including: S161: Detect the return value of the target kernel function.
[0052] S162: Detect the input parameter boundaries of the target kernel function.
[0053] S163: Update the value of the counter variable based on the detection results of the return value and parameter boundaries. The input parameter boundaries are the range of parameter values required for the execution of the target kernel function.
[0054] Specifically, detecting the return value of a target kernel function involves reading the returned value after the function completes execution and determining whether this value falls within the normal range for function execution. The return value reading operation is completed at the execution exit point of the target kernel function, directly reading the value stored in the return value register after function execution. No additional memory copying or data conversion operations are required; the reading process requires only a single processor register read instruction, resulting in extremely low overhead. The normal range for results is determined by the functional definition of the target kernel function and matches the kernel's standard execution specifications, requiring no dynamic adjustment. The detection process only needs to compare the return value with the upper and lower limits of the normal range to complete the anomaly determination.
[0055] Detecting the input parameter boundaries of the target kernel function involves reading the input parameters received by the target kernel function and determining whether the parameters fall within the range of parameter values required for the target kernel function's execution. The input parameter boundaries are defined by the target kernel function's functional definition and do not require dynamic adjustment. The input parameter reading operation is completed at the target kernel function's entry point, directly reading the input parameter values stored in the parameter register or function stack. No additional data processing is required, resulting in extremely low overhead. The parameter value range matches the kernel's function execution specifications, covering all legal parameters required for normal function execution; parameters exceeding this range are considered abnormal.
[0056] The count variable is updated based on the detection results of the return value and parameter boundaries. When the return value exceeds the normal range or the input parameter exceeds the boundary, the count variable is incremented by one; otherwise, it is not updated. The update operation is only performed when an exception is detected; normal function calls do not trigger this operation, further reducing the overhead of the statistical process. The update operation is the same as the call count statistics operation, only updating the exception trigger count variable corresponding to the current execution. There is no multi-core contention or lock synchronization; the operation can be completed with only a single processor addition instruction.
[0057] Specifically, taking a memory allocation kernel function as an example, the normal return value of this function is a valid memory address, and the input parameters are a memory allocation flag and the allocation quantity. When the return value is a null pointer, it is considered an abnormal return value. When the allocation quantity in the input parameters exceeds a preset range, it is considered a parameter boundary exception. In either case, the value of the exception trigger count variable is updated. When the function execution returns a valid memory address and the input parameters are within the preset range, it is considered normal execution, and the value of the exception trigger count variable is not updated; only the value of the call count variable is updated.
[0058] In alternative implementations, such as Figure 6 As shown, the atomic switching of the execution target of the kernel static branch to execute the verification logic based on the statistical results of the anomaly characteristics and call information includes: S210: Calculate the ratio of the number of exceptions triggered to the number of calls.
[0059] S220: Compare the ratio with a preset threshold, and atomically modify the execution target of the kernel static branch based on the comparison result. The preset threshold is a pre-configured branch switching trigger value.
[0060] Specifically, calculating the ratio of exception trigger counts to function call counts involves dividing the statistically obtained exception trigger count by the function call count to obtain a numerical result representing the probability of an exception occurring. This calculation is performed using native kernel integer division instructions, without the need for floating-point units and thus incurring no additional computational overhead. The calculation process first aggregates the exception trigger counts and function call counts for all processors to obtain the total exception trigger count and total function call count across all cores, then calculates the ratio to ensure that the statistical results cover all function call scenarios without any omissions. The calculation process executes in the kernel's low-priority work queue, does not consume the execution time of the target kernel function, and has no impact on the function's execution flow.
[0061] The ratio is compared with a preset threshold, which is a pre-configured branch switching trigger value. This value is configured based on the kernel runtime environment and verification requirements and remains unchanged after configuration. The range of the preset threshold matches the statistical range of the probability of anomalies, used to determine whether the probability of anomalies in the target kernel function reaches a level requiring the execution of verification logic. When the ratio exceeds the preset threshold, it is determined that the function execution has a persistent anomaly, requiring the execution of verification logic. When the ratio does not exceed the preset threshold, the function execution is in a normal state, maintaining the normal no-operation configuration. The comparison process requires only one integer comparison instruction, with extremely low overhead. It is also executed in the kernel's low-priority work queue and will not affect the execution of the target kernel function.
[0062] The atomic modification of the execution target of a kernel static branch based on the comparison result involves adjusting the jump address of the branch key through atomic operations when the comparison result meets the switching conditions, thereby changing the execution target of the kernel static branch. The modification operation is only executed when the ratio is greater than a preset threshold; if the condition is not met, no modification operation is performed, maintaining the initial configuration of the kernel static branch. The modification operation is completed through atomic instructions of the processor, and the execution process cannot be interrupted, ensuring the consistency of branch switching and preventing kernel execution anomalies caused by intermediate states.
[0063] For example, if the preset threshold is configured to a fixed value, and the calculated exception trigger ratio is greater than this value, it is determined that the target kernel function execution has a persistent exception, triggering a switch operation in the kernel static branch. If the ratio is less than or equal to this value, the initial configuration of the kernel static branch remains unchanged. When the preset threshold is configured to 5%, if the total number of calls is 100 and the total number of exception triggers is 6%, the calculated ratio is 6%, which is greater than the preset threshold, triggering a branch switch operation. If the total number of exception triggers is 3%, the calculated ratio is 3%, which is less than the preset threshold, and the initial configuration remains unchanged.
[0064] In alternative implementations, such as Figure 7As shown, the execution target of the kernel static branch is atomically modified based on the comparison results, including: S221: When the ratio is greater than a preset threshold, execute an atomic instruction to modify the jump address of the branch key. An atomic instruction is a single-cycle, uninterruptible instruction supported by the processor.
[0065] S222: Switch the jump address to the storage address of the verification logic and mark the activation status of the kernel static branch.
[0066] Specifically, when the ratio exceeds a preset threshold, an atomic instruction is executed to modify the jump address of the branch key. An atomic instruction is a single-cycle, uninterruptible instruction supported by the processor. Its execution is not interrupted by kernel interrupts, process scheduling, or other operations. After execution, the jump address of the branch key is updated. The atomic instruction uses a natively supported atomic memory write instruction from the processor architecture, which can modify the memory address within a single clock cycle. The execution process is indivisible, preventing other kernel processes from reading the data during the modification, ensuring that the jump address of the branch key is valid at all times and preventing kernel crashes caused by invalid addresses. The modification operation only updates the jump address field of the branch key; it does not change other fields of the branch key and does not affect its other functions.
[0067] Switching the jump address to the storage address of the verification logic changes the branch key's jump target from the processor no-operation instruction to the storage location of the verification logic. This ensures that the target kernel function will load and run the verification logic during subsequent execution. The storage address of the verification logic is a fixed address allocated during kernel compilation, storing all execution instructions of the verification logic. This address remains fixed during kernel runtime and does not require dynamic allocation. After the switching operation is complete, the jump instruction of the static branch will jump the execution flow to the starting address of the verification logic, execute all instructions of the verification logic, and complete the verification operation of the target kernel function.
[0068] Marking the activation status of a kernel static branch involves updating the status flag in the branch key to record whether the kernel static branch is currently active, thus avoiding repeated switching operations. The status flag is stored in a fixed field of the branch key. When active, it marks that the branch has switched to the verification logic. Subsequent comparison processes will first read this status flag. If the branch is already active, the atomic switching operation will not be repeated, avoiding redundant modification of the branch key's jump address and reducing unnecessary processor overhead. The marking operation and the jump address modification operation are completed in the same atomic instruction, ensuring that the status flag and the modified jump address are consistent and preventing mismatches between status and address.
[0069] Those skilled in the art will understand that the execution time of atomic instructions matches the processor cycle time, the operation of modifying the branch key jump address has no synchronization wait, does not increase the execution latency of the target kernel function, and the verification logic can be called immediately after the switch is completed without additional loading wait time. The execution of atomic instructions does not trigger processor pipeline refresh, does not generate additional overhead such as cache invalidation, and has no impact on the overall execution efficiency of the kernel.
[0070] In an optional implementation, after the verification logic is completed, the execution target of the kernel static branch is atomically switched to the processor no-operation instruction, resetting the value of the counter variable to its initial value.
[0071] Specifically, after the verification logic is executed, the atomic switch of the kernel static branch's execution target to the processor no-operation instruction restores the branch key's jump address to the initially configured no-operation instruction address using an atomic instruction, allowing the target kernel function to return to its normal execution state. The recovery operation uses the same atomic instruction as the branch switch, and its execution process cannot be interrupted, ensuring the consistency of address restoration and preventing kernel execution anomalies caused by intermediate states. The recovery operation simultaneously modifies the branch key's activation status to inactive, marking that the branch has returned to its normal configuration, allowing subsequent comparison processes to trigger new switch operations normally. The recovery operation is executed in the kernel's low-priority work queue, without consuming the target kernel function's execution time or affecting the function's execution flow.
[0072] It should be noted that the verification logic described in this application is a configurable set of verification functions, the specific content of which is determined according to the type of the target kernel function and the verification requirements. The verification logic includes at least one or more of the following operations: deep validation of function input parameters, consistency check of function execution preconditions, integrity verification of the function's internal state, correctness verification of function output results, and compliance detection of call sequences in multi-core concurrent scenarios. For different types of monitored functions, it is only necessary to register the corresponding verification routine through a callback function during compilation or module loading; the entry address of the verification routine is the target address for static branch switching.
[0073] Resetting the count variables to their initial values restores the call count and exception trigger count variables to their initial zero values, preparing for the next round of statistics and verification. The reset operation is performed immediately after the verification logic completes, with no delay. The reset operation iterates through the count variables corresponding to all processors, resetting each variable's value to zero to ensure that the next round of statistics starts from the initial state, preventing historical values from affecting the statistical results. The reset operation is performed through the kernel's native per-CPU variable operation interface; each variable only resets its own value, with no cross-data interaction or lock synchronization, resulting in extremely low operational overhead.
[0074] For example, after the verification logic completes parameter validation and status detection of the target kernel function, it outputs the verification result and then performs an atomic switch operation. The kernel static branch is restored to its initial configuration, the counter variable is reset, and the target kernel function continues to execute its native process. The verification operation does not have a lasting impact on subsequent calls. When the target kernel function experiences persistent exceptions again, the statistical process restarts counting, calculates the exception ratio, and triggers a new branch switch operation. The entire process can be executed cyclically, achieving continuous monitoring of the target kernel function.
[0075] In alternative implementations, such as Figure 8 As shown, the method further includes: S300: Stores the call information of the target kernel function through a singly linked list in the RCU, allocates linked list nodes based on the processor's local Slab cache, and reads the call information in batches and performs verification within the RCU grace period.
[0076] S400: The RCU singly linked list is a lock-free linked list structure based on a read-copy-update mechanism, and the Slab cache is a memory object reuse component provided by the kernel.
[0077] Specifically, the RCU singly linked list stores the call information of the target kernel function. The RCU singly linked list is a lock-free linked list structure based on a read-copy-update mechanism. This list supports lock-free read and write operations in a multi-core environment. The stored call information includes function identifiers, execution times, parameter summaries, etc. Read operations on the RCU singly linked list are completely lock-free; multiple processors can simultaneously add nodes to the list without lock synchronization, avoiding multi-core contention. Node addition requires only a single pointer assignment instruction, resulting in extremely low overhead. Write operations on the linked list are performed only after the RCU grace period expires, without affecting read operations or interfering with the storage of the target kernel function's call information. The storage of call information is completed at the entry and exit points of the target kernel function's execution. It only requires writing the collected call information to the linked list nodes and adding them to the RCU singly linked list, without increasing the function's execution latency.
[0078] Linked list nodes are allocated based on the processor's local Slab cache. The Slab cache is a kernel-provided memory object reuse component. Each processor has an independent cache region, and linked list nodes are allocated from the local cache without cross-memory access. The creation process of the Slab cache is completed through the kernel's native Slab allocation interface, creating a dedicated pool of memory objects for the linked list nodes. The size of each memory object perfectly matches the size of the linked list node, preventing memory fragmentation. Each processor has an independent local cache region, and memory objects are allocated only from the currently executing local cache during node allocation, eliminating the need for cross-memory access and multi-core contention, resulting in extremely low allocation overhead. After use, nodes are returned to their corresponding local cache, achieving memory object reuse without frequent memory allocation and deallocation operations.
[0079] Batch reading and verification of call information within the RCU grace period involves waiting for the kernel RCU grace period to expire, then traversing the linked list to complete all call information and performing verification operations in batches. The verification process is asynchronous with the execution flow of the target kernel function. The RCU grace period is the time frame in the kernel's RCU mechanism that ensures all read operations are completed. After the grace period expires, all nodes in the linked list will not be accessed by new read operations, allowing for safe traversal and release operations. Batch verification operations are executed in the kernel's low-priority work queue, thus not consuming the execution time of the target kernel function and not affecting the kernel's business execution flow. After verification, the linked list nodes are returned to their corresponding Slab local cache, achieving memory object reuse and preventing memory leaks.
[0080] Specifically, when the target kernel function is executed, call information is written to an RCU singly linked list. List nodes are allocated from the current processor's local Slab cache, with no memory contention during allocation. When the RCU grace period is met, call information in the linked list is read in batches, and verification steps are executed sequentially. After verification, the linked list nodes are returned to the local Slab cache, achieving memory object reuse. When multiple processors execute the target kernel function simultaneously, each allocates a node from its own local Slab cache and writes it to its corresponding RCU linked list branch. There is no cross-contention or lock synchronization, and the overhead of the entire storage process is extremely low, without affecting the execution flow of the target kernel function.
[0081] In this application embodiment, a kernel dynamic verification system is provided, such as Figure 9 As shown, the system includes a branch configuration module 01, a counting acquisition module 02, and a switching execution module 03.
[0082] Branch configuration module 01 is used to configure the verification logic of the target kernel function as the processor no-operation instruction by default based on the kernel static branch.
[0083] The counting acquisition module 02 is used to collect call information and exception characteristics of target kernel functions through per-CPU dynamic counting.
[0084] The switching execution module 03 is used to atomically switch the execution target of the kernel static branch to execute the verification logic based on the statistical results of the exception characteristics and call information.
[0085] Based on the same principle, the implementation method of the kernel dynamic verification system in this application is the same as the above method, and will not be described in detail here.
[0086] The above description is merely an embodiment of this application and is not intended to limit the scope of this application. Various modifications and variations can be made to this application by those skilled in the art. Any modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of this application should be included within the scope of the claims of this application.
Claims
1. A kernel dynamic verification method, characterized in that, include: Based on kernel static branching, the verification logic of the target kernel function is configured by default as a processor no-operation instruction, and the call information and exception characteristics of the target kernel function are collected through per-CPU dynamic counting; Based on the statistical results of abnormal characteristics and call information, the execution target of the kernel static branch is atomically switched to execute the verification logic. Here, the kernel static branch is a branch switching component provided by the kernel based on jump tags, the per-CPU dynamic count is a lock-free numerical statistical operation based on processor-independent variables, and the atomic switch is an operation that modifies the execution target through a single processor atomic instruction. Based on the statistical results of anomaly characteristics and call information, the execution target of the kernel static branch is atomically switched to execute the verification logic, including: Calculate the ratio of the number of exceptions triggered to the number of calls; The ratio is compared with a preset threshold, and the execution target of the kernel static branch is atomically modified according to the comparison result. The preset threshold is a pre-configured branch switching trigger value. Based on the comparison results, the execution targets of the kernel static branches are atomically modified, including: When the ratio is greater than a preset threshold, an atomic instruction is executed to modify the jump address of the branch key. An atomic instruction is a single-cycle, uninterruptible instruction supported by the processor. Switch the jump address to the storage address of the verification logic and mark the activation status of the kernel static branch.
2. The kernel dynamic verification method according to claim 1, characterized in that, Based on kernel static branching, the verification logic of the target kernel function is configured by default as a processor no-operation instruction, including: Initialize the branch key for the kernel's static branches; Bind the execution target of the branch key to the processor no-operation instruction; The kernel static branch is associated with the execution entry point of the target kernel function, and the branch key is a variable used to identify the switching state of the kernel static branch.
3. The kernel dynamic verification method according to claim 2, characterized in that, Binding the execution target of a branch key to a processor no-operation instruction includes: Read the memory address of the processor's no-operation instruction; Configure the branch key's jump address to the memory address of the processor's no-operation instruction; Locking the initial configuration state of the branch key is a memory protection operation that prevents non-switch operations from modifying the branch key jump address.
4. The kernel dynamic verification method according to claim 1, characterized in that, The collection of call information and exception characteristics of target kernel functions through per-CPU dynamic counting includes: Configure an independent counter variable for each processor; The number of times the target kernel function is called is counted using a counter variable: The number of times an exception is triggered in the target kernel function is counted by a counter variable, which is a numerical storage unit stored in the processor's local memory.
5. The kernel dynamic verification method according to claim 4, characterized in that, The number of exceptions triggered by the target kernel function is counted using a counter variable, including: Detect the return value of the target kernel function. Detect the input parameter boundaries of the target kernel function; The value of the counter variable is updated based on the detection results of the return value and the parameter boundary. The input parameter boundary is the range of parameter values required for the execution of the target kernel function.
6. The kernel dynamic verification method according to claim 1, characterized in that, Also includes: After the verification logic is completed, the execution target of the kernel static branch is atomically switched to the processor no-operation instruction, and the value of the counter variable is reset to the initial value.
7. The kernel dynamic verification method according to claim 1, characterized in that, The method further includes: The call information of the target kernel function is stored in a singly linked list through RCU. The linked list nodes are allocated based on the processor's local Slab cache. The call information is read in batches and verified within the RCU grace period. RCU singly linked lists are lock-free linked list structures based on read-copy-update mechanisms, while Slab caches are memory object reuse components provided by the kernel.
8. A kernel dynamic verification system, characterized in that, Includes a branch configuration module, a count acquisition module, and a switch execution module; The branch configuration module is used to configure the verification logic of the target kernel function as the processor no-operation instruction by default based on the kernel static branch. The kernel static branch is a branch switching component provided by the kernel based on the jump label. The counting and acquisition module is used to collect call information and exception characteristics of target kernel functions through per-CPU dynamic counting. Per-CPU dynamic counting is a lock-free numerical statistical operation based on processor-independent variables. The execution switching module is used to atomically switch the execution target of the kernel static branch to execute verification logic based on statistical results of exception characteristics and call information. Atomic switching is an operation that modifies the execution target through a single processor atomic instruction. Specifically, atomically switching the execution target of the kernel static branch to execute verification logic based on statistical results of exception characteristics and call information includes: calculating the ratio of exception trigger counts to call counts; comparing the ratio with a preset threshold; atomically modifying the execution target of the kernel static branch based on the comparison result; and, when the ratio is greater than the preset threshold, executing an atomic instruction to modify the jump address of the branch key. The atomic instruction is a single-cycle uninterruptible execution instruction supported by the processor. Finally, the jump address is switched to the storage address of the verification logic, and the activation state of the kernel static branch is marked.
Citation Information
Patent Citations
Data processing method, device and equipment and readable storage medium
CN116719663A
Method and system for detecting and diagnosing abnormal calling of linux system timer
CN119440222A