mirror of
https://github.com/openharmony/third_party_sane-airscan.git
synced 2026-07-01 21:14:00 -04:00
Add basic fuzzers
To compile: * CXX=clang++ meson build * ninja -C build fuzzer-xml fuzzer-uri These fuzzers use libFuzzer and asan support in clang 10 or later to fuzz the XML parsing and http_uri functions. They aren't very thorough (yet), but demonstrate the basic technique.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
The `fuzzer` directory contains several fuzz targets that make use of asan and
|
||||
[libFuzzer](https://llvm.org/docs/LibFuzzer.html) from clang 10 or later to test
|
||||
functions that are expected to process untrusted inputs.
|
||||
|
||||
To build:
|
||||
|
||||
```
|
||||
CXX=clang++-10 meson build
|
||||
ninja -C build fuzzer-$name
|
||||
```
|
||||
|
||||
where `$name` can be any of the files in the `fuzzer` directory.
|
||||
|
||||
You can then run the fuzzer as `build/fuzzer-$name`. The basic mode will run
|
||||
indefinitely until a problem is found. Pass `-help=1` to see additional fuzzer
|
||||
options.
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright 2020 The Chromium OS Authors. All rights reserved.
|
||||
// See LICENSE for license terms and conditions.
|
||||
|
||||
#include <fuzzer/FuzzedDataProvider.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
||||
#include "airscan.h"
|
||||
|
||||
constexpr int kMaxInputSize = 32 * 1024;
|
||||
|
||||
namespace {
|
||||
|
||||
struct LogWrapper {
|
||||
LogWrapper() { log_init(); }
|
||||
~LogWrapper() { log_cleanup(); }
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
// Limit fuzzer input size to 32KB. URLs technically don't have a limit, but
|
||||
// practical sizes found in real life will be under 4KB. This gives us a
|
||||
// buffer to test longer URLs without wasting time on huge inputs.
|
||||
if (size > kMaxInputSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FuzzedDataProvider data_provider(data, size);
|
||||
std::string str_input = data_provider.ConsumeRemainingBytesAsString();
|
||||
|
||||
LogWrapper log;
|
||||
|
||||
http_uri *uri1 = http_uri_new(str_input.c_str(), true);
|
||||
if (uri1 == NULL) {
|
||||
return 0;
|
||||
}
|
||||
http_uri_free(uri1);
|
||||
|
||||
uri1 = http_uri_new(str_input.c_str(), false);
|
||||
if (uri1 == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
http_uri *uri2 = http_uri_clone(uri1);
|
||||
if (uri2 == NULL) {
|
||||
http_uri_free(uri1);
|
||||
return 0;
|
||||
}
|
||||
http_uri_free(uri2);
|
||||
|
||||
const char *str = http_uri_str(uri1);
|
||||
uri2 = http_uri_new(str, true);
|
||||
if (uri2 == NULL) {
|
||||
http_uri_free(uri1);
|
||||
return 0;
|
||||
}
|
||||
http_uri_free(uri2);
|
||||
|
||||
const char *path = http_uri_get_path(uri1);
|
||||
uri2 = http_uri_new_relative(uri1, path, false, false);
|
||||
if (uri2 == NULL) {
|
||||
http_uri_free(uri1);
|
||||
return 0;
|
||||
}
|
||||
http_uri_free(uri2);
|
||||
|
||||
http_uri_fix_end_slash(uri1);
|
||||
http_uri_free(uri1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2020 The Chromium OS Authors. All rights reserved.
|
||||
// See LICENSE for license terms and conditions.
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
||||
#include <libxml/xmlerror.h>
|
||||
|
||||
#include "airscan.h"
|
||||
|
||||
void noerrs(void *ctx, const char*msg, ...) {
|
||||
// Ignore the libxml error messages.
|
||||
}
|
||||
|
||||
constexpr int kMaxInputSize = 32 * 1024;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
// Limit fuzzer input size to 32KB. libxml can take a very long time to
|
||||
// parse very large inputs, which causes the fuzzer to time out.
|
||||
if (size > kMaxInputSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmlSetGenericErrorFunc(NULL, noerrs);
|
||||
|
||||
xml_rd *xml = NULL;
|
||||
if (xml_rd_begin(&xml, (const char*)data, size, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
if (xml == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (!xml_rd_end(xml)) {
|
||||
xml_rd_deep_next(xml, 0);
|
||||
}
|
||||
|
||||
xml_rd_finish(&xml);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+12
-1
@@ -1,4 +1,4 @@
|
||||
project('sane-airscan', 'c')
|
||||
project('sane-airscan', 'c', 'cpp')
|
||||
|
||||
sources = [
|
||||
'airscan-array.c',
|
||||
@@ -76,6 +76,17 @@ dll_file = configure_file(
|
||||
copy: true
|
||||
)
|
||||
|
||||
foreach fuzzer : ['uri', 'xml']
|
||||
executable(
|
||||
'fuzzer-' + fuzzer,
|
||||
sources + ['fuzzer/@0@.cc'.format(fuzzer)],
|
||||
dependencies: shared_deps,
|
||||
build_by_default: false,
|
||||
cpp_args: ['-fsanitize=address', '-fsanitize=fuzzer-no-link'],
|
||||
link_args: ['-fsanitize=address', '-fsanitize=fuzzer']
|
||||
)
|
||||
endforeach
|
||||
|
||||
install_man('sane-airscan.5')
|
||||
install_man('airscan-discover.1')
|
||||
install_data('airscan.conf',
|
||||
|
||||
Reference in New Issue
Block a user