From bc846b39a8d3ad047a69cbc9c46b42c2504de415 Mon Sep 17 00:00:00 2001 From: Ceyhun Alp Date: Mon, 5 Oct 2020 08:03:04 +0000 Subject: [PATCH 1/8] Fuzzers for cairo [WIP] Updates to fuzzers Cleaning up old fuzzers + raster fuzzer added clean up meson.build file minor julien fixes fixing fuzzers Fuzzers for cairo --- fuzzing/fuzzer_temp_file.h | 81 ++++++++++++++++++++++++++++++ fuzzing/meson.build | 18 +++++++ fuzzing/pdf_surface_fuzzer.c | 34 +++++++++++++ fuzzing/raster_fuzzer.c | 52 +++++++++++++++++++ fuzzing/surface_write_png_fuzzer.c | 32 ++++++++++++ fuzzing/text_glyphs_fuzzer.c | 44 ++++++++++++++++ meson.build | 2 + 7 files changed, 263 insertions(+) create mode 100644 fuzzing/fuzzer_temp_file.h create mode 100644 fuzzing/meson.build create mode 100644 fuzzing/pdf_surface_fuzzer.c create mode 100644 fuzzing/raster_fuzzer.c create mode 100644 fuzzing/surface_write_png_fuzzer.c create mode 100644 fuzzing/text_glyphs_fuzzer.c diff --git a/fuzzing/fuzzer_temp_file.h b/fuzzing/fuzzer_temp_file.h new file mode 100644 index 000000000..158b49781 --- /dev/null +++ b/fuzzing/fuzzer_temp_file.h @@ -0,0 +1,81 @@ +// Copyright 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Adapter utility from fuzzer input to a temporary file, for fuzzing APIs that +// require a file instead of an input buffer. + +#ifndef FUZZER_TEMP_FILE_H_ +#define FUZZER_TEMP_FILE_H_ + +#include +#include +#include +#include +#include + +// Pure-C interface for creating and cleaning up temporary files. + +static char* fuzzer_get_tmpfile(const uint8_t* data, size_t size) { + char* filename_buffer = strdup("/tmp/generate_temporary_file.XXXXXX"); + if (!filename_buffer) { + perror("Failed to allocate file name buffer."); + abort(); + } + const int file_descriptor = mkstemp(filename_buffer); + if (file_descriptor < 0) { + perror("Failed to make temporary file."); + abort(); + } + FILE* file = fdopen(file_descriptor, "wb"); + if (!file) { + perror("Failed to open file descriptor."); + close(file_descriptor); + abort(); + } + const size_t bytes_written = fwrite(data, sizeof(uint8_t), size, file); + if (bytes_written < size) { + close(file_descriptor); + fprintf(stderr, "Failed to write all bytes to file (%zu out of %zu)", + bytes_written, size); + abort(); + } + fclose(file); + return filename_buffer; +} + +static void fuzzer_release_tmpfile(char* filename) { + if (unlink(filename) != 0) { + perror("WARNING: Failed to delete temporary file."); + } + free(filename); +} + +// C++ RAII object for creating temporary files. + +#ifdef __cplusplus +class FuzzerTemporaryFile { + public: + FuzzerTemporaryFile(const uint8_t* data, size_t size) + : filename_(fuzzer_get_tmpfile(data, size)) {} + + ~FuzzerTemporaryFile() { fuzzer_release_tmpfile(filename_); } + + const char* filename() const { return filename_; } + + private: + char* filename_; +}; +#endif + +#endif // FUZZER_TEMP_FILE_H_ diff --git a/fuzzing/meson.build b/fuzzing/meson.build new file mode 100644 index 000000000..a18feb27c --- /dev/null +++ b/fuzzing/meson.build @@ -0,0 +1,18 @@ +fuzz_targets = [ + 'raster_fuzzer', + 'pdf_surface_fuzzer', + 'text_glyphs_fuzzer', + 'surface_write_png_fuzzer', +] + +fuzz_args = ['-fsanitize=fuzzer,address'] + +foreach target_name : fuzz_targets + exe = executable(target_name, [target_name + '.c'], + include_directories: [incbase, incsrc, incboilerplate, incpdiff, inccairoscript, inccairomissing], + c_args: [fuzz_args, '-DHAVE_CONFIG_H'], + link_with: [libcairo, libcairoboilerplate, libpdiff], + link_args: [fuzz_args, extra_link_args], + dependencies: [deps, test_deps], + ) +endforeach diff --git a/fuzzing/pdf_surface_fuzzer.c b/fuzzing/pdf_surface_fuzzer.c new file mode 100644 index 000000000..c8ae6913a --- /dev/null +++ b/fuzzing/pdf_surface_fuzzer.c @@ -0,0 +1,34 @@ +#include +#include "cairo-boilerplate.h" +#include "fuzzer_temp_file.h" + +#define WIDTH_IN_INCHES 3 +#define HEIGHT_IN_INCHES 3 +#define WIDTH_IN_POINTS (WIDTH_IN_INCHES * 72.0) +#define HEIGHT_IN_POINTS (HEIGHT_IN_INCHES * 72.0) + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + cairo_t *cr; + cairo_surface_t *surface; + cairo_status_t status; + int flags; + + char *tmpfile = fuzzer_get_tmpfile(data, size); + surface = cairo_pdf_surface_create(tmpfile, WIDTH_IN_POINTS, HEIGHT_IN_POINTS); + status = cairo_surface_status(surface); + if (status != CAIRO_STATUS_SUCCESS) { + fuzzer_release_tmpfile(tmpfile); + return 0; + } + + flags = CAIRO_PDF_OUTLINE_FLAG_BOLD | CAIRO_PDF_OUTLINE_FLAG_OPEN; + cairo_pdf_surface_set_page_label(surface, data); + cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_TITLE, data); + cairo_tag_begin(cr, data, NULL); + cairo_tag_end(cr, data); + + cairo_surface_destroy(surface); + cairo_destroy(cr); + fuzzer_release_tmpfile(tmpfile); + return 0; +} diff --git a/fuzzing/raster_fuzzer.c b/fuzzing/raster_fuzzer.c new file mode 100644 index 000000000..bd6bdaf54 --- /dev/null +++ b/fuzzing/raster_fuzzer.c @@ -0,0 +1,52 @@ +#include "cairo-boilerplate.h" +#include "fuzzer_temp_file.h" + +#define WIDTH 200 +#define HEIGHT 80 + +static cairo_surface_t * +acquire (cairo_pattern_t *pattern, void *closure, + cairo_surface_t *target, + const cairo_rectangle_int_t *extents) +{ + return cairo_image_surface_create_from_png(closure); +} + +static void +release (cairo_pattern_t *pattern, void *closure, cairo_surface_t *surface) +{ + cairo_surface_destroy(surface); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + cairo_t *cr; + cairo_surface_t *surface; + cairo_pattern_t *pattern; + cairo_content_t content; + cairo_status_t status; + int w, h; + + char *tmpfile = fuzzer_get_tmpfile(data, size); + surface = cairo_image_surface_create_from_png(tmpfile); + status = cairo_surface_status (surface); + if (status != CAIRO_STATUS_SUCCESS) { + fuzzer_release_tmpfile(tmpfile); + return 0; + } + + cr = cairo_create(surface); + content = cairo_surface_get_content(surface); + w = cairo_image_surface_get_width(surface); + h = cairo_image_surface_get_height(surface); + + pattern = cairo_pattern_create_raster_source(data, content, w, h); + cairo_raster_source_pattern_set_acquire (pattern, acquire, release); + cairo_set_source(cr, pattern); + cairo_paint(cr); + + cairo_destroy(cr); + cairo_pattern_destroy(pattern); + cairo_surface_destroy(surface); + fuzzer_release_tmpfile(tmpfile); + return 0; +} diff --git a/fuzzing/surface_write_png_fuzzer.c b/fuzzing/surface_write_png_fuzzer.c new file mode 100644 index 000000000..c29bc5adb --- /dev/null +++ b/fuzzing/surface_write_png_fuzzer.c @@ -0,0 +1,32 @@ +#include "cairo-boilerplate.h" +#include "fuzzer_temp_file.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + cairo_surface_t *image; + cairo_surface_t *surface; + cairo_status_t status; + cairo_format_t format; + + char *tmpfile = fuzzer_get_tmpfile(data, size); + image = cairo_image_surface_create_from_png(tmpfile); + status = cairo_surface_status (image); + if (status != CAIRO_STATUS_SUCCESS) { + fuzzer_release_tmpfile(tmpfile); + return 0; + } + + format = cairo_image_surface_get_format(image); + surface = cairo_image_surface_create_for_data((unsigned char*)data, format, 1, 1, size); + status = cairo_surface_status (surface); + if (status != CAIRO_STATUS_SUCCESS) { + cairo_surface_destroy(image); + fuzzer_release_tmpfile(tmpfile); + return 0; + } + cairo_surface_write_to_png(surface, tmpfile); + + cairo_surface_destroy(surface); + cairo_surface_destroy(image); + fuzzer_release_tmpfile(tmpfile); + return 0; +} diff --git a/fuzzing/text_glyphs_fuzzer.c b/fuzzing/text_glyphs_fuzzer.c new file mode 100644 index 000000000..91a96dc7d --- /dev/null +++ b/fuzzing/text_glyphs_fuzzer.c @@ -0,0 +1,44 @@ +#include "cairo-boilerplate.h" +#include "fuzzer_temp_file.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + cairo_t *cr; + cairo_surface_t *surface; + cairo_status_t status; + cairo_text_extents_t extents; + cairo_text_cluster_t cluster; + + // Taken from test/text-glyph-range.c + long int index[] = { + 0, /* 'no matching glyph' */ + 0xffff, /* kATSDeletedGlyphCode */ + 0x1ffff, /* out of range */ + -1L, /* out of range */ + 70, 68, 76, 85, 82 /* 'cairo' */ + }; + + char *tmpfile = fuzzer_get_tmpfile(data, size); + surface = cairo_image_surface_create_from_png(tmpfile); + status = cairo_surface_status(surface); + if (status != CAIRO_STATUS_SUCCESS) { + fuzzer_release_tmpfile(tmpfile); + return 0; + } + + cr = cairo_create(surface); + cairo_text_extents(cr, data, &extents); + cluster.num_bytes = size; + cluster.num_glyphs = 1; + for (int i = 0; i < 9; i++) { + // Taken from test/text-glyph-range.c + cairo_glyph_t glyph = { + index[i], 10 * i, 25 + }; + cairo_show_text_glyphs(cr, data, size, &glyph, 1, &cluster, 1, 0); + } + + cairo_destroy(cr); + cairo_surface_destroy(surface); + fuzzer_release_tmpfile(tmpfile); + return 0; +} diff --git a/meson.build b/meson.build index 13c5482b6..987639930 100644 --- a/meson.build +++ b/meson.build @@ -908,6 +908,8 @@ if not get_option('tests').disabled() and feature_conf.get('CAIRO_HAS_PNG_FUNCTI subdir('test') endif +subdir('fuzzing') + configure_file(output: 'config.h', configuration: conf) foreach feature: built_features From f574bf756e14bfbef2cf8f9baa7a3c04c0eb0094 Mon Sep 17 00:00:00 2001 From: Ceyhun Alp Date: Mon, 16 Nov 2020 14:17:31 +0000 Subject: [PATCH 2/8] Minor changes --- fuzzing/pdf_surface_fuzzer.c | 17 +++++++++++------ fuzzing/raster_fuzzer.c | 8 +++++++- fuzzing/text_glyphs_fuzzer.c | 9 +++++++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/fuzzing/pdf_surface_fuzzer.c b/fuzzing/pdf_surface_fuzzer.c index c8ae6913a..aafc51c13 100644 --- a/fuzzing/pdf_surface_fuzzer.c +++ b/fuzzing/pdf_surface_fuzzer.c @@ -21,14 +21,19 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; } - flags = CAIRO_PDF_OUTLINE_FLAG_BOLD | CAIRO_PDF_OUTLINE_FLAG_OPEN; - cairo_pdf_surface_set_page_label(surface, data); - cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_TITLE, data); - cairo_tag_begin(cr, data, NULL); - cairo_tag_end(cr, data); + char *buf = (char *) malloc(size + 1); + memcpy(buf, data, size); + buf[size] = '\0'; - cairo_surface_destroy(surface); + flags = CAIRO_PDF_OUTLINE_FLAG_BOLD | CAIRO_PDF_OUTLINE_FLAG_OPEN; + cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_TITLE, buf); + cr = cairo_create(surface); + cairo_tag_begin(cr, buf, NULL); + cairo_tag_end(cr, buf); + + free(buf); cairo_destroy(cr); + cairo_surface_destroy(surface); fuzzer_release_tmpfile(tmpfile); return 0; } diff --git a/fuzzing/raster_fuzzer.c b/fuzzing/raster_fuzzer.c index bd6bdaf54..87224c450 100644 --- a/fuzzing/raster_fuzzer.c +++ b/fuzzing/raster_fuzzer.c @@ -39,14 +39,20 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { w = cairo_image_surface_get_width(surface); h = cairo_image_surface_get_height(surface); - pattern = cairo_pattern_create_raster_source(data, content, w, h); + char *buf = (char *) malloc(size + 1); + memcpy(buf, data, size); + buf[size] = '\0'; + + pattern = cairo_pattern_create_raster_source(buf, content, w, h); cairo_raster_source_pattern_set_acquire (pattern, acquire, release); cairo_set_source(cr, pattern); + cairo_pdf_surface_set_page_label(surface, buf); cairo_paint(cr); cairo_destroy(cr); cairo_pattern_destroy(pattern); cairo_surface_destroy(surface); + free(buf); fuzzer_release_tmpfile(tmpfile); return 0; } diff --git a/fuzzing/text_glyphs_fuzzer.c b/fuzzing/text_glyphs_fuzzer.c index 91a96dc7d..3661799df 100644 --- a/fuzzing/text_glyphs_fuzzer.c +++ b/fuzzing/text_glyphs_fuzzer.c @@ -25,8 +25,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; } + char *buf = (char *) malloc(size + 1); + memcpy(buf, data, size); + buf[size] = '\0'; + cr = cairo_create(surface); - cairo_text_extents(cr, data, &extents); + cairo_text_extents(cr, buf, &extents); cluster.num_bytes = size; cluster.num_glyphs = 1; for (int i = 0; i < 9; i++) { @@ -34,11 +38,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_glyph_t glyph = { index[i], 10 * i, 25 }; - cairo_show_text_glyphs(cr, data, size, &glyph, 1, &cluster, 1, 0); + cairo_show_text_glyphs(cr, buf, size, &glyph, 1, &cluster, 1, 0); } cairo_destroy(cr); cairo_surface_destroy(surface); + free(buf); fuzzer_release_tmpfile(tmpfile); return 0; } From 5f11c36f107a55989be8effb152befa791885de3 Mon Sep 17 00:00:00 2001 From: Ceyhun Alp Date: Sun, 22 Nov 2020 20:52:30 +0000 Subject: [PATCH 3/8] Remove include boilerplate header - not used --- fuzzing/meson.build | 4 ++-- fuzzing/pdf_surface_fuzzer.c | 2 +- fuzzing/raster_fuzzer.c | 4 +++- fuzzing/surface_write_png_fuzzer.c | 2 +- fuzzing/text_glyphs_fuzzer.c | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/fuzzing/meson.build b/fuzzing/meson.build index a18feb27c..282dc34de 100644 --- a/fuzzing/meson.build +++ b/fuzzing/meson.build @@ -9,9 +9,9 @@ fuzz_args = ['-fsanitize=fuzzer,address'] foreach target_name : fuzz_targets exe = executable(target_name, [target_name + '.c'], - include_directories: [incbase, incsrc, incboilerplate, incpdiff, inccairoscript, inccairomissing], + include_directories: [incbase, incsrc], c_args: [fuzz_args, '-DHAVE_CONFIG_H'], - link_with: [libcairo, libcairoboilerplate, libpdiff], + link_with: [libcairo], link_args: [fuzz_args, extra_link_args], dependencies: [deps, test_deps], ) diff --git a/fuzzing/pdf_surface_fuzzer.c b/fuzzing/pdf_surface_fuzzer.c index aafc51c13..ead58b3ee 100644 --- a/fuzzing/pdf_surface_fuzzer.c +++ b/fuzzing/pdf_surface_fuzzer.c @@ -1,5 +1,5 @@ +#include #include -#include "cairo-boilerplate.h" #include "fuzzer_temp_file.h" #define WIDTH_IN_INCHES 3 diff --git a/fuzzing/raster_fuzzer.c b/fuzzing/raster_fuzzer.c index 87224c450..d8c53bbf5 100644 --- a/fuzzing/raster_fuzzer.c +++ b/fuzzing/raster_fuzzer.c @@ -1,4 +1,5 @@ -#include "cairo-boilerplate.h" +#include +#include #include "fuzzer_temp_file.h" #define WIDTH 200 @@ -47,6 +48,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_raster_source_pattern_set_acquire (pattern, acquire, release); cairo_set_source(cr, pattern); cairo_pdf_surface_set_page_label(surface, buf); + cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_KEYWORDS, buf); cairo_paint(cr); cairo_destroy(cr); diff --git a/fuzzing/surface_write_png_fuzzer.c b/fuzzing/surface_write_png_fuzzer.c index c29bc5adb..b7527bd36 100644 --- a/fuzzing/surface_write_png_fuzzer.c +++ b/fuzzing/surface_write_png_fuzzer.c @@ -1,4 +1,4 @@ -#include "cairo-boilerplate.h" +#include #include "fuzzer_temp_file.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { diff --git a/fuzzing/text_glyphs_fuzzer.c b/fuzzing/text_glyphs_fuzzer.c index 3661799df..ae5586f75 100644 --- a/fuzzing/text_glyphs_fuzzer.c +++ b/fuzzing/text_glyphs_fuzzer.c @@ -1,4 +1,4 @@ -#include "cairo-boilerplate.h" +#include #include "fuzzer_temp_file.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { From 8c6d1628ed5270f6a49e793256d4c8c7ec0f7401 Mon Sep 17 00:00:00 2001 From: Ceyhun Alp Date: Tue, 24 Nov 2020 23:06:51 +0000 Subject: [PATCH 4/8] Change free and surface_destroy order --- fuzzing/pdf_surface_fuzzer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzzing/pdf_surface_fuzzer.c b/fuzzing/pdf_surface_fuzzer.c index ead58b3ee..d6c698dc0 100644 --- a/fuzzing/pdf_surface_fuzzer.c +++ b/fuzzing/pdf_surface_fuzzer.c @@ -31,9 +31,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_tag_begin(cr, buf, NULL); cairo_tag_end(cr, buf); - free(buf); cairo_destroy(cr); cairo_surface_destroy(surface); + free(buf); fuzzer_release_tmpfile(tmpfile); return 0; } From 69c93dd259daf8ff2eb5945eba1d9f811ad325b9 Mon Sep 17 00:00:00 2001 From: Ceyhun Alp Date: Thu, 26 Nov 2020 15:09:38 +0000 Subject: [PATCH 5/8] Change malloc to calloc. Randomize glyphs --- fuzzing/pdf_surface_fuzzer.c | 4 +--- fuzzing/raster_fuzzer.c | 2 +- fuzzing/text_glyphs_fuzzer.c | 18 +++++++----------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/fuzzing/pdf_surface_fuzzer.c b/fuzzing/pdf_surface_fuzzer.c index d6c698dc0..33cb0e08b 100644 --- a/fuzzing/pdf_surface_fuzzer.c +++ b/fuzzing/pdf_surface_fuzzer.c @@ -11,7 +11,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_t *cr; cairo_surface_t *surface; cairo_status_t status; - int flags; char *tmpfile = fuzzer_get_tmpfile(data, size); surface = cairo_pdf_surface_create(tmpfile, WIDTH_IN_POINTS, HEIGHT_IN_POINTS); @@ -21,11 +20,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; } - char *buf = (char *) malloc(size + 1); + char *buf = (char *) calloc(size + 1, sizeof(char)); memcpy(buf, data, size); buf[size] = '\0'; - flags = CAIRO_PDF_OUTLINE_FLAG_BOLD | CAIRO_PDF_OUTLINE_FLAG_OPEN; cairo_pdf_surface_set_metadata(surface, CAIRO_PDF_METADATA_TITLE, buf); cr = cairo_create(surface); cairo_tag_begin(cr, buf, NULL); diff --git a/fuzzing/raster_fuzzer.c b/fuzzing/raster_fuzzer.c index d8c53bbf5..797d4e7c1 100644 --- a/fuzzing/raster_fuzzer.c +++ b/fuzzing/raster_fuzzer.c @@ -40,7 +40,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { w = cairo_image_surface_get_width(surface); h = cairo_image_surface_get_height(surface); - char *buf = (char *) malloc(size + 1); + char *buf = (char *) calloc(size + 1, sizeof(char)); memcpy(buf, data, size); buf[size] = '\0'; diff --git a/fuzzing/text_glyphs_fuzzer.c b/fuzzing/text_glyphs_fuzzer.c index ae5586f75..60d752934 100644 --- a/fuzzing/text_glyphs_fuzzer.c +++ b/fuzzing/text_glyphs_fuzzer.c @@ -1,22 +1,18 @@ #include #include "fuzzer_temp_file.h" +#define GLYPH_RANGE 9 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size < GLYPH_RANGE) { + return 0; + } cairo_t *cr; cairo_surface_t *surface; cairo_status_t status; cairo_text_extents_t extents; cairo_text_cluster_t cluster; - // Taken from test/text-glyph-range.c - long int index[] = { - 0, /* 'no matching glyph' */ - 0xffff, /* kATSDeletedGlyphCode */ - 0x1ffff, /* out of range */ - -1L, /* out of range */ - 70, 68, 76, 85, 82 /* 'cairo' */ - }; - char *tmpfile = fuzzer_get_tmpfile(data, size); surface = cairo_image_surface_create_from_png(tmpfile); status = cairo_surface_status(surface); @@ -25,7 +21,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; } - char *buf = (char *) malloc(size + 1); + char *buf = (char *) calloc(size + 1, sizeof(char)); memcpy(buf, data, size); buf[size] = '\0'; @@ -36,7 +32,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { for (int i = 0; i < 9; i++) { // Taken from test/text-glyph-range.c cairo_glyph_t glyph = { - index[i], 10 * i, 25 + (long int)data[i], 10 * i, 25 }; cairo_show_text_glyphs(cr, buf, size, &glyph, 1, &cluster, 1, 0); } From 707dcab5ba0cc3392a1d95febffe1950cc9838e5 Mon Sep 17 00:00:00 2001 From: Ceyhun Alp Date: Thu, 26 Nov 2020 15:40:28 +0000 Subject: [PATCH 6/8] Replace DEFINEs with consts --- fuzzing/pdf_surface_fuzzer.c | 10 +++++----- fuzzing/raster_fuzzer.c | 3 --- fuzzing/text_glyphs_fuzzer.c | 6 +++--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/fuzzing/pdf_surface_fuzzer.c b/fuzzing/pdf_surface_fuzzer.c index 33cb0e08b..5df3fbef6 100644 --- a/fuzzing/pdf_surface_fuzzer.c +++ b/fuzzing/pdf_surface_fuzzer.c @@ -2,10 +2,10 @@ #include #include "fuzzer_temp_file.h" -#define WIDTH_IN_INCHES 3 -#define HEIGHT_IN_INCHES 3 -#define WIDTH_IN_POINTS (WIDTH_IN_INCHES * 72.0) -#define HEIGHT_IN_POINTS (HEIGHT_IN_INCHES * 72.0) +const double width_in_inches = 3; +const double height_in_inches = 3; +const double width_in_points = width_in_inches * 72.0; +const double height_in_points = height_in_inches * 72.0; int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_t *cr; @@ -13,7 +13,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_status_t status; char *tmpfile = fuzzer_get_tmpfile(data, size); - surface = cairo_pdf_surface_create(tmpfile, WIDTH_IN_POINTS, HEIGHT_IN_POINTS); + surface = cairo_pdf_surface_create(tmpfile, width_in_points, height_in_points); status = cairo_surface_status(surface); if (status != CAIRO_STATUS_SUCCESS) { fuzzer_release_tmpfile(tmpfile); diff --git a/fuzzing/raster_fuzzer.c b/fuzzing/raster_fuzzer.c index 797d4e7c1..2e04f66ce 100644 --- a/fuzzing/raster_fuzzer.c +++ b/fuzzing/raster_fuzzer.c @@ -2,9 +2,6 @@ #include #include "fuzzer_temp_file.h" -#define WIDTH 200 -#define HEIGHT 80 - static cairo_surface_t * acquire (cairo_pattern_t *pattern, void *closure, cairo_surface_t *target, diff --git a/fuzzing/text_glyphs_fuzzer.c b/fuzzing/text_glyphs_fuzzer.c index 60d752934..d23cb88bc 100644 --- a/fuzzing/text_glyphs_fuzzer.c +++ b/fuzzing/text_glyphs_fuzzer.c @@ -1,10 +1,10 @@ #include #include "fuzzer_temp_file.h" -#define GLYPH_RANGE 9 +const int glyph_range = 9; int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - if (size < GLYPH_RANGE) { + if (size < glyph_range) { return 0; } cairo_t *cr; @@ -29,7 +29,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_text_extents(cr, buf, &extents); cluster.num_bytes = size; cluster.num_glyphs = 1; - for (int i = 0; i < 9; i++) { + for (int i = 0; i < glyph_range; i++) { // Taken from test/text-glyph-range.c cairo_glyph_t glyph = { (long int)data[i], 10 * i, 25 From f6949881f66700819f10ad6fcff3e699d025f996 Mon Sep 17 00:00:00 2001 From: Ceyhun Alp Date: Fri, 27 Nov 2020 12:14:28 +0000 Subject: [PATCH 7/8] [Unstable] separate data from glyphs --- fuzzing/text_glyphs_fuzzer.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fuzzing/text_glyphs_fuzzer.c b/fuzzing/text_glyphs_fuzzer.c index d23cb88bc..051f4891f 100644 --- a/fuzzing/text_glyphs_fuzzer.c +++ b/fuzzing/text_glyphs_fuzzer.c @@ -12,18 +12,23 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_status_t status; cairo_text_extents_t extents; cairo_text_cluster_t cluster; + size_t new_size = size - glyph_range; + uint8_t *new_data = (uint8_t *) calloc(new_size, sizeof(uint8_t)); + /*memcpy(new_data, &data[glyph_range], new_size*sizeof(uint8_t));*/ + memcpy(new_data, data, new_size * sizeof(uint8_t)); - char *tmpfile = fuzzer_get_tmpfile(data, size); + char *tmpfile = fuzzer_get_tmpfile(new_data, new_size); surface = cairo_image_surface_create_from_png(tmpfile); status = cairo_surface_status(surface); if (status != CAIRO_STATUS_SUCCESS) { + free(new_data); fuzzer_release_tmpfile(tmpfile); return 0; } - char *buf = (char *) calloc(size + 1, sizeof(char)); - memcpy(buf, data, size); - buf[size] = '\0'; + char *buf = (char *) calloc(new_size + 1, sizeof(char)); + memcpy(buf, new_data, new_size); + buf[new_size] = '\0'; cr = cairo_create(surface); cairo_text_extents(cr, buf, &extents); @@ -39,6 +44,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_destroy(cr); cairo_surface_destroy(surface); + free(new_data); free(buf); fuzzer_release_tmpfile(tmpfile); return 0; From 6069322cefca71f0a716cf5e3d5efcc2c927e1a5 Mon Sep 17 00:00:00 2001 From: Ceyhun Alp Date: Fri, 27 Nov 2020 16:00:47 +0000 Subject: [PATCH 8/8] License header --- fuzzing/pdf_surface_fuzzer.c | 14 ++++++++++++++ fuzzing/raster_fuzzer.c | 14 ++++++++++++++ fuzzing/surface_write_png_fuzzer.c | 14 ++++++++++++++ fuzzing/text_glyphs_fuzzer.c | 18 ++++++++++++++++-- 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/fuzzing/pdf_surface_fuzzer.c b/fuzzing/pdf_surface_fuzzer.c index 5df3fbef6..7869f6371 100644 --- a/fuzzing/pdf_surface_fuzzer.c +++ b/fuzzing/pdf_surface_fuzzer.c @@ -1,3 +1,17 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include #include "fuzzer_temp_file.h" diff --git a/fuzzing/raster_fuzzer.c b/fuzzing/raster_fuzzer.c index 2e04f66ce..e7f9bc199 100644 --- a/fuzzing/raster_fuzzer.c +++ b/fuzzing/raster_fuzzer.c @@ -1,3 +1,17 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include #include "fuzzer_temp_file.h" diff --git a/fuzzing/surface_write_png_fuzzer.c b/fuzzing/surface_write_png_fuzzer.c index b7527bd36..9819fa287 100644 --- a/fuzzing/surface_write_png_fuzzer.c +++ b/fuzzing/surface_write_png_fuzzer.c @@ -1,3 +1,17 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include "fuzzer_temp_file.h" diff --git a/fuzzing/text_glyphs_fuzzer.c b/fuzzing/text_glyphs_fuzzer.c index 051f4891f..5cc2b03d7 100644 --- a/fuzzing/text_glyphs_fuzzer.c +++ b/fuzzing/text_glyphs_fuzzer.c @@ -1,3 +1,17 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include "fuzzer_temp_file.h" @@ -14,8 +28,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { cairo_text_cluster_t cluster; size_t new_size = size - glyph_range; uint8_t *new_data = (uint8_t *) calloc(new_size, sizeof(uint8_t)); - /*memcpy(new_data, &data[glyph_range], new_size*sizeof(uint8_t));*/ - memcpy(new_data, data, new_size * sizeof(uint8_t)); + // Skip first glyph_range number of bytes + memcpy(new_data, &data[glyph_range], new_size * sizeof(uint8_t)); char *tmpfile = fuzzer_get_tmpfile(new_data, new_size); surface = cairo_image_surface_create_from_png(tmpfile);