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