|
1 | | -### WebKit Fuzzing |
| 1 | +# WebKit Fuzzing |
2 | 2 |
|
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. |
4 | 4 |
|
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. |
6 | 6 |
|
7 | 7 | List of changes: |
8 | 8 |
|
9 | | - - Fixes to be able to build WebKitGTK+ with ASan |
| 9 | + - Fixes to be able to build WebKitGTK+ with ASan. |
10 | 10 |
|
11 | 11 | - Changed window.alert() implementation to immediately call the garbage collector instead of displaying a message window. |
12 | 12 |
|
13 | 13 | - As soon as any web process crashes, exit the main process with the same exit code. |
14 | 14 |
|
15 | | - - Created a custom target binary (webkitfuzz) |
| 15 | + - Created a custom target binary (webkitfuzz). |
16 | 16 |
|
17 | | -After applying the patch, you can build using the following commands: |
| 17 | + - Enable javascript console logging to terminal. |
18 | 18 |
|
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" |
26 | 19 |
|
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: |
29 | 28 |
|
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 .. |
| 29 | + `patch -p1 < webkit.patch` (tarball) or `git apply webkit.patch` (git repo) |
31 | 30 |
|
32 | | -make -j 4 |
| 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. |
33 | 34 |
|
34 | | -mkdir -p libexec/webkit2gtk-4.0 |
35 | | -cp bin/WebKit*Process libexec/webkit2gtk-4.0/ |
| 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. |
36 | 38 |
|
| 39 | + The build process works with either |
| 40 | + `make` or `ninja`. Our scripts use `make`, but replacing with `ninja` should |
| 41 | + work as well. |
| 42 | + |
| 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`. |
37 | 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 | + |
| 53 | +## Other Tips and Tricks |
38 | 54 |
|
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. |
| 55 | +If your build is succeeding, but you're not seeing the expected output during a |
| 56 | +run, check that your webkitfuzz is actually using WebKit executables and |
| 57 | +libraries that you build rather than the default ones on your machine: |
40 | 58 |
|
41 | | -After it builds, you can run the fuzzer binary as: |
| 59 | +1. Make sure you include the environment variable: `LD_LIBRATY_PATH=lib/` |
| 60 | +2. When webkitfuzz is running in another terminal run `ps -aux | grep WebKit` to |
| 61 | + check that the `WebKitWebProcess` and `WebKitNetworkProcess` that are running |
| 62 | + are from your build directory. |
| 63 | +3. Check that webkitfuzz is using the webkit and javascriptcore libraries from |
| 64 | + your build by running: `ldd bin/webkitfuzz` and checking what |
| 65 | + `libwebkit2gtk-4.0.so.37` and `libjavascriptcoregtk-4.0.so.18` point to. |
42 | 66 |
|
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>` |
44 | 67 |
|
45 | | -Note that exit code 42 will indicate an ASan crash. |
| 68 | +#### Other cmake flags |
46 | 69 |
|
| 70 | +Depending on what your fuzzing set-up and what you're trying to fuzz the |
| 71 | +following additional cmake flags can reduce build time and dependencies: |
| 72 | +``` |
| 73 | +-DENABLE_VIDEO=OFF |
| 74 | +-DENABLE_WEB_AUDIO=OFF |
| 75 | +-DENABLE_GAMEPAD=OFF |
| 76 | +-DENABLE_MEDIA_STREAM=OFF |
| 77 | +``` |
| 78 | + |
| 79 | +#### USE_SYSTEM_MALLOC flag |
| 80 | + |
| 81 | +Our script currently sets the `-DUSE_SYSTEM_MALLOC=ON`. When |
| 82 | +`-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. |
| 83 | + |
| 84 | +#### Symbolizing crashes |
| 85 | + |
| 86 | +If the symobilizing doesn't seem to be working, make sure that you've set |
| 87 | +ASAN_SYMBOLIZER_PATH to the version of the symbolizer that matches which clang |
| 88 | +version you're using to build WebKit. Among the first console prints when you |
| 89 | +run the build script, you'll see which compiler is running. For example: |
| 90 | +``` |
| 91 | +-- The C compiler identification is Clang 13.0.1 |
| 92 | +-- The CXX compiler identification is Clang 13.0.1 |
| 93 | +``` |
| 94 | +In this case you'd want to make sure you link to your llvm-symoblizer-13 binary |
| 95 | +since you're using clang-13. |
0 commit comments