[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:
parent
261a605f9c
commit
deca30b268
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue