1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker american fuzzy lop++ - linked list code
3*08b48e0bSAndroid Build Coastguard Worker ---------------------------------------
4*08b48e0bSAndroid Build Coastguard Worker
5*08b48e0bSAndroid Build Coastguard Worker Originally written by Michal Zalewski
6*08b48e0bSAndroid Build Coastguard Worker
7*08b48e0bSAndroid Build Coastguard Worker Now maintained by Marc Heuse <[email protected]>,
8*08b48e0bSAndroid Build Coastguard Worker Heiko Eißfeldt <[email protected]>,
9*08b48e0bSAndroid Build Coastguard Worker Andrea Fioraldi <[email protected]>,
10*08b48e0bSAndroid Build Coastguard Worker Dominik Maier <[email protected]>
11*08b48e0bSAndroid Build Coastguard Worker
12*08b48e0bSAndroid Build Coastguard Worker Copyright 2016, 2017 Google Inc. All rights reserved.
13*08b48e0bSAndroid Build Coastguard Worker Copyright 2019-2024 AFLplusplus Project. All rights reserved.
14*08b48e0bSAndroid Build Coastguard Worker
15*08b48e0bSAndroid Build Coastguard Worker Licensed under the Apache License, Version 2.0 (the "License");
16*08b48e0bSAndroid Build Coastguard Worker you may not use this file except in compliance with the License.
17*08b48e0bSAndroid Build Coastguard Worker You may obtain a copy of the License at:
18*08b48e0bSAndroid Build Coastguard Worker
19*08b48e0bSAndroid Build Coastguard Worker https://www.apache.org/licenses/LICENSE-2.0
20*08b48e0bSAndroid Build Coastguard Worker
21*08b48e0bSAndroid Build Coastguard Worker This allocator is not designed to resist malicious attackers (the canaries
22*08b48e0bSAndroid Build Coastguard Worker are small and predictable), but provides a robust and portable way to detect
23*08b48e0bSAndroid Build Coastguard Worker use-after-free, off-by-one writes, stale pointers, and so on.
24*08b48e0bSAndroid Build Coastguard Worker
25*08b48e0bSAndroid Build Coastguard Worker */
26*08b48e0bSAndroid Build Coastguard Worker
27*08b48e0bSAndroid Build Coastguard Worker #ifndef AFL_LIST
28*08b48e0bSAndroid Build Coastguard Worker #define AFL_LIST
29*08b48e0bSAndroid Build Coastguard Worker
30*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
31*08b48e0bSAndroid Build Coastguard Worker #include <stdbool.h>
32*08b48e0bSAndroid Build Coastguard Worker #include <string.h>
33*08b48e0bSAndroid Build Coastguard Worker
34*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
35*08b48e0bSAndroid Build Coastguard Worker #include "afl-prealloc.h"
36*08b48e0bSAndroid Build Coastguard Worker
37*08b48e0bSAndroid Build Coastguard Worker /* How many elements to allocate before malloc is needed */
38*08b48e0bSAndroid Build Coastguard Worker #define LIST_PREALLOC_SIZE (64)
39*08b48e0bSAndroid Build Coastguard Worker
40*08b48e0bSAndroid Build Coastguard Worker typedef struct list_element {
41*08b48e0bSAndroid Build Coastguard Worker
42*08b48e0bSAndroid Build Coastguard Worker PREALLOCABLE;
43*08b48e0bSAndroid Build Coastguard Worker
44*08b48e0bSAndroid Build Coastguard Worker struct list_element *prev;
45*08b48e0bSAndroid Build Coastguard Worker struct list_element *next;
46*08b48e0bSAndroid Build Coastguard Worker void *data;
47*08b48e0bSAndroid Build Coastguard Worker
48*08b48e0bSAndroid Build Coastguard Worker } element_t;
49*08b48e0bSAndroid Build Coastguard Worker
50*08b48e0bSAndroid Build Coastguard Worker typedef struct list {
51*08b48e0bSAndroid Build Coastguard Worker
52*08b48e0bSAndroid Build Coastguard Worker element_t element_prealloc_buf[LIST_PREALLOC_SIZE];
53*08b48e0bSAndroid Build Coastguard Worker s32 element_prealloc_count;
54*08b48e0bSAndroid Build Coastguard Worker
55*08b48e0bSAndroid Build Coastguard Worker } list_t;
56*08b48e0bSAndroid Build Coastguard Worker
get_head(list_t * list)57*08b48e0bSAndroid Build Coastguard Worker static inline element_t *get_head(list_t *list) {
58*08b48e0bSAndroid Build Coastguard Worker
59*08b48e0bSAndroid Build Coastguard Worker /* The first element is the head */
60*08b48e0bSAndroid Build Coastguard Worker return list->element_prealloc_buf;
61*08b48e0bSAndroid Build Coastguard Worker
62*08b48e0bSAndroid Build Coastguard Worker }
63*08b48e0bSAndroid Build Coastguard Worker
list_free_el(list_t * list,element_t * el)64*08b48e0bSAndroid Build Coastguard Worker static inline void list_free_el(list_t *list, element_t *el) {
65*08b48e0bSAndroid Build Coastguard Worker
66*08b48e0bSAndroid Build Coastguard Worker PRE_FREE(el, list->element_prealloc_count);
67*08b48e0bSAndroid Build Coastguard Worker
68*08b48e0bSAndroid Build Coastguard Worker }
69*08b48e0bSAndroid Build Coastguard Worker
list_append(list_t * list,void * el)70*08b48e0bSAndroid Build Coastguard Worker static inline void list_append(list_t *list, void *el) {
71*08b48e0bSAndroid Build Coastguard Worker
72*08b48e0bSAndroid Build Coastguard Worker element_t *head = get_head(list);
73*08b48e0bSAndroid Build Coastguard Worker if (!head->next) {
74*08b48e0bSAndroid Build Coastguard Worker
75*08b48e0bSAndroid Build Coastguard Worker /* initialize */
76*08b48e0bSAndroid Build Coastguard Worker
77*08b48e0bSAndroid Build Coastguard Worker memset(list, 0, sizeof(list_t));
78*08b48e0bSAndroid Build Coastguard Worker PRE_ALLOC_FORCE(head, list->element_prealloc_count);
79*08b48e0bSAndroid Build Coastguard Worker head->next = head->prev = head;
80*08b48e0bSAndroid Build Coastguard Worker
81*08b48e0bSAndroid Build Coastguard Worker }
82*08b48e0bSAndroid Build Coastguard Worker
83*08b48e0bSAndroid Build Coastguard Worker element_t *el_box = NULL;
84*08b48e0bSAndroid Build Coastguard Worker
85*08b48e0bSAndroid Build Coastguard Worker PRE_ALLOC(el_box, list->element_prealloc_buf, LIST_PREALLOC_SIZE,
86*08b48e0bSAndroid Build Coastguard Worker list->element_prealloc_count);
87*08b48e0bSAndroid Build Coastguard Worker if (!el_box) { FATAL("failed to allocate list element"); }
88*08b48e0bSAndroid Build Coastguard Worker el_box->data = el;
89*08b48e0bSAndroid Build Coastguard Worker el_box->next = head;
90*08b48e0bSAndroid Build Coastguard Worker el_box->prev = head->prev;
91*08b48e0bSAndroid Build Coastguard Worker head->prev->next = el_box;
92*08b48e0bSAndroid Build Coastguard Worker head->prev = el_box;
93*08b48e0bSAndroid Build Coastguard Worker
94*08b48e0bSAndroid Build Coastguard Worker }
95*08b48e0bSAndroid Build Coastguard Worker
96*08b48e0bSAndroid Build Coastguard Worker /* Simple foreach.
97*08b48e0bSAndroid Build Coastguard Worker Pointer to the current element is in `el`,
98*08b48e0bSAndroid Build Coastguard Worker casted to (a pointer) of the given `type`.
99*08b48e0bSAndroid Build Coastguard Worker A return from this block will return from calling func.
100*08b48e0bSAndroid Build Coastguard Worker */
101*08b48e0bSAndroid Build Coastguard Worker
102*08b48e0bSAndroid Build Coastguard Worker #define LIST_FOREACH(list, type, block) \
103*08b48e0bSAndroid Build Coastguard Worker do { \
104*08b48e0bSAndroid Build Coastguard Worker \
105*08b48e0bSAndroid Build Coastguard Worker list_t *li = (list); \
106*08b48e0bSAndroid Build Coastguard Worker element_t *head = get_head((li)); \
107*08b48e0bSAndroid Build Coastguard Worker element_t *el_box = (head)->next; \
108*08b48e0bSAndroid Build Coastguard Worker if (!el_box) FATAL("foreach over uninitialized list"); \
109*08b48e0bSAndroid Build Coastguard Worker while (el_box != head) { \
110*08b48e0bSAndroid Build Coastguard Worker \
111*08b48e0bSAndroid Build Coastguard Worker __attribute__((unused)) type *el = (type *)((el_box)->data); \
112*08b48e0bSAndroid Build Coastguard Worker /* get next so el_box can be unlinked */ \
113*08b48e0bSAndroid Build Coastguard Worker element_t *next = el_box->next; \
114*08b48e0bSAndroid Build Coastguard Worker {block}; \
115*08b48e0bSAndroid Build Coastguard Worker el_box = next; \
116*08b48e0bSAndroid Build Coastguard Worker \
117*08b48e0bSAndroid Build Coastguard Worker } \
118*08b48e0bSAndroid Build Coastguard Worker \
119*08b48e0bSAndroid Build Coastguard Worker } while (0);
120*08b48e0bSAndroid Build Coastguard Worker
121*08b48e0bSAndroid Build Coastguard Worker /* In foreach: remove the current el from the list */
122*08b48e0bSAndroid Build Coastguard Worker
123*08b48e0bSAndroid Build Coastguard Worker #define LIST_REMOVE_CURRENT_EL_IN_FOREACH() \
124*08b48e0bSAndroid Build Coastguard Worker do { \
125*08b48e0bSAndroid Build Coastguard Worker \
126*08b48e0bSAndroid Build Coastguard Worker el_box->prev->next = next; \
127*08b48e0bSAndroid Build Coastguard Worker el_box->next->prev = el_box->prev; \
128*08b48e0bSAndroid Build Coastguard Worker list_free_el(li, el_box); \
129*08b48e0bSAndroid Build Coastguard Worker \
130*08b48e0bSAndroid Build Coastguard Worker } while (0);
131*08b48e0bSAndroid Build Coastguard Worker
132*08b48e0bSAndroid Build Coastguard Worker /* Same as foreach, but will clear list in the process */
133*08b48e0bSAndroid Build Coastguard Worker
134*08b48e0bSAndroid Build Coastguard Worker #define LIST_FOREACH_CLEAR(list, type, block) \
135*08b48e0bSAndroid Build Coastguard Worker do { \
136*08b48e0bSAndroid Build Coastguard Worker \
137*08b48e0bSAndroid Build Coastguard Worker LIST_FOREACH((list), type, { \
138*08b48e0bSAndroid Build Coastguard Worker \
139*08b48e0bSAndroid Build Coastguard Worker {block}; \
140*08b48e0bSAndroid Build Coastguard Worker LIST_REMOVE_CURRENT_EL_IN_FOREACH(); \
141*08b48e0bSAndroid Build Coastguard Worker \
142*08b48e0bSAndroid Build Coastguard Worker }); \
143*08b48e0bSAndroid Build Coastguard Worker \
144*08b48e0bSAndroid Build Coastguard Worker } while (0);
145*08b48e0bSAndroid Build Coastguard Worker
146*08b48e0bSAndroid Build Coastguard Worker /* remove an item from the list */
147*08b48e0bSAndroid Build Coastguard Worker
list_remove(list_t * list,void * remove_me)148*08b48e0bSAndroid Build Coastguard Worker static inline void list_remove(list_t *list, void *remove_me) {
149*08b48e0bSAndroid Build Coastguard Worker
150*08b48e0bSAndroid Build Coastguard Worker LIST_FOREACH(list, void, {
151*08b48e0bSAndroid Build Coastguard Worker
152*08b48e0bSAndroid Build Coastguard Worker if (el == remove_me) {
153*08b48e0bSAndroid Build Coastguard Worker
154*08b48e0bSAndroid Build Coastguard Worker el_box->prev->next = el_box->next;
155*08b48e0bSAndroid Build Coastguard Worker el_box->next->prev = el_box->prev;
156*08b48e0bSAndroid Build Coastguard Worker el_box->data = NULL;
157*08b48e0bSAndroid Build Coastguard Worker list_free_el(list, el_box);
158*08b48e0bSAndroid Build Coastguard Worker return;
159*08b48e0bSAndroid Build Coastguard Worker
160*08b48e0bSAndroid Build Coastguard Worker }
161*08b48e0bSAndroid Build Coastguard Worker
162*08b48e0bSAndroid Build Coastguard Worker });
163*08b48e0bSAndroid Build Coastguard Worker
164*08b48e0bSAndroid Build Coastguard Worker FATAL("List item to be removed not in list");
165*08b48e0bSAndroid Build Coastguard Worker
166*08b48e0bSAndroid Build Coastguard Worker }
167*08b48e0bSAndroid Build Coastguard Worker
168*08b48e0bSAndroid Build Coastguard Worker /* Returns true if el is in list */
169*08b48e0bSAndroid Build Coastguard Worker
list_contains(list_t * list,void * contains_me)170*08b48e0bSAndroid Build Coastguard Worker static inline bool list_contains(list_t *list, void *contains_me) {
171*08b48e0bSAndroid Build Coastguard Worker
172*08b48e0bSAndroid Build Coastguard Worker LIST_FOREACH(list, void, {
173*08b48e0bSAndroid Build Coastguard Worker
174*08b48e0bSAndroid Build Coastguard Worker if (el == contains_me) return true;
175*08b48e0bSAndroid Build Coastguard Worker
176*08b48e0bSAndroid Build Coastguard Worker });
177*08b48e0bSAndroid Build Coastguard Worker
178*08b48e0bSAndroid Build Coastguard Worker return false;
179*08b48e0bSAndroid Build Coastguard Worker
180*08b48e0bSAndroid Build Coastguard Worker }
181*08b48e0bSAndroid Build Coastguard Worker
182*08b48e0bSAndroid Build Coastguard Worker #endif
183*08b48e0bSAndroid Build Coastguard Worker
184