Skip to content

Commit dde0f80

Browse files
authored
Merge pull request #4 from maddiestone/master
Update webkitfuzz to current releases
2 parents 6863555 + 4c10e97 commit dde0f80

3 files changed

Lines changed: 230 additions & 119 deletions

File tree

WebKitFuzz/README.md

Lines changed: 93 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,116 @@
1-
### WebKit Fuzzing
1+
# WebKit Fuzzing
22

3-
webkit.patch is a patch file that makes it easier to build WebKitGTK+ with ASan and fuzz it.
3+
This project includes directions and a patch ([webkit.patch](https://github.com/googleprojectzero/p0tools/blob/master/WebKitFuzz/webkit.patch)) to make fuzzing WebKit easier. We use the WebKitGTK+ implementation, running on Linux as the fuzzing target. This patch and instructions will build WebKitGTK+ with ASAN and make some changes that make fuzzing easier.
44

5-
The patch file was made with WebKitGTK+ version 2.20.2 (https://webkitgtk.org/releases/webkitgtk-2.20.2.tar.xz) and might not work as is on other versions.
5+
The patch file was made with [WebKitGTK+ version 2.34.6](https://webkitgtk.org/releases/webkitgtk-2.34.6.tar.xz) and/or the WebKit Github repo as of commit [690b38f1f792a1d9c72f3fcb6f8add83090d459a](https://github.com/WebKit/WebKit/tree/690b38f1f792a1d9c72f3fcb6f8add83090d459a). It might not work as is on other versions.
66

77
List of changes:
88

9-
- Fixes to be able to build WebKitGTK+ with ASan
9+
- Fixes to be able to build WebKitGTK+ with ASan.
1010

1111
- Changed window.alert() implementation to immediately call the garbage collector instead of displaying a message window.
1212

1313
- As soon as any web process crashes, exit the main process with the same exit code.
1414

15-
- Created a custom target binary (webkitfuzz)
15+
- Created a custom target binary (webkitfuzz).
1616

17-
After applying the patch, you can build using the following commands:
17+
- Enable javascript console logging to terminal.
1818

19-
```
20-
export CC=/usr/bin/clang
21-
export CXX=/usr/bin/clang++
22-
export CFLAGS="-fsanitize=address"
23-
export CXXFLAGS="-fsanitize=address"
24-
export LDFLAGS="-fsanitize=address"
25-
export ASAN_OPTIONS="detect_leaks=0"
2619

27-
mkdir build
28-
cd build
20+
## Building webkitfuzz & WebKit
21+
22+
There are two options for building WebKitGTK+: WebKitGTK+ stable release tarball
23+
or the WebKit git repo. These instructions support both options.
24+
25+
1. Get the code by either downloading and extracting the [WebKitGTK+ tarball version 2.34.6](https://webkitgtk.org/releases/webkitgtk-2.34.6.tar.xz) or cloning the WebKit git repo as of commit [690b38f1f792a1d9c72f3fcb6f8add83090d459a](https://github.com/WebKit/WebKit/tree/690b38f1f792a1d9c72f3fcb6f8add83090d459a).
26+
27+
2. Apply the changes in [webkit.patch](https://github.com/googleprojectzero/p0tools/blob/master/WebKitFuzz/webkit.patch) by running one of the following commands from the root of your WebKit tree:
28+
29+
`patch -p1 < webkit.patch` (tarball) or `git apply webkit.patch` (git repo)
30+
31+
3. Build WebKit by running the build script ([`build_webkitfuzz.sh`](https://github.com/googleprojectzero/p0tools/blob/master/WebKitFuzz/build_webkitfuzz.sh)) from the root of the WebKit
32+
tree (`webkitgtk-2.34.6/` or `WebKit/`). This script will place the built files
33+
into the `build/` directory.
2934

30-
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=. -DCMAKE_SKIP_RPATH=ON -DPORT=GTK -DLIB_INSTALL_DIR=./lib -DUSE_LIBHYPHEN=OFF -DENABLE_MINIBROWSER=ON -DUSE_SYSTEM_MALLOC=ON -DENABLE_GEOLOCATION=OFF -DENABLE_GTKDOC=OFF -DENABLE_INTROSPECTION=OFF -DENABLE_OPENGL=OFF -DENABLE_ACCELERATED_2D_CANVAS=OFF -DENABLE_CREDENTIAL_STORAGE=OFF -DENABLE_GAMEPAD_DEPRECATED=OFF -DENABLE_MEDIA_STREAM=OFF -DENABLE_WEB_RTC=OFF -DENABLE_PLUGIN_PROCESS_GTK2=OFF -DENABLE_SPELLCHECK=OFF -DENABLE_VIDEO=OFF -DENABLE_WEB_AUDIO=OFF -DUSE_LIBNOTIFY=OFF -DENABLE_SUBTLE_CRYPTO=OFF -DUSE_WOFF2=OFF -Wno-dev ..
35+
During the `cmake` stage, WebKit will likely yell at you to install
36+
requisite libraries. Many dependencies are turned off with the `ENABLE` and
37+
`USE` flags, but many are still required.
3138

32-
make -j 4
39+
The build process works with either
40+
`make` or `ninja`. Our scripts use `make`, but replacing with `ninja` should
41+
work as well.
3342

34-
mkdir -p libexec/webkit2gtk-4.0
35-
cp bin/WebKit*Process libexec/webkit2gtk-4.0/
43+
*NOTE:* The official WebKit build instructions recommend building with
44+
`Tools/Scripts/build-webkit`. In our experience this is a less reliable
45+
process for the purposes of building a separate target binary that will call and start the
46+
WebKit processes.
47+
48+
4. Run the fuzzer binary from the build directory (`build/`) with the following command. The sample can either be a path to a file or a URL beginning with `http` or `https`. If you don't set a `log_path`, then the crash will instead print to stdout.
49+
```
50+
ASAN_OPTIONS=detect_leaks=0,exitcode=42,log_path=asan_logs/crash ASAN_SYMBOLIZER_PATH=</path/to/llvm-symbolizer> LD_LIBRARY_PATH=lib/ ./bin/webkitfuzz </path/to/sample> <timeout in sec>
51+
```
52+
## Debugging with GDB
53+
54+
To debug the WebKit Web Process with gdb you can use `gdbserver`. Run webkitfuzz
55+
with the following command. I suggest using a long timeout, like 3600s or 1 hr,
56+
to ensure you have enough time to debug.
57+
```
58+
WEB_PROCESS_CMD_PREFIX='/usr/bin/gdbserver localhost:8080' ASAN_OPTIONS=detect_leaks=0,exitcode=42 LD_LIBRARY_PATH=lib/ ./bin/webkitfuzz http://poc.com 3600
59+
```
60+
From another terminal, you'll connect to the gdbserver as:
61+
```
62+
$ gdb bin/WebKitWebProcess
63+
(gdb) target remote localhost:8081
64+
```
3665

66+
If you're running on the same machine, then I suggest also running the following
67+
to save *a lot* of time. This will tell gdb that it doesn't have to send the
68+
symbols from the server to the client, but actually you can find them locally at
69+
this path.
70+
```
71+
(gdb) set sysroot /
3772
```
3873

39-
And install dependencies when it complains. Note that some of the dependencies were already removed via `-DENABLE_...=OFF` flags. These flags are mosly not necessary, but you will need to install additional dependencies if you remove them.
74+
## Other Tips and Tricks
75+
76+
If your build is succeeding, but you're not seeing the expected output during a
77+
run, check that your webkitfuzz is actually using WebKit executables and
78+
libraries that you build rather than the default ones on your machine:
79+
80+
1. Make sure you include the environment variable: `LD_LIBRATY_PATH=lib/`
81+
2. When webkitfuzz is running in another terminal run `ps -aux | grep WebKit` to
82+
check that the `WebKitWebProcess` and `WebKitNetworkProcess` that are running
83+
are from your build directory.
84+
3. Check that webkitfuzz is using the webkit and javascriptcore libraries from
85+
your build by running: `ldd bin/webkitfuzz` and checking what
86+
`libwebkit2gtk-4.0.so.37` and `libjavascriptcoregtk-4.0.so.18` point to.
87+
4088

41-
After it builds, you can run the fuzzer binary as:
89+
#### Other cmake flags
4290

43-
`ASAN_OPTIONS=detect_leaks=0,exitcode=42 ASAN_SYMBOLIZER_PATH=/path/to/llvm-symbolizer LD_LIBRARY_PATH=./lib ./bin/webkitfuzz /path/to/sample <timeout>`
91+
Depending on what your fuzzing set-up and what you're trying to fuzz the
92+
following additional cmake flags can reduce build time and dependencies:
93+
```
94+
-DENABLE_VIDEO=OFF
95+
-DENABLE_WEB_AUDIO=OFF
96+
-DENABLE_GAMEPAD=OFF
97+
-DENABLE_MEDIA_STREAM=OFF
98+
```
99+
100+
#### USE_SYSTEM_MALLOC flag
44101

45-
Note that exit code 42 will indicate an ASan crash.
102+
Our script currently sets the `-DUSE_SYSTEM_MALLOC=ON`. When
103+
`-DUSE_SYSTEM_MALLOC=OFF`, WebKit's `bmalloc` is used in of the system's `malloc`. `bmalloc` adds exploit mitigations that WebKit has implemented such as IsoHeap and GigaCage. Using the system's `malloc` may lead to better ASAN coverage. Change this flag based on your fuzzing needs.
46104

105+
#### Symbolizing crashes
106+
107+
If the symobilizing doesn't seem to be working, make sure that you've set
108+
ASAN_SYMBOLIZER_PATH to the version of the symbolizer that matches which clang
109+
version you're using to build WebKit. Among the first console prints when you
110+
run the build script, you'll see which compiler is running. For example:
111+
```
112+
-- The C compiler identification is Clang 13.0.1
113+
-- The CXX compiler identification is Clang 13.0.1
114+
```
115+
In this case you'd want to make sure you link to your llvm-symoblizer-13 binary
116+
since you're using clang-13.

WebKitFuzz/build_webkitfuzz.sh

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/bin/bash
2+
3+
echo "[*] Building webkitfuzz."
4+
5+
export CC=/usr/bin/clang
6+
export CXX=/usr/bin/clang++
7+
8+
# -g flag for debugging symbols
9+
# -w to skip printing warnings
10+
# -Wfatal-error to immediately stop build with an error is detected
11+
export CFLAGS="-fsanitize=address -g -w -Wfatal-error"
12+
export CXXFLAGS="-fsanitize=address -g -w -Wfatal-error"
13+
export LDFLAGS="-fsanitize=address -g"
14+
export ASAN_OPTIONS="detect_leaks=0"
15+
16+
mkdir build
17+
cd build
18+
19+
echo "[*] webkitfuzz: running cmake"
20+
21+
# Explanation of cmake flags:
22+
# -DCMAKE_BULD_TYPE=Release -DPORT=GTK -- Build release build of WebKit GTK port
23+
#
24+
# -G "Unix Makefiles". Change to -G "Ninja" if you want to build with ninja
25+
#
26+
# -DCMAKE_INSTALL_PREFIX=. -DCMAKE_INSTALL_LIBEXECDIR=libexec/
27+
# -DLIB_INSTALL_DIR=lib/ -DCMAKE_SKIP_RPATCH=ON - Required to have all the build
28+
# files and libs end up in your build/ directory so webkitfuzz uses those files
29+
# instead of the default on your machine
30+
#
31+
# -DENABLE_SANITIZERS=address - Build with ASAN
32+
# -DENABLE_MINIBROWSER=ON - webkitfuzz uses minibrowser
33+
#
34+
# The rest turn off dependencies not needed for most fuzzing cases
35+
cmake -DCMAKE_BUILD_TYPE=Release -DPORT=GTK -G "Unix Makefiles" \
36+
-DCMAKE_INSTALL_PREFIX=. -DCMAKE_SKIP_RPATH=ON -DLIB_INSTALL_DIR=./lib \
37+
-DCMAKE_INSTALL_LIBEXECDIR=./libexec \
38+
-DENABLE_SANITIZERS=address \
39+
-DENABLE_MINIBROWSER=ON \
40+
-DUSE_LIBSECRET=OFF \
41+
-DENABLE_GEOLOCATION=OFF \
42+
-DENABLE_GTKDOC=OFF \
43+
-DENABLE_MEDIA_STREAM=OFF \
44+
-DENABLE_WEB_RTC=OFF \
45+
-DUSE_SOUP2=ON \
46+
-DUSE_WPE_RENDERER=OFF \
47+
-DUSE_SYSTEMD=OFF \
48+
-DENABLE_INTROSPECTION=OFF \
49+
-DENABLE_SPELLCHECK=OFF \
50+
-DUSE_LIBNOTIFY=OFF \
51+
-DUSE_LIBHYPHEN=OFF \
52+
-DUSE_WOFF2=OFF \
53+
-DUSE_JPEGXL=OFF \
54+
-DENABLE_THUNDER=OFF \
55+
-DENABLE_JOURNALD_LOG=OFF \
56+
-DUSE_SYSTEM_MALLOC=ON \
57+
..
58+
59+
# Calling make with <num cores>*2. Change based on your machine
60+
echo "[*]: Calling make -j $((`nproc`*2))"
61+
make -j$((`nproc`*2))
62+
63+
echo "[*] Finished make. Calling make install."
64+
make install
65+
66+
echo "[*] Finished! Run webkitfuzz from build/ directory."
67+
echo "[*] Command to run: ASAN_OPTIONS=detect_leaks=0,exitcode=42,log_path=asan_logs/ ASAN_SYMBOLIZER_PATH=</path/to/llvm-symbolizer> LD_LIBRARY_PATH=lib ./bin/webkitfuzz </path/to/sample> <timeout in sec>"

0 commit comments

Comments
 (0)