[repacker] get repacker fuzzer working.

Additionally add helper method that allows a graph to be saved as a fuzzer seed.
This commit is contained in:
Garret Rieger 2022-09-08 21:10:06 +00:00
parent 261a605f9c
commit deca30b268
3 changed files with 60 additions and 5 deletions

View File

@ -953,6 +953,56 @@ struct graph_t
return true; return true;
} }
#if 0
/*
* Saves the current graph to a packed binary format which the repacker fuzzer takes
* as a seed.
*/
void save_fuzzer_seed (hb_tag_t tag) const
{
FILE* f = fopen ("./repacker_fuzzer_seed", "w");
fwrite ((void*) &tag, sizeof (tag), 1, f);
uint16_t num_objects = vertices_.length;
fwrite ((void*) &num_objects, sizeof (num_objects), 1, f);
for (const auto& v : vertices_)
{
uint16_t blob_size = v.table_size ();
fwrite ((void*) &blob_size, sizeof (blob_size), 1, f);
fwrite ((const void*) v.obj.head, blob_size, 1, f);
}
uint16_t link_count = 0;
for (const auto& v : vertices_)
link_count += v.obj.real_links.length;
fwrite ((void*) &link_count, sizeof (link_count), 1, f);
typedef struct
{
uint16_t parent;
uint16_t child;
uint16_t position;
uint8_t width;
} link_t;
for (unsigned i = 0; i < vertices_.length; i++)
{
for (const auto& l : vertices_[i].obj.real_links)
{
link_t link {
(uint16_t) i, (uint16_t) l.objidx,
(uint16_t) l.position, (uint8_t) l.width
};
fwrite ((void*) &link, sizeof (link), 1, f);
}
}
fclose (f);
}
#endif
void print_orphaned_nodes () void print_orphaned_nodes ()
{ {
if (!DEBUG_ENABLED(SUBSET_REPACK)) return; if (!DEBUG_ENABLED(SUBSET_REPACK)) return;

View File

@ -378,7 +378,7 @@ hb_resolve_overflows (const T& packed,
graph_t sorted_graph (packed); graph_t sorted_graph (packed);
if (!sorted_graph.is_fully_connected ()) if (!sorted_graph.is_fully_connected ())
{ {
DEBUG_MSG (SUBSET_REPACK, nullptr, "Input graph is not fully connected."); sorted_graph.print_orphaned_nodes ();
return nullptr; return nullptr;
} }

View File

@ -31,7 +31,10 @@ bool read(const uint8_t** data, size_t* size, T* out)
void cleanup (hb_object_t* objects, uint16_t num_objects) void cleanup (hb_object_t* objects, uint16_t num_objects)
{ {
for (uint32_t i = 0; i < num_objects; i++) for (uint32_t i = 0; i < num_objects; i++)
{
free (objects[i].head);
free (objects[i].real_links); free (objects[i].real_links);
}
} }
void add_links_to_objects (hb_object_t* objects, uint16_t num_objects, void add_links_to_objects (hb_object_t* objects, uint16_t num_objects,
@ -56,7 +59,7 @@ void add_links_to_objects (hb_object_t* objects, uint16_t num_objects,
for (uint32_t i = 0; i < num_links; i++) for (uint32_t i = 0; i < num_links; i++)
{ {
uint16_t parent_idx = links[i].parent; uint16_t parent_idx = links[i].parent;
uint16_t child_idx = links[i].child; uint16_t child_idx = links[i].child + 1; // All indices are shifted by 1 by the null object.
hb_link_t* link = &(objects[parent_idx].real_links[link_count[parent_idx] - 1]); hb_link_t* link = &(objects[parent_idx].real_links[link_count[parent_idx] - 1]);
link->width = links[i].width; link->width = links[i].width;
@ -89,8 +92,10 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
if (!read<uint16_t> (&data, &size, &blob_size)) goto end; if (!read<uint16_t> (&data, &size, &blob_size)) goto end;
if (size < blob_size) goto end; if (size < blob_size) goto end;
objects[i].head = (char*) data; char* copy = (char*) calloc (1, blob_size);
objects[i].tail = (char*) (data + blob_size); memcpy (copy, data, blob_size);
objects[i].head = (char*) copy;
objects[i].tail = (char*) (copy + blob_size);
size -= blob_size; size -= blob_size;
data += blob_size; data += blob_size;
@ -103,7 +108,7 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
if (!read<link_t> (&data, &size, &links[i])) goto end; if (!read<link_t> (&data, &size, &links[i])) goto end;
if (links[i].parent >= num_objects if (links[i].parent >= num_objects
|| links[i].child >= links[i].parent) // Enforces DAG graph || links[i].child > links[i].parent) // Enforces DAG graph
goto end; goto end;
if (links[i].width < 2 || links[i].width > 4) goto end; if (links[i].width < 2 || links[i].width > 4) goto end;