add AFL_TARGET_ENV to afl-fuzz
MODIFY
README.md
README.md
@@ -1178,6 +1178,7 @@ without feedback, bug reports, or patches from:
Josephine Calliotte Konrad Welc
Thomas Rooijakkers David Carlier
Ruben ten Hove Joey Jiao
+ fuzzah
```
Thank you!

MODIFY
docs/Changelog.md
docs/Changelog.md
@@ -9,6 +9,9 @@ Want to stay in the loop on major new features? Join our mailing list by
sending a mail to <afl-users+subscribe@googlegroups.com>.
### Version ++3.12a (dev)
+ - afl-fuzz:
+ - added AFL_TARGET_ENV variable to pass extra env vars to the target
+ (for things like LD_LIBRARY_PATH)
- afl-cc:
- fix cmplog rtn (rare crash and not being able to gather ptr data)
- link runtime not to shared libs

MODIFY
docs/env_variables.md
docs/env_variables.md
@@ -408,6 +408,12 @@ checks or alter some of the more exotic semantics of the tool:
without disrupting the afl-fuzz process itself. This is useful, among other
things, for bootstrapping libdislocator.so.
+ - Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables
+ for the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz ... `
+ This exists mostly for things like `LD_LIBRARY_PATH` but it would theoretically
+ allow fuzzing of AFL++ itself (with 'target' AFL++ using some AFL_ vars that
+ would disrupt work of 'fuzzer' AFL++).
+
- Setting `AFL_NO_UI` inhibits the UI altogether, and just periodically prints
some basic stats. This behavior is also automatically triggered when the
output from afl-fuzz is redirected to a file or to a pipe.

MODIFY
include/common.h
include/common.h
@@ -49,6 +49,10 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char * get_afl_env(char *env);
+/* Extract env vars from input string and set them using setenv()
+ For use with AFL_TARGET_ENV, ... */
+u8 extract_and_set_env(u8 *env_str);
+
extern u8 be_quiet;
extern u8 *doc_path; /* path to documentation dir */

MODIFY
include/envs.h
include/envs.h
@@ -130,6 +130,7 @@ static char *afl_environment_variables[] = {
"AFL_PATH",
"AFL_PERFORMANCE_FILE",
"AFL_PRELOAD",
+ "AFL_TARGET_ENV",
"AFL_PYTHON_MODULE",
"AFL_QEMU_CUSTOM_BIN",
"AFL_QEMU_COMPCOV",

MODIFY
src/afl-common.c
src/afl-common.c
@@ -706,6 +706,102 @@ char *get_afl_env(char *env) {
}
+u8 extract_and_set_env(u8 *env_str) {
+
+ if (!env_str) { return 0; }
+
+ u8 *p = ck_strdup(env_str);
+
+ u8 *end = p + strlen((char *)p);
+
+ u8 ret_val = 0; // return false by default
+
+ u8 *rest = p;
+ u8 *key = p;
+ u8 *val = p;
+
+ u8 closing_sym = ' ';
+ u8 c;
+
+ size_t num_pairs = 0;
+
+ while (rest < end) {
+
+ while (*rest == ' ') {
+
+ rest++;
+
+ }
+
+ if (rest + 1 >= end) break;
+
+ key = rest;
+ // env variable names may not start with numbers or '='
+ if (*key == '=' || (*key >= '0' && *key <= '9')) { goto free_and_return; }
+
+ while (rest < end && *rest != '=' && *rest != ' ') {
+
+ c = *rest;
+ // lowercase is bad but we may still allow it
+ if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
+ (c < '0' || c > '9') && c != '_') {
+
+ goto free_and_return;
+
+ }
+
+ rest++;
+
+ }
+
+ if (*rest != '=') { goto free_and_return; }
+
+ *rest = '\0'; // done with variable name
+
+ rest += 1;
+ if (rest >= end || *rest == ' ') { goto free_and_return; }
+
+ val = rest;
+ if (*val == '\'' || *val == '"') {
+
+ closing_sym = *val;
+ val += 1;
+ rest += 1;
+ if (rest >= end) { goto free_and_return; }
+
+ } else {
+
+ closing_sym = ' ';
+
+ }
+
+ while (rest < end && *rest != closing_sym) {
+
+ rest++;
+
+ }
+
+ if (closing_sym != ' ' && *rest != closing_sym) { goto free_and_return; }
+
+ *rest = '\0'; // done with variable value
+
+ rest += 1;
+ if (rest < end && *rest != ' ') { goto free_and_return; }
+
+ num_pairs += 1;
+
+ setenv(key, val, 1);
+
+ }
+
+ if (num_pairs > 0) { ret_val = 1; }
+
+free_and_return:
+ ck_free(p);
+ return ret_val;
+
+}
+
/* Read mask bitmap from file. This is for the -B option. */
void read_bitmap(u8 *fname, u8 *map, size_t len) {

MODIFY
src/afl-fuzz.c
src/afl-fuzz.c
@@ -223,6 +223,7 @@ static void usage(u8 *argv0, int more_help) {
"AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n"
"AFL_QUIET: suppress forkserver status messages\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
+ "AFL_TARGET_ENV: pass extra environment variables to target\n"
"AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
"AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n"
"AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
@@ -1303,6 +1304,13 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ u8 *extra_env = (u8 *)getenv("AFL_TARGET_ENV");
+ if (extra_env && !extract_and_set_env(extra_env)) {
+
+ FATAL("Bad value of AFL_TARGET_ENV");
+
+ }
+
save_cmdline(afl, argc, argv);
fix_up_banner(afl, argv[optind]);

add AFL_TARGET_ENV to afl-fuzz