• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    american fuzzy lop++ - debug / error handling macros
3    ----------------------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Now maintained by Marc Heuse <mh@mh-sec.de>,
8                      Heiko Eißfeldt <heiko.eissfeldt@hexco.de>,
9                      Andrea Fioraldi <andreafioraldi@gmail.com>,
10                      Dominik Maier <mail@dmnk.co>
11 
12    Copyright 2016, 2017 Google Inc. All rights reserved.
13    Copyright 2019-2022 AFLplusplus Project. All rights reserved.
14 
15    Licensed under the Apache License, Version 2.0 (the "License");
16    you may not use this file except in compliance with the License.
17    You may obtain a copy of the License at:
18 
19      https://www.apache.org/licenses/LICENSE-2.0
20 
21  */
22 
23 #ifndef _HAVE_DEBUG_H
24 #define _HAVE_DEBUG_H
25 
26 #include <errno.h>
27 
28 #include "types.h"
29 #include "config.h"
30 
31 /*******************
32  * Terminal colors *
33  *******************/
34 
35 #ifndef MESSAGES_TO_STDOUT
36   #define MESSAGES_TO_STDOUT
37 #endif
38 
39 #ifdef USE_COLOR
40 
41   #define cBLK "\x1b[0;30m"
42   #define cRED "\x1b[0;31m"
43   #define cGRN "\x1b[0;32m"
44   #define cBRN "\x1b[0;33m"
45   #define cBLU "\x1b[0;34m"
46   #define cMGN "\x1b[0;35m"
47   #define cCYA "\x1b[0;36m"
48   #define cLGR "\x1b[0;37m"
49   #define cGRA "\x1b[1;90m"
50   #define cLRD "\x1b[1;91m"
51   #define cLGN "\x1b[1;92m"
52   #define cYEL "\x1b[1;93m"
53   #define cLBL "\x1b[1;94m"
54   #define cPIN "\x1b[1;95m"
55   #define cLCY "\x1b[1;96m"
56   #define cBRI "\x1b[1;97m"
57   #define cRST "\x1b[0m"
58 
59   #define bgBLK "\x1b[40m"
60   #define bgRED "\x1b[41m"
61   #define bgGRN "\x1b[42m"
62   #define bgBRN "\x1b[43m"
63   #define bgBLU "\x1b[44m"
64   #define bgMGN "\x1b[45m"
65   #define bgCYA "\x1b[46m"
66   #define bgLGR "\x1b[47m"
67   #define bgGRA "\x1b[100m"
68   #define bgLRD "\x1b[101m"
69   #define bgLGN "\x1b[102m"
70   #define bgYEL "\x1b[103m"
71   #define bgLBL "\x1b[104m"
72   #define bgPIN "\x1b[105m"
73   #define bgLCY "\x1b[106m"
74   #define bgBRI "\x1b[107m"
75 
76 #else
77 
78   #define cBLK ""
79   #define cRED ""
80   #define cGRN ""
81   #define cBRN ""
82   #define cBLU ""
83   #define cMGN ""
84   #define cCYA ""
85   #define cLGR ""
86   #define cGRA ""
87   #define cLRD ""
88   #define cLGN ""
89   #define cYEL ""
90   #define cLBL ""
91   #define cPIN ""
92   #define cLCY ""
93   #define cBRI ""
94   #define cRST ""
95 
96   #define bgBLK ""
97   #define bgRED ""
98   #define bgGRN ""
99   #define bgBRN ""
100   #define bgBLU ""
101   #define bgMGN ""
102   #define bgCYA ""
103   #define bgLGR ""
104   #define bgGRA ""
105   #define bgLRD ""
106   #define bgLGN ""
107   #define bgYEL ""
108   #define bgLBL ""
109   #define bgPIN ""
110   #define bgLCY ""
111   #define bgBRI ""
112 
113 #endif                                                        /* ^USE_COLOR */
114 
115 /*************************
116  * Box drawing sequences *
117  *************************/
118 
119 #ifdef FANCY_BOXES
120 
121   #define SET_G1 "\x1b)0"                      /* Set G1 for box drawing    */
122   #define RESET_G1 "\x1b)B"                    /* Reset G1 to ASCII         */
123   #define bSTART "\x0e"                        /* Enter G1 drawing mode     */
124   #define bSTOP "\x0f"                         /* Leave G1 drawing mode     */
125   #define bH "q"                               /* Horizontal line           */
126   #define bV "x"                               /* Vertical line             */
127   #define bLT "l"                              /* Left top corner           */
128   #define bRT "k"                              /* Right top corner          */
129   #define bLB "m"                              /* Left bottom corner        */
130   #define bRB "j"                              /* Right bottom corner       */
131   #define bX "n"                               /* Cross                     */
132   #define bVR "t"                              /* Vertical, branch right    */
133   #define bVL "u"                              /* Vertical, branch left     */
134   #define bHT "v"                              /* Horizontal, branch top    */
135   #define bHB "w"                              /* Horizontal, branch bottom */
136 
137 #else
138 
139   #define SET_G1 ""
140   #define RESET_G1 ""
141   #define bSTART ""
142   #define bSTOP ""
143   #define bH "-"
144   #define bV "|"
145   #define bLT "+"
146   #define bRT "+"
147   #define bLB "+"
148   #define bRB "+"
149   #define bX "+"
150   #define bVR "+"
151   #define bVL "+"
152   #define bHT "+"
153   #define bHB "+"
154 
155 #endif                                                      /* ^FANCY_BOXES */
156 
157 /***********************
158  * Misc terminal codes *
159  ***********************/
160 
161 #define TERM_HOME "\x1b[H"
162 #define TERM_CLEAR TERM_HOME "\x1b[2J"
163 #define cEOL "\x1b[0K"
164 #define CURSOR_HIDE "\x1b[?25l"
165 #define CURSOR_SHOW "\x1b[?25h"
166 
167 /************************
168  * Debug & error macros *
169  ************************/
170 
171 #if defined USE_COLOR && !defined ALWAYS_COLORED
172   #include <unistd.h>
173   #pragma GCC diagnostic ignored "-Wformat-security"
colorfilter(const char * x)174 static inline const char *colorfilter(const char *x) {
175 
176   static int once = 1;
177   static int disabled = 0;
178 
179   if (once) {
180 
181     /* when there is no tty -> we always want filtering
182      * when AFL_NO_UI is set filtering depends on AFL_NO_COLOR
183      * otherwise we want always colors
184      */
185     disabled =
186         isatty(2) && (!getenv("AFL_NO_UI") ||
187                       (!getenv("AFL_NO_COLOR") && !getenv("AFL_NO_COLOUR")));
188     once = 0;
189 
190   }
191 
192   if (likely(disabled)) return x;
193 
194   static char monochromestring[4096];
195   char *      d = monochromestring;
196   int         in_seq = 0;
197 
198   while (*x) {
199 
200     if (in_seq && *x == 'm') {
201 
202       in_seq = 0;
203 
204     } else {
205 
206       if (!in_seq && *x == '\x1b') { in_seq = 1; }
207       if (!in_seq) { *d++ = *x; }
208 
209     }
210 
211     ++x;
212 
213   }
214 
215   *d = '\0';
216   return monochromestring;
217 
218 }
219 
220 #else
221   #define colorfilter(x) x                        /* no filtering necessary */
222 #endif
223 
224 /* macro magic to transform the first parameter to SAYF
225  * through colorfilter which strips coloring */
226 #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, \
227                   _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26,  \
228                   _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38,  \
229                   _39, _40, NAME, ...)                                         \
230   NAME
231 
232 #define SAYF(...)                                                           \
233   GET_MACRO(__VA_ARGS__, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N,    \
234             SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
235             SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
236             SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
237             SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
238             SAYF_N, SAYF_1)                                                 \
239   (__VA_ARGS__)
240 
241 #define SAYF_1(x) MY_SAYF(colorfilter(x))
242 #define SAYF_N(x, ...) MY_SAYF(colorfilter(x), __VA_ARGS__)
243 
244 /* Just print stuff to the appropriate stream. */
245 #ifdef MESSAGES_TO_STDOUT
246   #define MY_SAYF(x...) printf(x)
247 #else
248   #define MY_SAYF(x...) fprintf(stderr, x)
249 #endif                                               /* ^MESSAGES_TO_STDOUT */
250 
251 /* Show a prefixed warning. */
252 
253 #define WARNF(x...)                            \
254   do {                                         \
255                                                \
256     SAYF(cYEL "[!] " cBRI "WARNING: " cRST x); \
257     SAYF(cRST "\n");                           \
258                                                \
259   } while (0)
260 
261 /* Show a prefixed "doing something" message. */
262 
263 #define ACTF(x...)            \
264   do {                        \
265                               \
266     SAYF(cLBL "[*] " cRST x); \
267     SAYF(cRST "\n");          \
268                               \
269   } while (0)
270 
271 /* Show a prefixed "success" message. */
272 
273 #define OKF(x...)             \
274   do {                        \
275                               \
276     SAYF(cLGN "[+] " cRST x); \
277     SAYF(cRST "\n");          \
278                               \
279   } while (0)
280 
281 /* Show a prefixed fatal error message (not used in afl). */
282 
283 #define BADF(x...)              \
284   do {                          \
285                                 \
286     SAYF(cLRD "\n[-] " cRST x); \
287     SAYF(cRST "\n");            \
288                                 \
289   } while (0)
290 
291 /* Die with a verbose non-OS fatal error message. */
292 
293 #define FATAL(x...)                                                      \
294   do {                                                                   \
295                                                                          \
296     SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                            \
297          "\n[-] PROGRAM ABORT : " cRST   x);                               \
298     SAYF(cLRD "\n         Location : " cRST "%s(), %s:%u\n\n", __func__, \
299          __FILE__, (u32)__LINE__);                                       \
300     exit(1);                                                             \
301                                                                          \
302   } while (0)
303 
304 /* Die by calling abort() to provide a core dump. */
305 
306 #define ABORT(x...)                                                      \
307   do {                                                                   \
308                                                                          \
309     SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                            \
310          "\n[-] PROGRAM ABORT : " cRST   x);                               \
311     SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n\n", __func__, \
312          __FILE__, (u32)__LINE__);                                       \
313     abort();                                                             \
314                                                                          \
315   } while (0)
316 
317 /* Die while also including the output of perror(). */
318 
319 #define PFATAL(x...)                                                   \
320   do {                                                                 \
321                                                                        \
322     fflush(stdout);                                                    \
323     SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                          \
324          "\n[-]  SYSTEM ERROR : " cRST   x);                             \
325     SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n", __func__, \
326          __FILE__, (u32)__LINE__);                                     \
327     SAYF(cLRD "       OS message : " cRST "%s\n", strerror(errno));    \
328     exit(1);                                                           \
329                                                                        \
330   } while (0)
331 
332 /* Die with FATAL() or PFATAL() depending on the value of res (used to
333    interpret different failure modes for read(), write(), etc). */
334 
335 #define RPFATAL(res, x...) \
336   do {                     \
337                            \
338     if (res < 0)           \
339       PFATAL(x);           \
340     else                   \
341       FATAL(x);            \
342                            \
343   } while (0)
344 
345 /* Show a prefixed debug output. */
346 
347 #define DEBUGF(x...)                                    \
348   do {                                                  \
349                                                         \
350     fprintf(stderr, cMGN "[D] " cBRI "DEBUG: " cRST x); \
351     fprintf(stderr, cRST "");                           \
352                                                         \
353   } while (0)
354 
355 /* Error-checking versions of read() and write() that call RPFATAL() as
356    appropriate. */
357 
358 #define ck_write(fd, buf, len, fn)                                            \
359   do {                                                                        \
360                                                                               \
361     if (len <= 0) break;                                                      \
362     int _fd = (fd);                                                           \
363     s32 _written = 0, _off = 0, _len = (s32)(len);                            \
364                                                                               \
365     do {                                                                      \
366                                                                               \
367       s32 _res = write(_fd, (buf) + _off, _len);                              \
368       if (_res != _len && (_res > 0 && _written + _res != _len)) {            \
369                                                                               \
370         if (_res > 0) {                                                       \
371                                                                               \
372           _written += _res;                                                   \
373           _len -= _res;                                                       \
374           _off += _res;                                                       \
375                                                                               \
376         } else {                                                              \
377                                                                               \
378           RPFATAL(_res, "Short write to %s, fd %d (%d of %d bytes)", fn, _fd, \
379                   _res, _len);                                                \
380                                                                               \
381         }                                                                     \
382                                                                               \
383       } else {                                                                \
384                                                                               \
385         break;                                                                \
386                                                                               \
387       }                                                                       \
388                                                                               \
389     } while (1);                                                              \
390                                                                               \
391                                                                               \
392                                                                               \
393   } while (0)
394 
395 #define ck_read(fd, buf, len, fn)                              \
396   do {                                                         \
397                                                                \
398     s32 _len = (s32)(len);                                     \
399     s32 _res = read(fd, buf, _len);                            \
400     if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \
401                                                                \
402   } while (0)
403 
404 #endif                                                   /* ! _HAVE_DEBUG_H */
405 
406