Linux USB drive fuzzy testing method and system based on component weighted scheduling
Through the component-weighted scheduling method, the test case scheduling of USB driver fuzz testing is optimized, which solves the problems of unreasonable scheduling and slow coverage improvement in the existing technology, and achieves a more efficient improvement in the coverage of USB driver fuzz testing.
Patent Information
- Application Number
- CN202411763337.8
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2024-12-03
- Publication Date
- 2025-03-25
AI Technical Summary
In the existing USB driver fuzz testing technology, the test case scheduling is unreasonable, resulting in slow coverage improvement, wasted computing resources, and failure to effectively distinguish and process different types of USB drivers.
Using a component-weighted scheduling method, we use extracts and filters USB-related components in the Linux kernel, builds component dependency graphs, assigns weights, and optimizes the execution and mutation strategies of test cases to improve coverage.
It improves the orientation to USB drivers, and effectively cross-mutation covers test cases of related USB components, significantly accelerates the coverage of Linux USB driver fuzz testing, and exceeds the performance of existing open source fuzz testing tools.
Smart Images

Figure CN119691750A_ABST
Abstract
Description
Technical Field
[0001] The present invention relates to the field of network system security vulnerability detection, and in particular to a Linux USB driver fuzzy testing method and system based on component weighted scheduling. Background Art
[0002] The Universal Serial Bus (USB) protocol is a universal serial bus standard that provides a unified master-slave connection protocol for peripheral devices of various purposes. It also has many convenient functions. It can not only be used to transmit data and provide power, but also supports plug-and-play. It is widely used in computer systems such as IoT terminals, smart devices and servers. Many mainstream operating systems (such as Linux) have integrated USB device drivers in their subsystems. As the technology improves and matures, the USB protocol will gradually replace other interface standards and support more peripheral devices.
[0003] However, there are still many security vulnerabilities in the USB drivers of the mainstream operating system Linux. Attackers can inject malicious data into the USB drivers on the host through USB peripherals, causing task interruption, system crash, and code injection. Based on network technologies such as USB / IP, attackers can also attack USB drivers without hardware connection, threatening the normal operation of key computer devices. Therefore, it is crucial to discover and fix vulnerabilities in USB drivers as soon as possible.
[0004] In order to detect potential vulnerabilities in USB drivers, the most effective method at present is to use fuzz testing technology. It can obtain test cases through generation and mutation mechanisms, and input the test cases into the target software to trigger potential vulnerabilities. Scheduling technology refers to sorting the potential of test cases according to specific indicators during the fuzz testing process, so that high-potential test cases are executed and mutated first. At present, many software use fuzz testing technology to automatically discover vulnerabilities and have achieved remarkable results. The most advanced kernel fuzz testing tool at present is Syzkaller, which is mainly used to test system calls initiated by the user layer to the kernel layer. But it also provides a pseudo system call interface to interact with the USB driver, so that the peripheral device interface of the USB driver can be tested like a system call. Specifically, through the raw gadget and dummy_hcd mechanisms of the Linux kernel, Syzkaller allows user space test cases to simulate the process of injecting data from USB peripheral devices to the host USB driver. Most existing USB driver fuzz testing methods are based on Syzkaller for improvement, but they focus on expanding the analysis scope and using static analysis and symbolic execution technology to generate effective test cases. These methods can significantly improve the upper limit of the final coverage. However, in actual fuzz testing, the coverage rate still increases very slowly. The main reason is that the scheduling strategy of the existing method does not fully evaluate and give full play to the actual potential of the test cases, resulting in a waste of computing resources. On the one hand, the existing USB test case evaluation does not focus on the USB driver code. In fact, there is a large amount of coverage information of the USB core layer in the existing USB driver coverage feedback, while the information about the driver is very limited. Therefore, under the existing evaluation scheme that only considers the number of new coverage rates, a large amount of computing power will be consumed on test cases that only touch the USB core layer; on the other hand, the scheduling of the existing scheme ignores the diversity of the USB driver itself and does not distinguish between them. In the Linux system, there are a large number of different types of USB drivers. These USB drivers exchange data with the corresponding subsystems (such as storage, audio subsystem, etc.), so the supported data protocols are also different. However, the existing USB fuzz testing method does not distinguish between USB drivers, but uniformly schedules and processes them, and uses a single indicator to determine the priority of test cases, thereby consuming a lot of computing resources. After these test cases with large differences are cross-mutated, a large number of invalid test cases will be further generated. These defects prevent the existing fuzz testing tools from going deep into the USB driver code, making it difficult to dig deep driver vulnerabilities.
[0005] The prior art with document number CN118193375A discloses a black box fuzz testing method and system guided by linear temporal logic on finite traces, the method comprising: screening abnormal behaviors of the system under test by checking the message interaction path with the system under test, introducing linear temporal logic on finite traces to express the security attributes of the system under test, and finding counterexamples that deviate from the security attributes through lightweight runtime verification. The present invention expresses the security attributes that should be met by the security protocol implementation through LTL, converts the negative form of LTL into the corresponding DFA, guides the generation of fuzzy test sequences based on DFA, detects abnormal behaviors based on abstract input and output paths and outputs counterexamples, and further analyzes the counterexamples to determine whether they constitute logical vulnerabilities. This method effectively and automatically detects logical vulnerabilities in security protocol implementations, but still does not respond to the above-mentioned problems. Summary of the invention
[0006] The technical problems to be solved by the present invention are:
[0007] Aiming at the problems existing in the existing USB driver fuzzy testing technology, such as unreasonable scheduling of USB driver test cases and impact on coverage improvement of Linux USB driver fuzzy testing, the present invention proposes a Linux USB driver fuzzy testing method and system based on component weighted scheduling.
[0008] The technical solution adopted by the present invention to solve the above technical problems is:
[0009] A Linux USB driver fuzz testing method based on component weighted scheduling, the implementation process of the method is as follows:
[0010] Step 1: Extract and filter out USB-related components in the Linux kernel, thereby accurately narrowing the scope of code analysis for the Linux USB driver, where components are defined as the source code corresponding to each configuration item in Kconfig.
[0011] The basis for determining whether a component is related to USB is that the Kconfig configuration item corresponding to the component has a direct or indirect dependency relationship with the USB configuration item, where the dependency relationship includes the directory dependency marked with the "menu" keyword in Kconfig, the strong dependency marked with "depends on", the inverse dependency marked with "select", and the weak dependency marked with "imply";
[0012] Step 2: Extract the dependency graph of Linux USB driver-related components to prepare for weight allocation; the component dependency graph needs to be defined by four dependencies in Kconfig, with the priorities from high to low being directory dependency, strong dependency, inverse dependency, and weak dependency; during analysis, the Kconfig parser will be used to traverse the Kconfig files of each source directory, first build a dependency graph of high-priority dependencies, and then re-traverse the source directory to build a dependency graph of low-priority dependencies based on the high-priority dependency graph; if a low-priority dependency will form a loop with the original dependency, the low-priority dependency will be ignored;
[0013] Step 3: Based on the component dependency graph, different weights are assigned to USB-related components to ensure that components containing USB driver code have a larger weight, while components containing underlying USB core code have a smaller weight; the weight assignment needs to traverse the component dependency graph in topological order, so as to ensure that each time the weight of a component is calculated, the weights of all pre-components have been calculated; the weight calculation method needs to comprehensively consider the weights and in-and-out degrees of all pre-components, and add a fixed constant based on the weight of the pre-component;
[0014] Step 4: According to the weights assigned to the USB-related components, the Linux image configuration containing the most components and capable of successful compilation is screened out, wherein the screening method of the present invention needs to sort the components in descending order according to the weight, and select the components to be added to the configuration according to the dichotomy method; the Kconfig system will automatically add the pre-components that the configured components depend on to the configuration, finally forming a .config file, and completing the compilation of the Linux test image;
[0015] Step 5: Extract the mapping relationship between addresses and components from the Linux source code and build directory, mainly including recursively parsing each Makefile file, extracting the correspondence between each component and the object file, extracting the correspondence between the function address and the source code file from System.map, and finally establishing the mapping relationship between the address and the component based on the same name relationship between the object file and the source code file;
[0016] Step 6: Use the remote KCOV mechanism of Linux to collect the tracking data of the coverage feedback of the USB driver test case, and use the mapping relationship in step 5 to convert it from the address-level sequence to the component-level sequence;
[0017] Step 7: When the fuzz test is executed, the priority of executing the test case needs to be weighted and evaluated according to the components tracked by the coverage feedback. The weighted calculation needs to be calculated according to the weight assigned in step 3, and the weights of all components tracked by the coverage feedback are added one by one as one of the considerations for evaluating the priority.
[0018] Step 8: When the fuzzy test is mutated, clustering needs to be completed according to the component feature distance of the current test case that needs to be mutated;
[0019] Among them, fuzz testing will maintain a distance matrix of existing test cases to save component feature distances; the calculation of component feature distances requires using the component sequence converted by the test case coverage feedback tracking, converting it into a corresponding weight sequence, and then calculating the distance between the sequences;
[0020] Each time mutation is required, a fixed proportion of test cases are randomly selected and the distance is updated, and finally the cross-mutation is completed together with the fixed number of test cases with the closest distance.
[0021] The present invention has the following beneficial technical effects:
[0022] The present invention provides a component weighted scheduling method for Linux USB driver fuzzy testing, which can not only improve the guidance of USB drivers, but also enable test cases covering related USB components to effectively cross-mutate. This solves the problem of unreasonable scheduling of USB driver test cases and accelerates the improvement of the coverage rate of Linux USB driver fuzzy testing.
[0023] The present invention surpasses the existing open source fuzz testing tool Syzkaller in terms of overall coverage and coverage under specific USB driver directories.
[0024] The present invention implements a prototype USBox, and all code writing and evaluation are performed on a computer equipped with an Intel Core i5-13600KF 5.1GHz CPU and 64GiB memory. The operating system kernel is 64-bit Ubuntu 22.04LTSLinux6.5.0-35-generic, and the compiler used to compile the kernel is GCC 11.4. To ensure the fairness of the experiment, the QEMU simulator of all experiments uses the same parameters and mode. All instances run an equal number of virtual machines to achieve parallelization, and each virtual machine is allocated 2 CPU cores and 8GiB memory.
[0025] Figure 2The block coverage changes of USBox, Syzkaller++ and Syzkaller on Linux kernel versions v6.6, v6.7, v6.8 and v6.9 after running for 12 hours respectively are shown. Syzkaller++ is Syzkaller with the latest corpus on Syzbot attached. It can be seen that the prototype USBox of the invention can quickly improve the block coverage, surpassing other fuzz testing tools.
[0026] Figure 2 The block coverage of each fuzz test tool on some directories after 12 hours of fuzz testing on Linux version v6.9 is shown. It can be seen that the prototype USBox of the present invention can surpass other similar tools on multiple directories, especially on deep USB driver directories. This shows that the present invention can improve the testing effect on USB drivers.
[0027] The present invention improves the scheduling technology of the kernel driver fuzz tester, and is used to improve the vulnerability mining effect of the USB driver. The present invention is mainly applied to the field of system security, especially USB driver fuzz testing. BRIEF DESCRIPTION OF THE DRAWINGS
[0028] Figure 1 It is a schematic diagram of the process of the present invention; Figure 2 The coverage curve of fuzz testing running for 12 hours on four Linux kernel versions; Figure 3 This is a bar chart showing coverage of some key directories after 12 hours of fuzz testing.
[0029] Figure 4 This is a dependency graph of some USB-related components; Figure 5 A diagram showing the steps for parsing component address intervals; Figure 6 Schematic diagram of the steps for clustering test cases based on component feature distance. DETAILED DESCRIPTION
[0030] Give Figures 1 to 6 , the implementation process of the present invention is described as follows:
[0031] The present invention provides a vulnerability mining method, comprising:
[0032] 1. Extract and filter out USB-related components in the Linux kernel, so as to accurately narrow the scope of code analysis of the Linux USB driver. The component is defined as the source code corresponding to each configuration item in Kconfig. The basis for determining the correlation between the component and USB is that the Kconfig configuration item corresponding to the component has a direct or indirect dependency relationship with the USB configuration item. The dependency relationship includes the directory dependency marked with the "Menu" keyword in Kconfig, the strong dependency marked with "depends on", the inverse dependency marked with "select", and the weak dependency marked with "imply".
[0033] 2. Extract the dependency graph of Linux USB driver-related components to prepare for weight distribution. The component dependency graph needs to be defined by four dependencies in Kconfig, with the priorities from high to low being directory dependency, strong dependency, inverse dependency, and weak dependency. During analysis, the Kconfig parser will be used to traverse the Kconfig files of each source directory, first build a dependency graph of high-priority dependencies, and then re-traverse the source directory to build a dependency graph of low-priority dependencies based on the high-priority dependency graph. If a low-priority dependency will form a loop with the original dependency, the low-priority dependency will be ignored.
[0034] 3. Based on the component dependency graph, different weights are assigned to USB-related components to ensure that components containing USB driver code have greater weights, while components containing underlying USB core code have smaller weights. The weight assignment needs to traverse the component dependency graph in topological order to ensure that each time a component's weight is calculated, the weights of all pre-components have been calculated. The weight calculation method needs to comprehensively consider the weights and in-and-out degrees of all pre-components, and add a fixed constant based on the pre-component weights.
[0035] 4. According to the weights assigned to the USB-related components, filter out the Linux image configuration that contains the most components and can be successfully compiled. The screening method of the present invention needs to sort the components in descending order according to the weight, and select the components to be added to the configuration according to the dichotomy. The Kconfig system will automatically add the pre-components that the configured components depend on to the configuration. Finally, the .config file is formed, and the compilation of the Linux test image is completed.
[0036] 5. Extract the mapping relationship between addresses and components from the Linux source code and build directory. This mainly includes recursively parsing each Makefile file, extracting the corresponding relationship between each component and the object file, extracting the corresponding relationship between the function address and the source code file from System.map, and finally establishing the mapping relationship between the address and the component based on the same name relationship between the object file and the source code file. Due to the large number of addresses, the present invention merges adjacent addresses belonging to the same component into intervals to facilitate subsequent conversion.
[0037] 6. Use Linux's remote KCOV mechanism to collect the tracking data of the coverage feedback of the USB driver test case, and use the mapping relationship in step 5 to convert it from the address-level sequence to the component-level sequence.
[0038] 7. When the fuzz test is executed, the priority of executing the test case needs to be weighted and evaluated according to the components tracked by the coverage feedback. The weighted calculation needs to add the weights of all components tracked by the coverage feedback one by one according to the weights assigned in step 3, as one of the considerations for evaluating the priority.
[0039] 8. When the fuzzy test mutates, clustering needs to be completed based on the component feature distance of the current test case that needs to be mutated. Among them, the fuzzy test will maintain a distance matrix of existing test cases to save the component feature distance. The calculation of the component feature distance requires the use of the component sequence converted by the coverage feedback tracking of the test case, and after converting it into the corresponding weight sequence, the distance between the sequences is calculated. This distance can use the Euclidean distance or the distance calculation formula adopted by the specific implementation scheme of the present invention. Each time a mutation is required, a fixed proportion of test cases will be randomly selected, and the distance will be updated, and finally the cross mutation will be completed together with the fixed number of test cases with the closest distance.
[0040] The overall flow chart of the invention is shown in Figure (1). Steps 1-3 are component weight allocation based on dependency graph, steps 4-5 are component address interval resolution, and steps 6-8 are test case clustering based on component feature distance.
[0041] Example:
[0042] Component weight assignment based on dependency graph
[0043] This part is divided into two steps. First, the USB-related components and their dependency graphs need to be extracted, and finally weights are assigned based on them.
[0044] There are various functional components in the Linux kernel, which are organized into a tree-like directory structure in the Kconfig configuration system built into the Linux kernel. Developers can use Kconfig to choose to compile these functional components into the kernel, compile them into modules, or not compile them. There is a dependency relationship between these components, which ensures that the pre-components will not be lost during compilation. As shown in Figure (4), each directed edge represents this dependency relationship, that is, the source component depends on the target component it points to. It can be seen that the components closer to the front of the dependency chain tend to integrate the functions of the USB core or other underlying functions; and the components closer to the back of the dependency chain tend to integrate specific USB driver functions. In order to distinguish different components and focus the subsequent fuzz testing on the USB driver components, the present invention needs to extract the dependency graph from the USB-related components so that the components that integrate the USB driver functions have a higher weight.
[0045] The present invention firstly adopts Kconfig parser to recursively parse each configuration option in each Linux kernel, and constructs the components that have direct or indirect dependency with USB functions into the form of dependency graph. Among them, the present invention summarizes four kinds of dependency relationships, namely, directory dependency relationship marked by "Menu" keyword, strong dependency relationship marked by "depends on", inverse dependency relationship marked by "select" and weak dependency relationship marked by "imply". When constructing, the above-mentioned dependency relationships will be extracted in sequence according to the priority from high to low to construct and supplement the dependency graph, and the dependency that will generate loops will be ignored to ensure that the obtained dependency graph is a directed acyclic graph.
[0046] After obtaining the component dependency graph, the present invention calculates the weight of each component. The present invention assigns different weights to these different components to extract the characteristics of the components on the coverage path. To this end, the present invention designs a component weight allocation algorithm based on the component dependency graph. The algorithm steps are as follows:
[0047] 3) Extract the components with out-degree 0 in the component dependency graph, that is, components that do not need to depend on any other components, and assign weights to these components as initial values (usually set to 1).
[0048] 4) Starting from these components with out-degree 0, calculate the weights of the components that depend on them in topological order. The topological order ensures that the weights of all existing predecessor components have been calculated before calculation.
[0049] 5) Specifically, the weight calculation formula is: Among them, n.deps represents the set of pre-components that n depends on. O m and I mare the out-degree and in-degree of m respectively. This formula first needs to calculate the ratio R of the out-degree to in-degree of each component m of n's dependency m , this value can reflect the relative position of the component to the driver code. Generally speaking, the higher the out-degree and the lower the in-degree, the closer the component is to the driver code, so R m In addition, this component also needs to consider the weight W of each dependent pre-component m , so the weight of the current component W n It is through R m With W m Obtained by weighted summation.
[0050] 6) When all component weights on the component dependency graph are calculated, the algorithm ends.
[0051] The algorithm will obtain a component weight function φ:M→R, where M is the set of USB-related components and R is the real number field. This component weight function will be used to evaluate and cluster test cases in the next fuzz test run.
[0052] Component address range mapping analysis
[0053] The main steps of this part are shown in Figure (5). It is mainly divided into three steps: First, extract the relationship between components and object files from Makefile. Then extract the correspondence between function addresses and source files from System.map. Finally, construct the correspondence between function addresses and components and merge address ranges. Finally, a mapping table from address ranges to components can be obtained.
[0054] First, the Linux kernel needs to be compiled according to a specific configuration. The present invention sorts the components from large to small based on their weights, and uses a binary search method to select the largest kernel configuration file .config that can be successfully mutated. In order to ensure that the system image can provide a coverage feedback mechanism and detect anomalies, it is also necessary to turn on the CONFIG_KCOV and CONFIG_KASAN options in .config. After successfully completing the compilation, the present invention needs to extract the components corresponding to each address range in the compiled image. First, the present invention parses the Makefile files in the Linux kernel source code tree, which record the correspondence between components and binary object files. The present invention writes a regular expression-based parser that recursively parses each Makefile file to eventually obtain the component to which each object file belongs. First, extract all Linux kernel source code directories that have USB component codes, which can be obtained by searching for the usb string. Then, starting from the leaf directory at the end, match all object files in the current directory that can confirm the attribution relationship. Specifically, the basic expression in the Makefile file is an equation, with the component on the left side of the equal sign and the object file belonging to the component on the right side of the equal sign. For object files whose ownership cannot be determined in the current directory, it is necessary to query the parent directory level by level. By traversing all directories with USB codes in sequence, a USB component mapping table to which each object file belongs can be constructed.
[0055] Next, the present invention needs to parse the source code file to which each function address belongs. The System.map file in the Linux build root directory records all the symbol information in the compiled vmlinux file. The present invention uses addr2line to scan the symbols of all function types in System.map to obtain the function name, address and corresponding source code file of each function.
[0056] Finally, the present invention associates function addresses with components. Since function addresses of the same source file are usually adjacent, the present invention merges all function addresses of the same component into a continuous address range, which is convenient for mapping the addresses to the corresponding components at runtime. Specifically, all addresses are sorted in order from small to large, and then adjacent addresses belonging to the same component are merged into the same range. The present invention excludes debug trace functions by regular matching.
[0057] Through the above steps, the present invention obtains a mapping table that records the components to which each address interval belongs, which can be formalized as λ:B→M, where B is the set of all basic block addresses and M is the set of all USB-related components. This will be used to extract component features from the coverage feedback tracking of test cases.
[0058] Test case clustering based on component feature distance
[0059] In order to effectively schedule USB test cases, we adopted a two-stage process, as shown in Figure (6). First, we used the previously obtained component address range and component weight information to convert the test case coverage feedback into component features, and completed the weighted evaluation priority according to the component weight. Finally, the test cases were clustered based on the component feature distance to complete dynamic cross-mutation. This ensures that high-potential test cases are prioritized and improves the utilization of test cases.
[0060] During the fuzz testing process, the present invention collects the basic block address sequence covered by each test case from the KCOV cache as coverage feedback. The present invention uses the component address interval mapping table λ: B→M and the component weight function φ: M→R to evaluate the original coverage feedback. This process can be formalized as follows:
[0061] 1. In order to extract features from the test case at the component level, the present invention converts the coverage feedback of the test case into a component sequence. Execute each test case to obtain the coverage feedback sequence. Given a test case coverage feedback sequence Cov = {b1, b2, ..., b n}, where b i ∈B, 0≤i≤n, the component address interval mapping table λ can be used to calculate the component sequence Mcov={λ(b1),λ(b2),…,λ(b n )}={m1,m2,…,m n},m i ∈M,
[0062] 0≤i≤n.
[0063] 2. Use the component weight function φ:M→R to calculate the priority of the test case Where p is the number of previously uncovered addresses.
[0064] 3. When the fuzz test is running, the priority queue of test cases is maintained, and the test case with the largest priority P is selected each time.
[0065] Afterwards, the present invention will complete clustering based on the component feature distance during mutation, with the test case currently in need of mutation as the center, thereby improving the effectiveness of mutation of similar test cases. In the specific scheme of the present invention, a distance matrix D is maintained during operation, recording the component feature distance information between existing test cases. Assuming that the test case currently in need of mutation is u, the specific steps are as follows:
[0066] 1. First, randomly select 5% of the test cases from the set of test cases, calculate the component feature distance with the current test case u, and update the distance matrix D.
[0067] 2. Sort the above test cases in ascending order according to the component feature distance and put them into queue Q.
[0068] 3. Obtain each test case v in Q in turn, obtain several (usually 10) test cases w closest to v in the distance matrix D, calculate the distance between u and w, and update the distance matrix D.
[0069] 4. Obtain several (usually 10) test cases closest to u from the distance matrix D and perform cross-mutation.
[0070] Through the above process, similar test cases can generate more effective cross-mutation, thereby obtaining new test cases that can cover more deep paths. The calculation steps of the component feature distance mentioned above are described as follows. Assume that the component feature distance between test case u and test case v needs to be calculated, and the component coverage feedback of u is Ucov = {u1,u2,…,u x}, and {λ(u1),λ(u2),…,λ(u x )}={m1,m2,…,m x}, and the coverage feedback of v is Vcov = {v1,v2,…,v y},So
[0071] 1. First calculate TF u ={f(m1),f(m2),…,f(m x )},m i ∈M,0≤i≤x, where This counts the frequency of each component in Ucov.
[0072] 2. After that, for each component m, calculate where |Z| represents the number of all test cases, and |Z m |
[0073] It represents the number of all test cases that contain component m. Count the inverse document frequency IDFm of each component in all current test cases.
[0074] 3. According to the above IDF value, calculate the vector Where Λ=
[0075] diag(λ(m1),λ(m2),…,λ(m n )), n is the number of all current components. The vector t represents the eigenvalue of each component.
[0076] 4. Calculate component feature distance This calculation formula replaces the addresses in the coverage feedback sequences of the two test cases u and v with the eigenvalues of each component of the vector t, and compares the similarity of the two sequences. Since some components belonging to the USB core will appear repeatedly, the present invention uses the TF index to reduce their influence on the distance metric. The TF index is the word frequency index, which is a commonly used concept in the field of natural language processing.
[0077] Through the above calculation process, it is finally possible to cluster test cases and complete crossover mutation to obtain new test cases.
[0078] In summary, the scheduling method proposed in the present invention can not only improve the guidance of USB drivers, but also enable the test cases covering related USB components to effectively cross-mutate. This solves the problem of unreasonable scheduling of USB driver test cases and accelerates the improvement of the coverage of Linux USB driver fuzzy testing. The method of the present invention has been verified through simulation experiments and practical applications, and the technical effects and practicality claimed by the present invention have been verified.
[0079] The method of the present invention has been verified through simulation experiments and practical applications, and the technical effects claimed by the present invention have been verified.
[0080] The algorithm (method) proposed in the present invention is the underlying technical core of the present invention, and various products can be derived based on the algorithm.
[0081] Based on the algorithm (method) proposed in the present invention, a Linux USB driver fuzzy testing system based on component weighted scheduling is developed using a programming language. The system has program modules corresponding to the steps of the above technical solution, and executes the steps in the above Linux USB driver fuzzy testing method based on component weighted scheduling during operation.
[0082] The computer program of the developed system (software) is stored on a computer-readable storage medium, and the computer program is configured to implement the steps of the above-mentioned Linux USB driver fuzz testing method based on component weighted scheduling when called by a processor, that is, the present invention is materialized on a carrier to become a computer program product.
[0083] The systems described herein may be implemented in digital electronic circuit systems, integrated circuit systems, dedicated ASICs (application specific integrated circuits), computer hardware, firmware, software, and / or combinations thereof. These various implementations may include: being implemented in one or more computer programs that can be executed and / or interpreted on a programmable system including at least one programmable processor, which may be a dedicated or general-purpose programmable processor that can receive data and instructions from a storage system, at least one input device, and at least one output device, and transmit data and instructions to the storage system, the at least one input device, and the at least one output device.
[0084] The computer programs (also referred to as programs, software, software applications, or codes) of the present invention include machine instructions for programmable processors, and these computer programs can be implemented using high-level procedural and / or object-oriented programming languages, and / or assembly / machine languages. As used in the present invention, the terms "machine-readable medium" and "computer-readable medium" refer to any computer program product, device, and / or device (e.g., disk, optical disk, memory, programmable logic device PLD) for providing machine instructions and / or data to a programmable processor, including a machine-readable medium that receives machine instructions as machine-readable signals. The term "machine-readable signal" refers to any signal for providing machine instructions and / or data to a programmable processor.
[0085] It should be understood that the various forms of processes shown above can be used to reorder, add or delete steps. For example, the steps recorded in this application can be executed in parallel, sequentially or in different orders, as long as the expected results of the technical solution disclosed in this application can be achieved, they are all within the scope of protection of the present invention.
Claims
1. A Linux USB driver fuzz testing method based on component weighted scheduling, characterized in that: The implementation process of the method is: Step 1: Extract and filter out USB-related components in the Linux kernel, thereby accurately narrowing the scope of code analysis for the Linux USB driver, where components are defined as the source code corresponding to each configuration item in Kconfig. The basis for determining whether a component is related to USB is that the Kconfig configuration item corresponding to the component has a direct or indirect dependency relationship with the USB configuration item, where the dependency relationship includes the directory dependency marked with the "menu" keyword in Kconfig, the strong dependency marked with "depends on", the inverse dependency marked with "select", and the weak dependency marked with "imply"; Step 2: Extract the dependency graph of Linux USB driver related components to prepare for weight allocation; The component dependency graph needs to be defined by four dependencies in Kconfig, with the priorities from high to low being directory dependency, strong dependency, inverse dependency, and weak dependency. During analysis, the Kconfig parser will be used to traverse the Kconfig files of each source directory, first build a dependency graph of high-priority dependencies, and then traverse the source directory again to build a dependency graph of low-priority dependencies based on the high-priority dependency graph. If a low-priority dependency will form a loop with the original dependency, the low-priority dependency will be ignored. Step 3: Based on the component dependency graph, different weights are assigned to USB-related components to ensure that components containing USB driver code have a larger weight, while components containing underlying USB core code have a smaller weight; the weight assignment needs to traverse the component dependency graph in topological order, so as to ensure that each time the weight of a component is calculated, the weights of all pre-components have been calculated; the weight calculation method needs to comprehensively consider the weights and in-and-out degrees of all pre-components, and add a fixed constant based on the weight of the pre-component; Step 4: According to the weights assigned to the USB-related components, the Linux image configuration containing the most components and capable of successful compilation is screened out, wherein the screening method of the present invention needs to sort the components in descending order according to the weight, and select the components to be added to the configuration according to the dichotomy method; the Kconfig system will automatically add the pre-components that the configured components depend on to the configuration, finally forming a .config file, and completing the compilation of the Linux test image; Step 5: Extract the mapping relationship between addresses and components from the Linux source code and build directory, mainly including recursively parsing each Makefile file, extracting the correspondence between each component and the object file, extracting the correspondence between the function address and the source code file from System.map, and finally establishing the mapping relationship between the address and the component based on the same name relationship between the object file and the source code file; Step 6: Use the remote KCOV mechanism of Linux to collect the tracking data of the coverage feedback of the USB driver test case, and use the mapping relationship in step 5 to convert it from the address-level sequence to the component-level sequence; Step 7: When the fuzz test is executed, the priority of executing the test case needs to be weighted and evaluated according to the components tracked by the coverage feedback. The weighted calculation needs to be calculated according to the weight assigned in step 3, and the weights of all components tracked by the coverage feedback are added one by one as one of the considerations for evaluating the priority. Step 8: When the fuzzy test is mutated, clustering needs to be completed according to the component feature distance of the current test case that needs to be mutated; Among them, fuzz testing will maintain a distance matrix of existing test cases to save component feature distances; the calculation of component feature distances requires using the component sequence converted by the test case coverage feedback tracking, converting it into a corresponding weight sequence, and then calculating the distance between the sequences; Each time mutation is required, a fixed proportion of test cases are randomly selected and the distance is updated, and finally the cross-mutation is completed together with the fixed number of test cases with the closest distance.
2. A Linux USB driver fuzz testing method based on component weighted scheduling according to claim 1, characterized in that: In step five, when the number of addresses is large, that is, when the number of addresses exceeds 10% of the number of component functions, adjacent addresses belonging to the same component are merged into intervals to facilitate subsequent conversion.
3. A Linux USB driver fuzz testing method based on component weighted scheduling according to claim 1, characterized in that: In step eight, the distance between the sequences may be calculated using the Euclidean distance.
4. A Linux USB driver fuzz testing method based on component weighted scheduling according to claim 1, characterized in that: The specific process of component weight allocation based on the dependency graph is: It is necessary to extract the USB-related components and their dependency graphs, and finally assign weights based on them: There are various functional components in the Linux kernel, which are organized into a tree-like directory structure in the Kconfig configuration system built into the Linux kernel. The focus of subsequent fuzz testing is placed on the USB driver components to distinguish different components, extract the dependency graph of USB-related components, and give components that integrate USB driver functions a higher weight; First, the Kconfig parser is used to recursively parse each configuration option in each Linux kernel, and the components that have direct or indirect dependencies on the USB functions are constructed into a dependency graph, giving four types of dependencies: directory dependencies marked with the "Menu" keyword, strong dependencies marked with "depends on", inverse dependencies marked with "select", and weak dependencies marked with "imply". During construction, the above dependencies will be extracted in order from high to low priority to construct and supplement the dependency graph, and dependencies that will produce loops will be ignored to ensure that the obtained dependency graph is a directed acyclic graph. After obtaining the component dependency graph, the weight of each component is calculated, and different weights are assigned to these different components to extract the characteristics of the components on the coverage path.
5. A Linux USB driver fuzz testing method based on component weighted scheduling according to claim 4, characterized in that: The component weight allocation process based on the component dependency graph is: 1) Extract the components with out-degree 0 in the component dependency graph, that is, the components that do not need to depend on any other components, and assign weights to these components as initial values; 2) Starting from these components with out-degree 0, weights are calculated for the components that depend on them in topological order. The topological order ensures that the weights of all existing predecessor components have been calculated before the calculation. 3) The weight calculation formula is: Among them, n.deps represents the set of pre-components that n depends on. O m and I m are the out-degree and in-degree of m respectively; The formula first needs to calculate the ratio R of the out-degree to in-degree of each component m that n depends on m , R m The value reflects the relative position of the component and the driver code; Weight W n It is through R m With W m Obtained by weighted summation; 4) Calculate the weights of all components on the component dependency graph.
6. A Linux USB driver fuzz testing method based on component weighted scheduling according to claim 4 or 5, characterized in that: The process of component address interval mapping and parsing is as follows: first, extract the attribution relationship between components and object files from Makefile; then extract the correspondence between function addresses and source files from System.map; finally, construct the correspondence between function addresses and components, and merge address intervals, and finally get a mapping table from address intervals to components; specifically: First, you need to compile the Linux kernel according to a specific configuration. Based on the weights of the above components, sort them from large to small, and use the binary search method to select the largest kernel configuration file .config that can be successfully mutated. In order to ensure that the system image can provide a coverage feedback mechanism and detect anomalies, turn on the CONFIG_KCOV and CONFIG_KASAN options in .config. After the compilation is successfully completed, extract the components corresponding to each address range in the compiled image. Parse the Makefile file in the Linux kernel source tree that records the correspondence between components and binary object files, write a regular expression-based parser, and recursively parse Each Makefile file eventually gets the component to which each object file belongs; extract all Linux kernel source code directories with USB component codes, which can be obtained by searching for the string usb; then start from the last leaf directory and match all object files in the current directory whose ownership relationship can be confirmed; the basic expression in the Makefile file is an equation, with the component on the left side of the equal sign and the object file belonging to the component on the right side of the equal sign; for object files whose ownership relationship cannot be determined in the current directory, it is necessary to query the parent directory step by step; traverse all directories with USB codes in turn, and finally build a USB component mapping table to which each object file belongs; Next, parse the source code file to which each function address belongs; record all symbol information in the compiled vmlinux file in the System.map file in the Linux build root directory; use addr2line to scan the symbols of all function types in System.map to obtain the function name, address and corresponding source code file of each function; Finally, associate the function address with the component. Since the function addresses of the same source file are usually adjacent, all function addresses of the same component are merged into a continuous address range to facilitate the subsequent mapping of the address to the corresponding component at runtime; all addresses are sorted in order from small to large, and then adjacent addresses belonging to the same component are merged into the same range; and the functions for debugging and tracing are excluded through regular matching.
7. A Linux USB driver fuzz testing method based on component weighted scheduling according to claim 6, characterized in that: The specific process of test case clustering based on component feature distance is as follows: Using the previously obtained component address range and component weight information, the test case coverage feedback is converted into component features, and weighted evaluation priorities are completed according to the component weights. Finally, the test cases are clustered based on the component feature distance to complete dynamic crossover mutation. During the fuzz testing process, the basic block address sequence covered by each test case is collected from the KCOV cache as coverage feedback; the original coverage feedback is evaluated using the component address interval mapping table λ:B→M and the component weight function φ:M→R, which is formalized as follows: 1) Convert the coverage feedback of the test case into a component sequence to extract features of the test case from the component level, and execute each test case to obtain the coverage feedback sequence; given the coverage feedback sequence of the test case Cov = {b1, b2, ..., b n }, where b i ∈B, 0≤i≤n, and use the component address interval mapping table λ to calculate the component sequence Mcov={λ(b1),λ(b2),…,λ(b n )}={m1,m2,…,m n },m i ∈M, 0≤i≤n; 2) Use the component weight function φ:M→R to calculate the priority of the test case Where p is the number of previously uncovered addresses; 3) When the fuzz test is running, a priority queue of test cases is maintained, and the test case with the largest priority P is selected each time.
8. A Linux USB driver fuzz testing method based on component weighted scheduling according to claim 7, characterized in that: During mutation, clustering is completed based on the component feature distance, with the test case that currently needs to be mutated as the center, thereby improving the effectiveness of mutation of similar test cases. During the operation, a distance matrix D is maintained to record the component feature distance information between existing test cases. Assuming that the test case that currently needs to be mutated is u, the specific steps are as follows: 1) First, randomly select 5% of the test cases from the set of test cases, calculate the component feature distance with the current test case u, and update the distance matrix D; 2) Sort the above test cases in ascending order according to component feature distance and put them into queue Q; 3) Obtain each test case v in Q in turn, obtain several test cases w closest to v in the distance matrix D, calculate the distance between u and w, and update the distance matrix D; 4) Obtain several test cases closest to u from the distance matrix D and perform cross-mutation; The calculation steps of component feature distance are as follows: Assume that the component feature distance between test case u and test case v needs to be calculated, and the component coverage feedback of u is Ucov = {u1,u2,…,u x }, and {λ(u1),λ(u2),…,λ(u x )}={m1,m2,…,m x }, and the coverage feedback of v is Vcov = {v1,v2,…,v y },So 1) First calculate TF u ={f(m1),f(m2),…,f(m x )},m i ∈M,0≤i≤x, where This counts the frequency of each component in Ucov; 2) Then, for each component m, calculate where |Z| represents the number of all test cases, and |Z m | represents the number of all test cases containing component m; 3) According to the above IDF value, calculate the vector where Λ=diag(λ(m1),λ(m2),…,λ(m n )), n is the number of all current components, and vector t represents the eigenvalue of each component; 4) Calculate component feature distance The formula replaces the addresses in the coverage feedback sequences of the two test cases u and v with the eigenvalues of each component of the vector t, and compares the similarity of the two sequences. Since some components belonging to the USB core will appear repeatedly, the TF indicator is used to reduce their impact on the distance measurement.
9. A Linux USB driver fuzz testing system based on component weighted scheduling, characterized in that: The system has a program module corresponding to the steps of any one of claims 1 to 8, and executes the steps of the Linux USB driver fuzz testing method based on component weighted scheduling during operation.
10. A computer-readable storage medium, characterized in that: The computer-readable storage medium stores a computer program, and the computer program is configured to implement the steps of a Linux USB driver fuzz testing method based on component weighted scheduling according to any one of claims 1 to 8 when called by a processor.
Citation Information
Patent Citations
Black box fuzz testing method and system based on linear temporal logic guidance on limited trajectory
CN118193375A