[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;
}
#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 ()
{
if (!DEBUG_ENABLED(SUBSET_REPACK)) return;

View File

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

View File

@ -31,8 +31,11 @@ bool read(const uint8_t** data, size_t* size, T* out)
void cleanup (hb_object_t* objects, uint16_t num_objects)
{
for (uint32_t i = 0; i < num_objects; i++)
{
free (objects[i].head);
free (objects[i].real_links);
}
}
void add_links_to_objects (hb_object_t* objects, uint16_t num_objects,
link_t* links, uint16_t num_links)
@ -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++)
{
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]);
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 (size < blob_size) goto end;
objects[i].head = (char*) data;
objects[i].tail = (char*) (data + blob_size);
char* copy = (char*) calloc (1, blob_size);
memcpy (copy, data, blob_size);
objects[i].head = (char*) copy;
objects[i].tail = (char*) (copy + blob_size);
size -= 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 (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;
if (links[i].width < 2 || links[i].width > 4) goto end;