Simple one-bash-script utility for git bisection. Receives suspected commit range, PoC input, and PoC command, produces the first bad commit (if it exists in the range).
Background
Git already has an embedded facility to trace back the root commit that introduced a given bug, namely git bisect
, but its usage is seemingly not widespread. Why is it that? I suspect it's because git bisect
still resorts to quite a lot of manual efforts, such as deciding whether a given commit is good (bug-free) or bad (bug-affected).
However, come to think of it, does every kind of bug actually need manual efforts to decide the presence of a certain bug? When we trace back the root commit of a certain bug, we simply investigate whether a given PoC input exhibits the same crash at the same program location. This procedure is quite mechanical, so it's not supposed to require human efforts.
On this account, I wrote a short bash script that automates the git bisect
operation, given a suspected commit range and a PoC input/command. The script simply decides whether a certain commit is bug-affected by identifying the bug type and the crashing function in the ASAN report, spitting out the first bad commit hash as a result if it exists between the suspected commit range.
Requirements
- ASAN-enabled compiler
- (Obviously) git-managed project
- Known bad/good commit hashes
- PoC input
- PoC command
Using the Code
- Place a
BISECT
file in the project directory, formatted as follows:
<known_bad_commit> <known_good_commit> <poc_input_path> -- <poc_command>
<known_bad_commit>
: Known bad commit hash (tag name applicable as tags/<name>
) <known_good_commit>
: Known good commit hash <poc_input_path>
: Path to PoC input <poc_command>
: PoC command, with `@@
` as a placeholder for the PoC input
- Place `
bisector
` in the project directory and execute it:
$ ./bisector
- When finished, find the first bad commit in the
FIRSTBAD
file. See {good,bad}.bis
for the ASAN dumps from the last good and first bad commit, respectively.
Example: CVE-2016-3658
- Prepare
libtiff
itself and the PoC input.
$ git clone https://gitlab.com/libtiff/libtiff.git libtiff
$ cd libtiff
$ curl http://bugzilla.maptools.org/attachment.cgi?id=601 > POC
The PoC input is provided by http://bugzilla.maptools.org/show_bug.cgi?id=2500.
- Place a
BISECT
file.
d7db70c9 tags/Release-v4-0-0 POC -- ./tools/tiffset @@
d7db70c9
is the last commit before 07/01/2015, and we expect CVE-2016-3658 has been created after 4.0.0.
- Place the
bisector
script and run it.
$ ./bisector
[*] Initializing...
+ Commit range: 'd7db70c9'(bad) to 'f7b79dc7'(good)
+ PoC input: POC
+ PoC command: ./tools/tiffset @@
[*] Generating most recent ASAN dump...
[*] Testing commit 'd7db70c9'...
+ Bug type: heap-buffer-overflow
+ Crash function: TIFFWriteDirectoryTagSampleformatArray
[*] Verifying good commit...
[*] Testing commit 'f7b79dc7'... Good
[*] Bisecting...
[*] Testing commit 'd1be5cb7'... (234 remaining) Bad
[*] Testing commit '871d1067'... (117 remaining) Bad
[*] Testing commit '1358a916'... (58 remaining) Bad
[*] Testing commit 'f502a159'... (29 remaining) Good
[*] Testing commit '920688aa'... (15 remaining) Bad
[*] Testing commit 'e54e9545'... (7 remaining) Good
[*] Testing commit 'c0733844'... (4 remaining) Bad
[*] Testing commit 'af47ad26'... (2 remaining) Good
[*] Verifying...
[*] Testing commit 'c0733844'... Bad
[*] Testing commit 'af47ad26'... Good
+ First bad commit: c0733844461ceb1b05f41968c1d962480f0db5f6 (see FIRSTBAD)
+ {Last-good, First-bad} ASAN log: {good, bad}.bis
+ All done!
- Check
FIRSTBAD
to see the first bad commit.
c0733844461ceb1b05f41968c1d962480f0db5f6
Disclaimer
- Currently supports
configure
only - Supported bug types include:
- ASAN-detectable memory corruptions
- Divide-by-zero (SIGFPE)
- Null dereference (SIGSEGV)
- Assertion failure
- This script tests a bug by identifying the bug type and the crashing function in the ASAN dump; it does not recognize whether the bug manifests in another commit with a different bug type or at a different function.
- Random contributions would be very much appreciated.
History
- 16th July, 2020: Initial post