|
2 | 2 |
|
3 | 3 | ## Overview |
4 | 4 |
|
5 | | -This fuzzer tests the generic linked list library (`lib_c_list`) for memory safety issues, edge cases, and potential crashes. It exercises all list operations including insertion, removal, sorting, and traversal. |
| 5 | +This fuzzer tests the generic linked list library (`lib_c_list`) for memory safety issues, edge cases, and potential crashes. It exercises both **forward lists** (`c_flist_*`) and **doubly-linked lists** (`c_dlist_*`) with all available operations including insertion, removal, sorting, reversing, and traversal. |
| 6 | + |
| 7 | +## List Type Selection |
| 8 | + |
| 9 | +The **first byte** determines which type of list to test: |
| 10 | + |
| 11 | +- **Bit 7 = 0**: Forward list (singly-linked) |
| 12 | +- **Bit 7 = 1**: Doubly-linked list |
| 13 | + |
| 14 | +This allows the fuzzer to test both implementations independently within a single harness. |
6 | 15 |
|
7 | 16 | ## Operations Tested |
8 | 17 |
|
| 18 | +### Forward List Operations (c_flist_*) |
| 19 | + |
9 | 20 | The fuzzer uses the lower 4 bits of each input byte to select operations: |
10 | 21 |
|
11 | 22 | | Op Code | Operation | Description | |
12 | 23 | |---------|-------------------|------------------------------------------------| |
13 | | -| 0x00 | `push_front` | Add node at the beginning | |
14 | | -| 0x01 | `push_back` | Add node at the end | |
15 | | -| 0x02 | `pop_front` | Remove first node | |
16 | | -| 0x03 | `pop_back` | Remove last node | |
17 | | -| 0x04 | `insert_after` | Insert node after reference node | |
18 | | -| 0x05 | `insert_before` | Insert node before reference node | |
19 | | -| 0x06 | `remove` | Remove specific node | |
20 | | -| 0x07 | `clear` | Remove all nodes | |
21 | | -| 0x08 | `sort` | Sort list by node ID | |
22 | | -| 0x09 | `size` | Get list size | |
23 | | -| 0x0A | `traverse` | Traverse and verify integrity (cycle detection)| |
| 24 | +| 0x00 | `push_front` | Add node at the beginning (O(1)) | |
| 25 | +| 0x01 | `push_back` | Add node at the end (O(n)) | |
| 26 | +| 0x02 | `pop_front` | Remove first node (O(1)) | |
| 27 | +| 0x03 | `pop_back` | Remove last node (O(n)) | |
| 28 | +| 0x04 | `insert_after` | Insert node after reference node (O(1)) | |
| 29 | +| 0x05 | `remove` | Remove specific node (O(n)) | |
| 30 | +| 0x06 | `clear` | Remove all nodes (O(n)) | |
| 31 | +| 0x07 | `sort` | Sort list by node ID (O(n²)) | |
| 32 | +| 0x08 | `size` | Get list size (O(n)) | |
| 33 | +| 0x09 | `reverse` | Reverse list order (O(n)) | |
| 34 | +| 0x0A | `empty` | Check if list is empty (O(1)) | |
| 35 | + |
| 36 | +### Doubly-Linked List Operations (c_dlist_*) |
| 37 | + |
| 38 | +| Op Code | Operation | Description | |
| 39 | +|---------|-------------------|------------------------------------------------| |
| 40 | +| 0x00 | `push_front` | Add node at the beginning (O(1)) | |
| 41 | +| 0x01 | `push_back` | Add node at the end (O(1) ⚡) | |
| 42 | +| 0x02 | `pop_front` | Remove first node (O(1) ⚡) | |
| 43 | +| 0x03 | `pop_back` | Remove last node (O(1) ⚡) | |
| 44 | +| 0x04 | `insert_after` | Insert node after reference (O(1)) | |
| 45 | +| 0x05 | `insert_before` | Insert node before reference (O(1) ⚡) | |
| 46 | +| 0x06 | `remove` | Remove specific node (O(1) ⚡) | |
| 47 | +| 0x07 | `clear` | Remove all nodes (O(n)) | |
| 48 | +| 0x08 | `sort` | Sort list by node ID (O(n²)) | |
| 49 | +| 0x09 | `size` | Get list size (O(n)) | |
| 50 | +| 0x0A | `reverse` | Reverse list order (O(n)) | |
| 51 | +| 0x0B | `empty` | Check if list is empty (O(1)) | |
24 | 52 |
|
25 | 53 | ## Features |
26 | 54 |
|
| 55 | +### Dual List Testing |
| 56 | + |
| 57 | +The fuzzer tests both list implementations: |
| 58 | + |
| 59 | +- **Forward Lists** (`c_flist_node_t`): Singly-linked, minimal memory overhead |
| 60 | +- **Doubly-Linked Lists** (`c_dlist_node_t`): Bidirectional traversal, O(1) operations |
| 61 | + |
27 | 62 | ### Safety Checks |
28 | 63 |
|
29 | | -- **Cycle detection**: Prevents infinite loops in traversal |
| 64 | +- **Type safety**: Separate tracking for forward and doubly-linked nodes |
30 | 65 | - **Node tracking**: All allocated nodes are tracked for cleanup |
31 | 66 | - **Memory leak prevention**: Automatic cleanup at end of fuzzing iteration |
32 | | -- **Integrity verification**: Validates list structure during traversal |
| 67 | +- **Size limits**: Prevents excessive memory usage |
33 | 68 |
|
34 | 69 | ### Test Data |
35 | 70 |
|
36 | 71 | Each node contains: |
37 | 72 |
|
38 | 73 | - Unique ID (auto-incremented) |
39 | 74 | - 16 bytes of fuzzer-provided data |
40 | | -- Standard list node structure |
| 75 | +- Standard list node structure (with or without prev pointer) |
41 | 76 |
|
42 | 77 | ### Limits |
43 | 78 |
|
44 | 79 | - `MAX_NODES`: 1000 (prevents excessive memory usage) |
45 | 80 | - `MAX_TRACKERS`: 100 (limits number of tracked nodes) |
46 | | -- Maximum input length: 256 bytes (configurable) |
| 81 | +- Minimum input length: 2 bytes (1 for type selection, 1+ for operations) |
47 | 82 |
|
48 | 83 | ## Building |
49 | 84 |
|
@@ -97,9 +132,45 @@ fuzzing/harness/fuzz_c_list/ |
97 | 132 |
|
98 | 133 | Example corpus files: |
99 | 134 |
|
100 | | -- Simple operations: `\x00\x00...` (push_front operations) |
101 | | -- Mixed operations: `\x00...\x01...\x02` (push_front, push_back, pop_front) |
102 | | -- Complex sequences: Various operation combinations |
| 135 | +**Forward list operations** (first byte < 0x80): |
| 136 | + |
| 137 | +```bash |
| 138 | +# Simple forward list operations |
| 139 | +00 00 <16 bytes> # push_front |
| 140 | +00 01 <16 bytes> # push_back |
| 141 | +00 02 # pop_front |
| 142 | + |
| 143 | +# Complex forward list sequence |
| 144 | +00 00 <16 bytes> 01 <16 bytes> 07 09 # push_front, push_back, sort, reverse |
| 145 | +``` |
| 146 | + |
| 147 | +**Doubly-linked list operations** (first byte >= 0x80): |
| 148 | + |
| 149 | +```bash |
| 150 | +# Simple doubly-linked operations |
| 151 | +80 00 <16 bytes> # push_front |
| 152 | +80 01 <16 bytes> # push_back (O(1) - fast!) |
| 153 | +80 05 00 <16 bytes> # insert_before (unique to doubly-linked) |
| 154 | + |
| 155 | +# Complex doubly-linked sequence |
| 156 | +80 00 <16 bytes> 01 <16 bytes> 08 0A # push_front, push_back, sort, reverse |
| 157 | +``` |
| 158 | + |
| 159 | +## Input Format |
| 160 | + |
| 161 | +```bash |
| 162 | +Byte 0: [1 bit: list type] [7 bits: unused] |
| 163 | + - Bit 7 = 0: Forward list |
| 164 | + - Bit 7 = 1: Doubly-linked list |
| 165 | + |
| 166 | +Byte 1+: [Operation code] [Optional parameters] |
| 167 | + - Lower 4 bits: operation type (0x00-0x0F) |
| 168 | + - Upper 4 bits: unused |
| 169 | + |
| 170 | +Parameters: |
| 171 | +- Node creation: 16 bytes of data |
| 172 | +- Node reference: 1 byte index (for insert/remove operations) |
| 173 | +``` |
103 | 174 |
|
104 | 175 | ## Debugging |
105 | 176 |
|
|
0 commit comments