Skip to content

Commit

Permalink
Fixed all leaks in XML parsing, libudev and used buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
abozhinov444 committed Oct 24, 2019
1 parent 5895388 commit 190ccba
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 19 deletions.
30 changes: 22 additions & 8 deletions firehose.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ static void firehose_response_log(xmlNode *node)

value = xmlGetProp(node, (xmlChar*)"value");
printf("LOG: %s\n", value);

xmlFree(value);
}

static int firehose_read(struct qdl_device *qdl, int wait, int (*response_parser)(xmlNode *node))
Expand Down Expand Up @@ -153,8 +155,7 @@ static int firehose_read(struct qdl_device *qdl, int wait, int (*response_parser
for (node = nodes; node; node = node->next) {
if (xmlStrcmp(node->name, (xmlChar*)"log") == 0) {
firehose_response_log(node);
}
else if (xmlStrcmp(node->name, (xmlChar*)"response") == 0) {
} else if (xmlStrcmp(node->name, (xmlChar*)"response") == 0) {
if (!response_parser)
fprintf(stderr, "received response with no parser\n");
else
Expand Down Expand Up @@ -195,9 +196,14 @@ static int firehose_write(struct qdl_device *qdl, xmlDoc *doc)
static int firehose_nop_parser(xmlNode *node)
{
xmlChar *value;
int ret;

value = xmlGetProp(node, (xmlChar*)"value");
return !!xmlStrcmp(value, (xmlChar*)"ACK");
ret = !!xmlStrcmp(value, (xmlChar*)"ACK");

xmlFree(value);

return ret;
}

static size_t max_payload_size = 1048576;
Expand All @@ -215,9 +221,14 @@ static int firehose_configure_response_parser(xmlNode *node)
size_t max_size;

value = xmlGetProp(node, (xmlChar*)"value");
if (!value)
return -EINVAL;

payload = xmlGetProp(node, (xmlChar*)"MaxPayloadSizeToTargetInBytes");
if (!value || !payload)
if (!payload) {
xmlFree(value);
return -EINVAL;
}

max_size = strtoul((char*)payload, NULL, 10);

Expand All @@ -226,13 +237,17 @@ static int firehose_configure_response_parser(xmlNode *node)
* a larger payload size
*/
if (!xmlStrcmp(value, (xmlChar*)"ACK")) {
xmlFree(payload);
payload = xmlGetProp(node, (xmlChar*)"MaxPayloadSizeToTargetInBytesSupported");
if (!payload)
return -EINVAL;

max_size = strtoul((char*)payload, NULL, 10);
}

xmlFree(payload);
xmlFree(value);

return max_size;
}

Expand Down Expand Up @@ -380,8 +395,7 @@ static int firehose_program(struct qdl_device *qdl, struct program *program, int
sparse_cb_info.total_write_count = sparse_file_len(s_file, false);

num_sectors = (sparse_cb_info.total_write_count + program->sector_size - 1) / program->sector_size;
}
else {
} else {
num_sectors = (sb.st_size + program->sector_size - 1) / program->sector_size;
}

Expand Down Expand Up @@ -432,8 +446,7 @@ static int firehose_program(struct qdl_device *qdl, struct program *program, int
ret = sparse_stream_callback(s_file, false, firehose_program_sparse, &sparse_cb_info);

sparse_file_destroy(s_file);
}
else {
} else {
left = num_sectors;
while (left > 0) {
chunk_size = MIN(max_payload_size / program->sector_size, left);
Expand Down Expand Up @@ -473,6 +486,7 @@ static int firehose_program(struct qdl_device *qdl, struct program *program, int

out:
xmlFreeDoc(doc);
free(buf);
return ret;
}

Expand Down
25 changes: 25 additions & 0 deletions patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,28 @@ int patch_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, s

return 0;
}

void patch_unload(void)
{
struct patch *patch;

patches_last = NULL;

for (patch = patches; patch; patch = patch->next) {
if (patch->filename)
xmlFree(patch->filename);
if (patch->start_sector)
xmlFree(patch->start_sector);
if (patch->value)
xmlFree(patch->value);
if (patch->what)
xmlFree(patch->what);

if (patches_last)
free(patches_last);

patches_last = patch;
}

free(patches_last);
}
1 change: 1 addition & 0 deletions patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct patch {
};

int patch_load(const char *patch_file);
void patch_unload(void);
int patch_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct patch *patch));

#endif
23 changes: 23 additions & 0 deletions program.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,26 @@ int program_find_bootable_partition(void)

return part;
}

void program_unload(void)
{
struct program *program;

programes_last = NULL;

for (program = programes; program; program = program->next) {
if (program->filename)
xmlFree(program->filename);
if (program->start_sector)
xmlFree(program->start_sector);
if (program->label)
xmlFree(program->label);

if (programes_last)
free(programes_last);

programes_last = program;
}

free(programes_last);
}
1 change: 1 addition & 0 deletions program.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct program {
};

int program_load(const char *program_file);
void program_unload(void);
int program_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct program *program, int fd),
const char *incdir);
int program_find_bootable_partition(void);
Expand Down
28 changes: 24 additions & 4 deletions qdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,17 +265,23 @@ static int usb_open(struct qdl_device *qdl)
dev = udev_device_new_from_syspath(udev, path);
dev_node = udev_device_get_devnode(dev);

if (!dev_node)
if (!dev_node) {
udev_device_unref(dev);
continue;
}

fd = open(dev_node, O_RDWR);
if (fd < 0)
if (fd < 0) {
udev_device_unref(dev);
continue;
}

ret = parse_usb_desc(fd, qdl, &intf);
if (!ret)
goto found;

udev_device_unref(dev);

close(fd);
}

Expand All @@ -297,19 +303,25 @@ static int usb_open(struct qdl_device *qdl)
dev = udev_monitor_receive_device(mon);
dev_node = udev_device_get_devnode(dev);

if (!dev_node)
if (!dev_node) {
udev_device_unref(dev);
continue;
}

printf("%s\n", dev_node);

fd = open(dev_node, O_RDWR);
if (fd < 0)
if (fd < 0) {
udev_device_unref(dev);
continue;
}

ret = parse_usb_desc(fd, qdl, &intf);
if (!ret)
goto found;

udev_device_unref(dev);

close(fd);
}

Expand All @@ -323,6 +335,7 @@ static int usb_open(struct qdl_device *qdl)
udev_enumerate_unref(enumerate);
udev_monitor_unref(mon);
udev_unref(udev);
udev_device_unref(dev);

cmd.ifno = intf;
cmd.ioctl_code = USBDEVFS_DISCONNECT;
Expand Down Expand Up @@ -464,6 +477,8 @@ int main(int argc, char **argv)

prog_mbn = argv[optind++];

xmlInitParser();

do {
type = detect_type(argv[optind]);
if (type < 0 || type == QDL_FILE_UNKNOWN)
Expand Down Expand Up @@ -503,5 +518,10 @@ int main(int argc, char **argv)
if (ret < 0)
return 1;

ufs_unload();
program_unload();
patch_unload();
xmlCleanupParser();

return 0;
}
4 changes: 2 additions & 2 deletions sahara.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ static int sahara_done(struct qdl_device *qdl, struct sahara_pkt *pkt)

int sahara_run(struct qdl_device *qdl, char *prog_mbn)
{
struct sahara_pkt *pkt;
char buf[4096];
struct sahara_pkt *pkt = NULL;
char buf[4096] = {0};
char tmp[32];
bool done = false;
int n;
Expand Down
19 changes: 19 additions & 0 deletions ufs.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,22 @@ int ufs_provisioning_execute(struct qdl_device *qdl,
}
return apply_ufs_epilogue(qdl, ufs_epilogue_p, true);
}

void ufs_unload(void)
{
struct ufs_body *body;

ufs_body_last = NULL;

for (body = ufs_body_p; body; body = body->next) {
if (body->desc)
xmlFree(body->desc);

if (ufs_body_last)
free(ufs_body_last);

ufs_body_last = body;
}

free(ufs_body_last);
}
17 changes: 12 additions & 5 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,28 +84,35 @@ void print_hex_dump(const char *prefix, const void *buf, size_t len)
unsigned int attr_as_unsigned(xmlNode *node, const char *attr, int *errors)
{
xmlChar *value;
unsigned int ret;

value = xmlGetProp(node, (xmlChar*)attr);
value = xmlGetProp(node, (xmlChar *) attr);
if (!value) {
(*errors)++;
return 0;
}

return (unsigned int) strtoul((char*)value, NULL, 10);
ret = (unsigned int) strtoul((const char*)value, NULL, 10);

xmlFree(value);

return ret;
}

xmlChar *attr_as_string(xmlNode *node, const char *attr, int *errors)
{
xmlChar *value;

value = xmlGetProp(node, (xmlChar*)attr);
value = xmlGetProp(node, (xmlChar *) attr);
if (!value) {
(*errors)++;
return NULL;
}

if (value[0] == '\0')
if (value[0] == '\0') {
xmlFree(value);
return NULL;
}

return strdup((char*)value);
return value;
}

0 comments on commit 190ccba

Please sign in to comment.