etc.git


etc

~ scripts and random things
git clone https://github.com/djnnvx/etc.git
log | files | refs | archive

fuzz_devlist.c (2394B)

      1 /*
      2  * fuzz_devlist.c — USB/IP device-list reply parsing harness.
      3  *
      4  * Exercises the devlist reply path:
      5  *   [ndev:4 BE] + ndev × (usbip_usb_device + bNumInterfaces × usbip_usb_interface)
      6  *
      7  * Bug classes: large ndev overflow, malformed device structs, integer overflow
      8  * in ndev × sizeof(usbip_usb_device), bNumInterfaces out of bounds.
      9  */
     10 
     11 #include "fuzz-include/usbip_fuzz.h"
     12 #include "usbip-src/libsrc/usbip_common.h"
     13 #include "usbip-src/src/usbip_network.h"
     14 
     15 #include <stdint.h>
     16 #include <stdlib.h>
     17 #include <string.h>
     18 #include <arpa/inet.h>
     19 
     20 #define FAKE_FD       42
     21 #define MAX_NDEV_FUZZ 64
     22 
     23 static int fuzz_one(const uint8_t *data, size_t size)
     24 {
     25     if (size < sizeof(struct op_devlist_reply))
     26         return 0;
     27 
     28     uint8_t buf[FUZZ_BUF_MAX];
     29     size_t n = size < FUZZ_BUF_MAX ? size : FUZZ_BUF_MAX;
     30     memcpy(buf, data, n);
     31 
     32     /* Clamp ndev so we don't OOM the fuzzer on a 2^32-device list */
     33     uint32_t ndev_be;
     34     memcpy(&ndev_be, buf, 4);
     35     uint32_t ndev = ntohl(ndev_be);
     36     if (ndev > MAX_NDEV_FUZZ) {
     37         ndev = MAX_NDEV_FUZZ;
     38         uint32_t clamped = htonl(ndev);
     39         memcpy(buf, &clamped, 4);
     40     }
     41 
     42     fuzz_reset(buf, n);
     43 
     44     struct op_devlist_reply reply;
     45     memset(&reply, 0, sizeof(reply));
     46     if (usbip_net_recv(FAKE_FD, &reply, sizeof(reply)) < 0)
     47         return 0;
     48     PACK_OP_DEVLIST_REPLY(0, &reply);
     49 
     50     uint32_t num = reply.ndev;
     51     if (num > MAX_NDEV_FUZZ) num = MAX_NDEV_FUZZ;
     52 
     53     for (uint32_t i = 0; i < num; i++) {
     54         struct usbip_usb_device udev;
     55         memset(&udev, 0, sizeof(udev));
     56         if (usbip_net_recv(FAKE_FD, &udev, sizeof(udev)) < 0)
     57             return 0;
     58         usbip_net_pack_usb_device(0, &udev);
     59 
     60         uint8_t nif = udev.bNumInterfaces;
     61         for (uint8_t j = 0; j < nif; j++) {
     62             struct usbip_usb_interface uinf;
     63             memset(&uinf, 0, sizeof(uinf));
     64             if (usbip_net_recv(FAKE_FD, &uinf, sizeof(uinf)) < 0)
     65                 return 0;
     66             usbip_net_pack_usb_interface(0, &uinf);
     67         }
     68     }
     69 
     70     return 0;
     71 }
     72 
     73 #ifdef __AFL_FUZZ_TESTCASE_LEN
     74 __AFL_FUZZ_INIT();
     75 
     76 int main(void)
     77 {
     78     __AFL_INIT();
     79     uint8_t *buf = __AFL_FUZZ_TESTCASE_BUF;
     80     while (__AFL_LOOP(10000)) {
     81         fuzz_one(buf, __AFL_FUZZ_TESTCASE_LEN);
     82     }
     83     return 0;
     84 }
     85 
     86 #else
     87 
     88 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
     89 {
     90     return fuzz_one(data, size);
     91 }
     92 
     93 #endif