Skip to content

Commit ff592b7

Browse files
authored
Merge pull request #161 from igoropaniuk/memleaks_sec_issues
Address memory leaks/mitigate buffer overflows
2 parents f1fc7ad + d192ab7 commit ff592b7

File tree

6 files changed

+54
-16
lines changed

6 files changed

+54
-16
lines changed

firehose.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,8 @@ static int firehose_try_configure(struct qdl_device *qdl, bool skip_storage_init
370370

371371
if (storage != QDL_STORAGE_NAND) {
372372
max_sector_size = sector_sizes[ARRAY_SIZE(sector_sizes) - 1];
373-
buf = malloc(max_sector_size);
373+
buf = alloca(max_sector_size);
374+
374375
memset(&op, 0, sizeof(op));
375376
op.partition = 0;
376377
op.start_sector = "1";

gpt.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <assert.h>
1212
#include <dirent.h>
1313
#include <fcntl.h>
14+
#include <inttypes.h>
1415
#include <stdbool.h>
1516
#include <stdint.h>
1617
#include <unistd.h>
@@ -140,8 +141,8 @@ static int gpt_load_table_from_partition(struct qdl_device *qdl, unsigned int ph
140141
uint8_t buf[4096];
141142
struct read_op op;
142143
unsigned int offset;
143-
unsigned int lba;
144-
char lba_buf[10];
144+
uint64_t lba;
145+
char lba_buf[21];
145146
uint16_t name_utf16le[36];
146147
char name[36 * 4];
147148
int ret;
@@ -178,7 +179,7 @@ static int gpt_load_table_from_partition(struct qdl_device *qdl, unsigned int ph
178179

179180
if (offset == 0) {
180181
lba = gpt.part_entry_lba + i * gpt.part_entry_size / qdl->sector_size;
181-
sprintf(lba_buf, "%u", lba);
182+
snprintf(lba_buf, sizeof(lba_buf), "%" PRIu64, lba);
182183
op.start_sector = lba_buf;
183184

184185
memset(buf, 0, sizeof(buf));

qdl.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,14 @@ static uint32_t parse_ascii_hex32(const char *s)
150150
/**
151151
* decode_programmer_archive() - Attempt to decode a programmer CPIO archive
152152
* @blob: Loaded image to be decoded as archive
153-
* @images: List of Sahara images, with @images[0] populated
153+
* @images: List of Sahara images to populate
154154
*
155-
* The single blob provided in @images[0] might be a CPIO archive containing
156-
* Sahara images, in files with names in the format "<id>:<filename>". Load
157-
* each such Sahara image into the relevant spot in the @images array.
155+
* The blob might be a CPIO archive containing Sahara images, in files with
156+
* names in the format "<id>:<filename>". Load each such Sahara image into the
157+
* relevant spot in the @images array.
158158
*
159-
* The original blob (in @images[0]) is freed once it has been consumed.
159+
* The blob is always consumed (freed) on both success and error paths.
160+
* On error, any partially-populated @images entries are also freed.
160161
*
161162
* Returns: 0 if no archive was found, 1 if archive was decoded, -1 on error
162163
*/
@@ -178,13 +179,13 @@ static int decode_programmer_archive(struct sahara_image *blob, struct sahara_im
178179
for (;;) {
179180
if (ptr + sizeof(*hdr) > end) {
180181
ux_err("programmer archive is truncated\n");
181-
return -1;
182+
goto err;
182183
}
183184
hdr = ptr;
184185

185186
if (memcmp(hdr->c_magic, "070701", 6)) {
186187
ux_err("expected cpio header in programmer archive\n");
187-
return -1;
188+
goto err;
188189
}
189190

190191
filesize = parse_ascii_hex32(hdr->c_filesize);
@@ -193,12 +194,12 @@ static int decode_programmer_archive(struct sahara_image *blob, struct sahara_im
193194
ptr += sizeof(*hdr);
194195
if (ptr + namesize > end || ptr + filesize + namesize > end) {
195196
ux_err("programmer archive is truncated\n");
196-
return -1;
197+
goto err;
197198
}
198199

199200
if (namesize > sizeof(name)) {
200201
ux_err("unexpected filename length in progammer archive\n");
201-
return -1;
202+
goto err;
202203
}
203204
memcpy(name, ptr, namesize);
204205

@@ -209,7 +210,7 @@ static int decode_programmer_archive(struct sahara_image *blob, struct sahara_im
209210
id = strtoul(tok, NULL, 0);
210211
if (id == 0 || id >= MAPPING_SZ) {
211212
ux_err("invalid image id \"%s\" in programmer archive\n", tok);
212-
return -1;
213+
goto err;
213214
}
214215

215216
ptr += namesize;
@@ -231,6 +232,13 @@ static int decode_programmer_archive(struct sahara_image *blob, struct sahara_im
231232
blob->len = 0;
232233

233234
return 1;
235+
236+
err:
237+
sahara_images_free(images, MAPPING_SZ);
238+
free(blob->ptr);
239+
blob->ptr = NULL;
240+
blob->len = 0;
241+
return -1;
234242
}
235243

236244
/**
@@ -335,6 +343,10 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *
335343
return 1;
336344

337345
err_free_doc:
346+
sahara_images_free(images, MAPPING_SZ);
347+
free(blob->ptr);
348+
blob->ptr = NULL;
349+
blob->len = 0;
338350
xmlFreeDoc(doc);
339351
free(blob_name_buf);
340352
return -1;
@@ -747,6 +759,9 @@ static int qdl_flash(int argc, char **argv)
747759
vip_gen_finalize(qdl);
748760

749761
qdl_close(qdl);
762+
763+
sahara_images_free(sahara_images, MAPPING_SZ);
764+
750765
free_programs();
751766
free_patches();
752767

qdl.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
#ifndef __QDL_H__
33
#define __QDL_H__
44

5+
#ifdef _WIN32
6+
#include <malloc.h>
7+
#define alloca _alloca
8+
#else
9+
#include <alloca.h>
10+
#endif
11+
512
#include <stdbool.h>
613

714
#include "patch.h"
@@ -72,7 +79,7 @@ struct qdl_device {
7279
};
7380

7481
struct sahara_image {
75-
const char *name;
82+
char *name;
7683
void *ptr;
7784
size_t len;
7885
};
@@ -106,6 +113,7 @@ int sahara_run(struct qdl_device *qdl, const struct sahara_image *images,
106113
const char *ramdump_path,
107114
const char *ramdump_filter);
108115
int load_sahara_image(const char *filename, struct sahara_image *image);
116+
void sahara_images_free(struct sahara_image *images, size_t count);
109117
void print_hex_dump(const char *prefix, const void *buf, size_t len);
110118
unsigned int attr_as_unsigned(xmlNode *node, const char *attr, int *errors);
111119
const char *attr_as_string(xmlNode *node, const char *attr, int *errors);

usb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ static int usb_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int
328328
return -ETIMEDOUT;
329329

330330
/* If what we read equals the endpoint's Max Packet Size, consume the ZLP explicitly */
331-
if (len == actual && !(actual % qdl_usb->in_maxpktsize)) {
331+
if (len == (size_t)actual && !(actual % qdl_usb->in_maxpktsize)) {
332332
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->in_ep,
333333
NULL, 0, NULL, timeout);
334334
if (ret)

util.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,10 @@ int load_sahara_image(const char *filename, struct sahara_image *image)
242242
lseek(fd, 0, SEEK_SET);
243243

244244
ptr = malloc(len);
245+
if (!ptr) {
246+
ux_err("failed to init buffer for content of \"%s\"\n", filename);
247+
goto err_close;
248+
}
245249

246250
n = read(fd, ptr, len);
247251
if (n != len) {
@@ -262,3 +266,12 @@ int load_sahara_image(const char *filename, struct sahara_image *image)
262266
close(fd);
263267
return -1;
264268
}
269+
270+
void sahara_images_free(struct sahara_image *images, size_t count)
271+
{
272+
for (size_t i = 0; i < count; i++) {
273+
free(images[i].name);
274+
free(images[i].ptr);
275+
images[i] = (struct sahara_image){};
276+
}
277+
}

0 commit comments

Comments
 (0)