Skip to content

Commit a3e344d

Browse files
committed
add --gcov-check and --gcov-check-bin args
1 parent 2e101f5 commit a3e344d

File tree

2 files changed

+62
-18
lines changed

2 files changed

+62
-18
lines changed

ChangeLog

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ afl-cov-0.6 (06/05/2016):
1616
execute a series of AFL test cases (instead of each individual test
1717
case one at a time) before coverage is calculated.
1818
- Add a prerequisite test to make sure the targeted binary is compiled
19-
with code coverage support ('-fprofile-arcs -ftest-coverage').
19+
with code coverage support ('-fprofile-arcs -ftest-coverage'). This test
20+
can be run by itself with --gcov-check.
2021
- Use the tempfile module for temporary files (suggested by Markus
2122
Teufelberger in issue #19).
2223

afl-cov

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ def main():
6161
print "afl-cov-" + __version__
6262
return exit_success
6363

64+
if cargs.gcov_check or cargs.gcov_check_bin:
65+
if is_gcov_enabled(cargs):
66+
return exit_success
67+
else:
68+
return exit_failure
69+
6470
if not check_requirements(cargs):
6571
return exit_failure
6672

@@ -804,19 +810,22 @@ def init_tracking(cov_paths, cargs):
804810
def is_exe(fpath):
805811
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
806812

807-
def is_gcov_enabled(binary, cargs):
813+
def is_bin_gcov_enabled(binary, cargs):
808814

809815
rv = False
810816

811817
### run readelf against the binary to see if it contains gcov support
812818
for line in run_cmd("%s -a %s" % (cargs.readelf_path, binary),
813819
False, cargs, WANT_OUTPUT)[1]:
814820
if ' __gcov' in line:
815-
if cargs.validate_args:
816-
print " Binary '%s' is compiled with code coverage support." % binary
821+
if cargs.validate_args or cargs.gcov_check or cargs.gcov_check_bin:
822+
print "[+] Binary '%s' is compiled with code coverage support." % binary
817823
rv = True
818824
break
819825

826+
if not rv and cargs.gcov_check_bin:
827+
print "[*] Binary '%s' is not compiled with code coverage support." % binary
828+
820829
return rv
821830

822831
def which(prog):
@@ -859,7 +868,11 @@ def check_requirements(cargs):
859868

860869
return False
861870

862-
def validate_cargs(cargs):
871+
def is_gcov_enabled(cargs):
872+
873+
if not is_exe(cargs.readelf_path):
874+
print "[*] Need a valid path to readelf, use --readelf-path"
875+
return False
863876

864877
if cargs.coverage_cmd:
865878
if 'AFL_FILE' not in cargs.coverage_cmd:
@@ -876,7 +889,7 @@ def validate_cargs(cargs):
876889
continue
877890
if (which(part)):
878891
found_exec = True
879-
if is_exe(cargs.readelf_path) and is_gcov_enabled(part, cargs):
892+
if is_bin_gcov_enabled(part, cargs):
880893
found_code_cov_binary = True
881894
break
882895

@@ -885,11 +898,26 @@ def validate_cargs(cargs):
885898
"--coverage-cmd '%s'" % cargs.coverage_cmd
886899
return False
887900

888-
if is_exe(cargs.readelf_path) and not found_code_cov_binary:
901+
if not found_code_cov_binary:
889902
print "[*] Could not find an executable binary with code " \
890903
"coverage support ('-fprofile-arcs -ftest-coverage') " \
891904
"in --coverage-cmd '%s'" % cargs.coverage_cmd
892905
return False
906+
907+
elif cargs.gcov_check_bin:
908+
if not is_bin_gcov_enabled(cargs.gcov_check_bin, cargs):
909+
return False
910+
elif cargs.gcov_check:
911+
print "[*] Either --coverage-cmd or --gcov-check-bin required in --gcov-check mode"
912+
return False
913+
914+
return True
915+
916+
def validate_cargs(cargs):
917+
918+
if cargs.coverage_cmd:
919+
if not is_gcov_enabled(cargs):
920+
return False
893921
else:
894922
if not cargs.func_search and not cargs.line_search:
895923
print "[*] Must set --coverage-cmd or --func-search/--line-search"
@@ -900,18 +928,10 @@ def validate_cargs(cargs):
900928
print "[*] --code-dir path does not exist"
901929
return False
902930

903-
### make sure the code has been compiled with code coverage support,
904-
### so *.gcno files should exist
905-
found_code_coverage_support = False
906-
for root, dirs, files in os.walk(cargs.code_dir):
907-
for filename in files:
908-
if filename[-5:] == '.gcno':
909-
found_code_coverage_support = True
910-
if not found_code_coverage_support:
911-
print "[*] Could not find any *.gcno files in --code-dir " \
912-
"'%s', is code coverage ('-fprofile-arcs -ftest-coverage') " \
913-
"compiled in?" % cargs.code_dir
931+
### make sure code coverage support is compiled in
932+
if not gcno_files_exist(cargs):
914933
return False
934+
915935
else:
916936
if not cargs.func_search and not cargs.line_search:
917937
print "[*] Must set --code-dir unless using --func-search " \
@@ -943,6 +963,23 @@ def validate_cargs(cargs):
943963

944964
return True
945965

966+
967+
def gcno_files_exist(cargs):
968+
969+
### make sure the code has been compiled with code coverage support,
970+
### so *.gcno files should exist
971+
found_code_coverage_support = False
972+
for root, dirs, files in os.walk(cargs.code_dir):
973+
for filename in files:
974+
if filename[-5:] == '.gcno':
975+
found_code_coverage_support = True
976+
if not found_code_coverage_support:
977+
print "[*] Could not find any *.gcno files in --code-dir " \
978+
"'%s', is code coverage ('-fprofile-arcs -ftest-coverage') " \
979+
"compiled in?" % cargs.code_dir
980+
return False
981+
return True
982+
946983
def is_afl_running(cargs):
947984
while not is_dir(cargs.afl_fuzzing_dir):
948985
if not cargs.background:
@@ -1096,6 +1133,12 @@ def parse_cmdline():
10961133
p.add_argument("--sleep", type=int,
10971134
help="In --live mode, # of seconds to sleep between checking for new queue files",
10981135
default=60)
1136+
p.add_argument("--gcov-check", action='store_true',
1137+
help="Check to see if there is a binary in --coverage-cmd (or in --gcov-check-bin) has coverage support",
1138+
default=False)
1139+
p.add_argument("--gcov-check-bin", type=str,
1140+
help="Test a specific binary for code coverage support",
1141+
default=False)
10991142
p.add_argument("--background", action='store_true',
11001143
help="Background mode - if also in --live mode, will exit when the alf-fuzz process is finished",
11011144
default=False)

0 commit comments

Comments
 (0)