xref: /aosp_15_r20/external/AFLplusplus/utils/afl_proxy/afl-proxy.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker    american fuzzy lop++ - afl-proxy skeleton example
3*08b48e0bSAndroid Build Coastguard Worker    ---------------------------------------------------
4*08b48e0bSAndroid Build Coastguard Worker 
5*08b48e0bSAndroid Build Coastguard Worker    Written by Marc Heuse <[email protected]>
6*08b48e0bSAndroid Build Coastguard Worker 
7*08b48e0bSAndroid Build Coastguard Worker    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
8*08b48e0bSAndroid Build Coastguard Worker 
9*08b48e0bSAndroid Build Coastguard Worker    Licensed under the Apache License, Version 2.0 (the "License");
10*08b48e0bSAndroid Build Coastguard Worker    you may not use this file except in compliance with the License.
11*08b48e0bSAndroid Build Coastguard Worker    You may obtain a copy of the License at:
12*08b48e0bSAndroid Build Coastguard Worker 
13*08b48e0bSAndroid Build Coastguard Worker    http://www.apache.org/licenses/LICENSE-2.0
14*08b48e0bSAndroid Build Coastguard Worker 
15*08b48e0bSAndroid Build Coastguard Worker 
16*08b48e0bSAndroid Build Coastguard Worker    HOW-TO
17*08b48e0bSAndroid Build Coastguard Worker    ======
18*08b48e0bSAndroid Build Coastguard Worker 
19*08b48e0bSAndroid Build Coastguard Worker    You only need to change the while() loop of the main() to send the
20*08b48e0bSAndroid Build Coastguard Worker    data of buf[] with length len to the target and write the coverage
21*08b48e0bSAndroid Build Coastguard Worker    information to __afl_area_ptr[__afl_map_size]
22*08b48e0bSAndroid Build Coastguard Worker 
23*08b48e0bSAndroid Build Coastguard Worker 
24*08b48e0bSAndroid Build Coastguard Worker */
25*08b48e0bSAndroid Build Coastguard Worker 
26*08b48e0bSAndroid Build Coastguard Worker #ifdef __ANDROID__
27*08b48e0bSAndroid Build Coastguard Worker   #include "android-ashmem.h"
28*08b48e0bSAndroid Build Coastguard Worker #endif
29*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
30*08b48e0bSAndroid Build Coastguard Worker #include "types.h"
31*08b48e0bSAndroid Build Coastguard Worker 
32*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
33*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
34*08b48e0bSAndroid Build Coastguard Worker #include <signal.h>
35*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
36*08b48e0bSAndroid Build Coastguard Worker #include <string.h>
37*08b48e0bSAndroid Build Coastguard Worker #include <assert.h>
38*08b48e0bSAndroid Build Coastguard Worker #include <stdint.h>
39*08b48e0bSAndroid Build Coastguard Worker #include <errno.h>
40*08b48e0bSAndroid Build Coastguard Worker 
41*08b48e0bSAndroid Build Coastguard Worker #include <sys/mman.h>
42*08b48e0bSAndroid Build Coastguard Worker #include <sys/shm.h>
43*08b48e0bSAndroid Build Coastguard Worker #include <sys/wait.h>
44*08b48e0bSAndroid Build Coastguard Worker #include <sys/types.h>
45*08b48e0bSAndroid Build Coastguard Worker #include <fcntl.h>
46*08b48e0bSAndroid Build Coastguard Worker 
47*08b48e0bSAndroid Build Coastguard Worker u8 *__afl_area_ptr;
48*08b48e0bSAndroid Build Coastguard Worker 
49*08b48e0bSAndroid Build Coastguard Worker #ifdef __ANDROID__
50*08b48e0bSAndroid Build Coastguard Worker u32 __afl_map_size = MAP_SIZE;
51*08b48e0bSAndroid Build Coastguard Worker #else
52*08b48e0bSAndroid Build Coastguard Worker __thread u32 __afl_map_size = MAP_SIZE;
53*08b48e0bSAndroid Build Coastguard Worker #endif
54*08b48e0bSAndroid Build Coastguard Worker 
55*08b48e0bSAndroid Build Coastguard Worker /* Error reporting to forkserver controller */
56*08b48e0bSAndroid Build Coastguard Worker 
send_forkserver_error(int error)57*08b48e0bSAndroid Build Coastguard Worker void send_forkserver_error(int error) {
58*08b48e0bSAndroid Build Coastguard Worker 
59*08b48e0bSAndroid Build Coastguard Worker   u32 status;
60*08b48e0bSAndroid Build Coastguard Worker   if (!error || error > 0xffff) return;
61*08b48e0bSAndroid Build Coastguard Worker   status = (FS_OPT_ERROR | FS_OPT_SET_ERROR(error));
62*08b48e0bSAndroid Build Coastguard Worker   if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) return;
63*08b48e0bSAndroid Build Coastguard Worker 
64*08b48e0bSAndroid Build Coastguard Worker }
65*08b48e0bSAndroid Build Coastguard Worker 
66*08b48e0bSAndroid Build Coastguard Worker /* SHM setup. */
67*08b48e0bSAndroid Build Coastguard Worker 
__afl_map_shm(void)68*08b48e0bSAndroid Build Coastguard Worker static void __afl_map_shm(void) {
69*08b48e0bSAndroid Build Coastguard Worker 
70*08b48e0bSAndroid Build Coastguard Worker   char *id_str = getenv(SHM_ENV_VAR);
71*08b48e0bSAndroid Build Coastguard Worker   char *ptr;
72*08b48e0bSAndroid Build Coastguard Worker 
73*08b48e0bSAndroid Build Coastguard Worker   /* NOTE TODO BUG FIXME: if you want to supply a variable sized map then
74*08b48e0bSAndroid Build Coastguard Worker      uncomment the following: */
75*08b48e0bSAndroid Build Coastguard Worker 
76*08b48e0bSAndroid Build Coastguard Worker   /*
77*08b48e0bSAndroid Build Coastguard Worker   if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) {
78*08b48e0bSAndroid Build Coastguard Worker 
79*08b48e0bSAndroid Build Coastguard Worker     u32 val = atoi(ptr);
80*08b48e0bSAndroid Build Coastguard Worker     if (val > 0) __afl_map_size = val;
81*08b48e0bSAndroid Build Coastguard Worker 
82*08b48e0bSAndroid Build Coastguard Worker   }
83*08b48e0bSAndroid Build Coastguard Worker 
84*08b48e0bSAndroid Build Coastguard Worker   */
85*08b48e0bSAndroid Build Coastguard Worker 
86*08b48e0bSAndroid Build Coastguard Worker   if (__afl_map_size > MAP_SIZE) {
87*08b48e0bSAndroid Build Coastguard Worker 
88*08b48e0bSAndroid Build Coastguard Worker     if (__afl_map_size > FS_OPT_MAX_MAPSIZE) {
89*08b48e0bSAndroid Build Coastguard Worker 
90*08b48e0bSAndroid Build Coastguard Worker       fprintf(stderr,
91*08b48e0bSAndroid Build Coastguard Worker               "Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u to "
92*08b48e0bSAndroid Build Coastguard Worker               "be able to run this instrumented program!\n",
93*08b48e0bSAndroid Build Coastguard Worker               __afl_map_size);
94*08b48e0bSAndroid Build Coastguard Worker       if (id_str) {
95*08b48e0bSAndroid Build Coastguard Worker 
96*08b48e0bSAndroid Build Coastguard Worker         send_forkserver_error(FS_ERROR_MAP_SIZE);
97*08b48e0bSAndroid Build Coastguard Worker         exit(-1);
98*08b48e0bSAndroid Build Coastguard Worker 
99*08b48e0bSAndroid Build Coastguard Worker       }
100*08b48e0bSAndroid Build Coastguard Worker 
101*08b48e0bSAndroid Build Coastguard Worker     } else {
102*08b48e0bSAndroid Build Coastguard Worker 
103*08b48e0bSAndroid Build Coastguard Worker       fprintf(stderr,
104*08b48e0bSAndroid Build Coastguard Worker               "Warning: AFL++ tools will need to set AFL_MAP_SIZE to %u to "
105*08b48e0bSAndroid Build Coastguard Worker               "be able to run this instrumented program!\n",
106*08b48e0bSAndroid Build Coastguard Worker               __afl_map_size);
107*08b48e0bSAndroid Build Coastguard Worker 
108*08b48e0bSAndroid Build Coastguard Worker     }
109*08b48e0bSAndroid Build Coastguard Worker 
110*08b48e0bSAndroid Build Coastguard Worker   }
111*08b48e0bSAndroid Build Coastguard Worker 
112*08b48e0bSAndroid Build Coastguard Worker   if (id_str) {
113*08b48e0bSAndroid Build Coastguard Worker 
114*08b48e0bSAndroid Build Coastguard Worker #ifdef USEMMAP
115*08b48e0bSAndroid Build Coastguard Worker     const char    *shm_file_path = id_str;
116*08b48e0bSAndroid Build Coastguard Worker     int            shm_fd = -1;
117*08b48e0bSAndroid Build Coastguard Worker     unsigned char *shm_base = NULL;
118*08b48e0bSAndroid Build Coastguard Worker 
119*08b48e0bSAndroid Build Coastguard Worker     /* create the shared memory segment as if it was a file */
120*08b48e0bSAndroid Build Coastguard Worker     shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
121*08b48e0bSAndroid Build Coastguard Worker     if (shm_fd == -1) {
122*08b48e0bSAndroid Build Coastguard Worker 
123*08b48e0bSAndroid Build Coastguard Worker       fprintf(stderr, "shm_open() failed\n");
124*08b48e0bSAndroid Build Coastguard Worker       send_forkserver_error(FS_ERROR_SHM_OPEN);
125*08b48e0bSAndroid Build Coastguard Worker       exit(1);
126*08b48e0bSAndroid Build Coastguard Worker 
127*08b48e0bSAndroid Build Coastguard Worker     }
128*08b48e0bSAndroid Build Coastguard Worker 
129*08b48e0bSAndroid Build Coastguard Worker     /* map the shared memory segment to the address space of the process */
130*08b48e0bSAndroid Build Coastguard Worker     shm_base =
131*08b48e0bSAndroid Build Coastguard Worker         mmap(0, __afl_map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
132*08b48e0bSAndroid Build Coastguard Worker 
133*08b48e0bSAndroid Build Coastguard Worker     if (shm_base == MAP_FAILED) {
134*08b48e0bSAndroid Build Coastguard Worker 
135*08b48e0bSAndroid Build Coastguard Worker       close(shm_fd);
136*08b48e0bSAndroid Build Coastguard Worker       shm_fd = -1;
137*08b48e0bSAndroid Build Coastguard Worker 
138*08b48e0bSAndroid Build Coastguard Worker       fprintf(stderr, "mmap() failed\n");
139*08b48e0bSAndroid Build Coastguard Worker       send_forkserver_error(FS_ERROR_MMAP);
140*08b48e0bSAndroid Build Coastguard Worker       exit(2);
141*08b48e0bSAndroid Build Coastguard Worker 
142*08b48e0bSAndroid Build Coastguard Worker     }
143*08b48e0bSAndroid Build Coastguard Worker 
144*08b48e0bSAndroid Build Coastguard Worker     __afl_area_ptr = shm_base;
145*08b48e0bSAndroid Build Coastguard Worker #else
146*08b48e0bSAndroid Build Coastguard Worker     u32 shm_id = atoi(id_str);
147*08b48e0bSAndroid Build Coastguard Worker 
148*08b48e0bSAndroid Build Coastguard Worker     __afl_area_ptr = shmat(shm_id, 0, 0);
149*08b48e0bSAndroid Build Coastguard Worker 
150*08b48e0bSAndroid Build Coastguard Worker #endif
151*08b48e0bSAndroid Build Coastguard Worker 
152*08b48e0bSAndroid Build Coastguard Worker     if (__afl_area_ptr == (void *)-1) {
153*08b48e0bSAndroid Build Coastguard Worker 
154*08b48e0bSAndroid Build Coastguard Worker       send_forkserver_error(FS_ERROR_SHMAT);
155*08b48e0bSAndroid Build Coastguard Worker       exit(1);
156*08b48e0bSAndroid Build Coastguard Worker 
157*08b48e0bSAndroid Build Coastguard Worker     }
158*08b48e0bSAndroid Build Coastguard Worker 
159*08b48e0bSAndroid Build Coastguard Worker     /* Write something into the bitmap so that the parent doesn't give up */
160*08b48e0bSAndroid Build Coastguard Worker 
161*08b48e0bSAndroid Build Coastguard Worker     __afl_area_ptr[0] = 1;
162*08b48e0bSAndroid Build Coastguard Worker 
163*08b48e0bSAndroid Build Coastguard Worker   }
164*08b48e0bSAndroid Build Coastguard Worker 
165*08b48e0bSAndroid Build Coastguard Worker }
166*08b48e0bSAndroid Build Coastguard Worker 
167*08b48e0bSAndroid Build Coastguard Worker /* Fork server logic. */
168*08b48e0bSAndroid Build Coastguard Worker 
__afl_start_forkserver(void)169*08b48e0bSAndroid Build Coastguard Worker static void __afl_start_forkserver(void) {
170*08b48e0bSAndroid Build Coastguard Worker 
171*08b48e0bSAndroid Build Coastguard Worker   u8  tmp[4] = {0, 0, 0, 0};
172*08b48e0bSAndroid Build Coastguard Worker   u32 status = 0;
173*08b48e0bSAndroid Build Coastguard Worker 
174*08b48e0bSAndroid Build Coastguard Worker   if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
175*08b48e0bSAndroid Build Coastguard Worker     status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
176*08b48e0bSAndroid Build Coastguard Worker   if (status) status |= (FS_OPT_ENABLED);
177*08b48e0bSAndroid Build Coastguard Worker   memcpy(tmp, &status, 4);
178*08b48e0bSAndroid Build Coastguard Worker 
179*08b48e0bSAndroid Build Coastguard Worker   /* Phone home and tell the parent that we're OK. */
180*08b48e0bSAndroid Build Coastguard Worker 
181*08b48e0bSAndroid Build Coastguard Worker   if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
182*08b48e0bSAndroid Build Coastguard Worker 
183*08b48e0bSAndroid Build Coastguard Worker }
184*08b48e0bSAndroid Build Coastguard Worker 
__afl_next_testcase(u8 * buf,u32 max_len)185*08b48e0bSAndroid Build Coastguard Worker static u32 __afl_next_testcase(u8 *buf, u32 max_len) {
186*08b48e0bSAndroid Build Coastguard Worker 
187*08b48e0bSAndroid Build Coastguard Worker   s32 status, res = 0xffffff;
188*08b48e0bSAndroid Build Coastguard Worker 
189*08b48e0bSAndroid Build Coastguard Worker   /* Wait for parent by reading from the pipe. Abort if read fails. */
190*08b48e0bSAndroid Build Coastguard Worker   if (read(FORKSRV_FD, &status, 4) != 4) return 0;
191*08b48e0bSAndroid Build Coastguard Worker 
192*08b48e0bSAndroid Build Coastguard Worker   /* we have a testcase - read it */
193*08b48e0bSAndroid Build Coastguard Worker   status = read(0, buf, max_len);
194*08b48e0bSAndroid Build Coastguard Worker 
195*08b48e0bSAndroid Build Coastguard Worker   /* report that we are starting the target */
196*08b48e0bSAndroid Build Coastguard Worker   if (write(FORKSRV_FD + 1, &res, 4) != 4) return 0;
197*08b48e0bSAndroid Build Coastguard Worker 
198*08b48e0bSAndroid Build Coastguard Worker   return status;
199*08b48e0bSAndroid Build Coastguard Worker 
200*08b48e0bSAndroid Build Coastguard Worker }
201*08b48e0bSAndroid Build Coastguard Worker 
__afl_end_testcase(void)202*08b48e0bSAndroid Build Coastguard Worker static void __afl_end_testcase(void) {
203*08b48e0bSAndroid Build Coastguard Worker 
204*08b48e0bSAndroid Build Coastguard Worker   int status = 0xffffff;
205*08b48e0bSAndroid Build Coastguard Worker 
206*08b48e0bSAndroid Build Coastguard Worker   if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(1);
207*08b48e0bSAndroid Build Coastguard Worker 
208*08b48e0bSAndroid Build Coastguard Worker }
209*08b48e0bSAndroid Build Coastguard Worker 
210*08b48e0bSAndroid Build Coastguard Worker /* you just need to modify the while() loop in this main() */
211*08b48e0bSAndroid Build Coastguard Worker 
main(int argc,char * argv[])212*08b48e0bSAndroid Build Coastguard Worker int main(int argc, char *argv[]) {
213*08b48e0bSAndroid Build Coastguard Worker 
214*08b48e0bSAndroid Build Coastguard Worker   /* This is were the testcase data is written into */
215*08b48e0bSAndroid Build Coastguard Worker   u8  buf[1024];  // this is the maximum size for a test case! set it!
216*08b48e0bSAndroid Build Coastguard Worker   s32 len;
217*08b48e0bSAndroid Build Coastguard Worker 
218*08b48e0bSAndroid Build Coastguard Worker   /* here you specify the map size you need that you are reporting to
219*08b48e0bSAndroid Build Coastguard Worker      afl-fuzz.  Any value is fine as long as it can be divided by 32. */
220*08b48e0bSAndroid Build Coastguard Worker   __afl_map_size = MAP_SIZE;  // default is 65536
221*08b48e0bSAndroid Build Coastguard Worker 
222*08b48e0bSAndroid Build Coastguard Worker   /* then we initialize the shared memory map and start the forkserver */
223*08b48e0bSAndroid Build Coastguard Worker   __afl_map_shm();
224*08b48e0bSAndroid Build Coastguard Worker   __afl_start_forkserver();
225*08b48e0bSAndroid Build Coastguard Worker 
226*08b48e0bSAndroid Build Coastguard Worker   while ((len = __afl_next_testcase(buf, sizeof(buf))) > 0) {
227*08b48e0bSAndroid Build Coastguard Worker 
228*08b48e0bSAndroid Build Coastguard Worker     if (len > 4) {  // the minimum data size you need for the target
229*08b48e0bSAndroid Build Coastguard Worker 
230*08b48e0bSAndroid Build Coastguard Worker       /* here you have to create the magic that feeds the buf/len to the
231*08b48e0bSAndroid Build Coastguard Worker          target and write the coverage to __afl_area_ptr */
232*08b48e0bSAndroid Build Coastguard Worker 
233*08b48e0bSAndroid Build Coastguard Worker       // ... the magic ...
234*08b48e0bSAndroid Build Coastguard Worker 
235*08b48e0bSAndroid Build Coastguard Worker       // remove this, this is just to make afl-fuzz not complain when run
236*08b48e0bSAndroid Build Coastguard Worker       if (buf[0] == 0xff)
237*08b48e0bSAndroid Build Coastguard Worker         __afl_area_ptr[1] = 1;
238*08b48e0bSAndroid Build Coastguard Worker       else
239*08b48e0bSAndroid Build Coastguard Worker         __afl_area_ptr[2] = 2;
240*08b48e0bSAndroid Build Coastguard Worker 
241*08b48e0bSAndroid Build Coastguard Worker     }
242*08b48e0bSAndroid Build Coastguard Worker 
243*08b48e0bSAndroid Build Coastguard Worker     /* report the test case is done and wait for the next */
244*08b48e0bSAndroid Build Coastguard Worker     __afl_end_testcase();
245*08b48e0bSAndroid Build Coastguard Worker 
246*08b48e0bSAndroid Build Coastguard Worker   }
247*08b48e0bSAndroid Build Coastguard Worker 
248*08b48e0bSAndroid Build Coastguard Worker   return 0;
249*08b48e0bSAndroid Build Coastguard Worker 
250*08b48e0bSAndroid Build Coastguard Worker }
251*08b48e0bSAndroid Build Coastguard Worker 
252