Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP3:GA
libplist.4090
0021-Fix-OOB-write-on-heap-buffer-and-improve-r...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0021-Fix-OOB-write-on-heap-buffer-and-improve-recursion-check.patch of Package libplist.4090
From c4dcf11b533b1b604216edb295e4f50a6085650f Mon Sep 17 00:00:00 2001 From: Nikias Bassen <nikias@gmx.li> Date: Sat, 4 Feb 2017 02:51:03 +0100 Subject: [PATCH] bplist: Fix OOB write on heap buffer and improve recursion check Issue #92 pointed out an problem with (invalid) bplist files which have exactly one structured node whose subnode reference itself. The recursion check used a fixed size array with the size of the total number of objects. In this case the number of objects is 1 but the recursion check code wanted to set the node_index for the level 1 which leads to an OOB write on the heap. This commit fixes/improves two things: 1) Prevent OOB write by using a dynamic data storage for the used node indexes (plist_t of type PLIST_ARRAY) 2) Reduces the memory usage of large binary plists, because not the total number of nodes in the binary plist, but the number of recursion levels is important for the recursion check. --- src/bplist.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/bplist.c b/src/bplist.c index 0cfe5fe..d2a1ccb 100644 --- a/src/bplist.c +++ b/src/bplist.c @@ -187,7 +187,7 @@ struct bplist_data { uint8_t offset_size; const char* offset_table; uint32_t level; - uint32_t *used_indexes; + plist_t used_indexes; }; static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node_index); @@ -645,11 +645,20 @@ static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node } /* store node_index for current recursion level */ - bplist->used_indexes[bplist->level] = node_index; + if (plist_array_get_size(bplist->used_indexes) < bplist->level+1) { + while (plist_array_get_size(bplist->used_indexes) < bplist->level+1) { + plist_array_append_item(bplist->used_indexes, plist_new_uint(node_index)); + } + } else { + plist_array_set_item(bplist->used_indexes, plist_new_uint(node_index), bplist->level); + } + /* recursion check */ if (bplist->level > 0) { for (i = bplist->level-1; i >= 0; i--) { - if (bplist->used_indexes[i] == bplist->used_indexes[bplist->level]) { + plist_t node_i = plist_array_get_item(bplist->used_indexes, i); + plist_t node_level = plist_array_get_item(bplist->used_indexes, bplist->level); + if (plist_compare_node_value(node_i, node_level)) { fprintf(stderr, "Recursion detected in binary plist. Aborting.\n"); return NULL; } @@ -709,9 +718,6 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * if (offset_table + num_objects * offset_size >= plist_bin + length) return; - if (sizeof(uint32_t) * num_objects < num_objects) - return; - struct bplist_data bplist; bplist.data = plist_bin; bplist.size = length; @@ -720,14 +726,14 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * bplist.offset_size = offset_size; bplist.offset_table = offset_table; bplist.level = 0; - bplist.used_indexes = (uint32_t*)malloc(sizeof(uint32_t) * num_objects); + bplist.used_indexes = plist_new_array(); if (!bplist.used_indexes) return; *plist = parse_bin_node_at_index(&bplist, root_object); - free(bplist.used_indexes); + plist_free(bplist.used_indexes); } static unsigned int plist_data_hash(const void* key)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor