From 46750e99d014e1505901c9ee27e34960812a31f2 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 19 Jun 2014 13:27:34 +0200 Subject: local: Fix truncating file --- src/local.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/local.c b/src/local.c index e90011b..499be92 100644 --- a/src/local.c +++ b/src/local.c @@ -457,6 +457,10 @@ int local_dump_image(enum image_type image, const char * file) { if ( addr[nlen-1] != 0xFF ) break; + for ( ; nlen > 0; --nlen ) + if ( addr[nlen-1] != 0x00 ) + break; + if ( image == IMAGE_MMC ) align = 8; else -- cgit v1.2.3 From 23b916bcc9de857a1c88718cc2315813efbcb4e4 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 29 Sep 2014 00:42:52 +0200 Subject: fiasco: Call free at correct place --- src/fiasco.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/fiasco.c b/src/fiasco.c index 721785e..2d22747 100644 --- a/src/fiasco.c +++ b/src/fiasco.c @@ -493,8 +493,10 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { if ( image->layout ) { layout_name = calloc(1, strlen(name) + strlen(".layout") + 1); - if ( ! layout_name ) + if ( ! layout_name ) { + free(name); ALLOC_ERROR_RETURN(-1); + } sprintf(layout_name, "%s.layout", name); @@ -512,8 +514,6 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { } } - free(name); - image_seek(image, 0); while ( 1 ) { size = image_read(image, buf, sizeof(buf)); @@ -522,7 +522,10 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { WRITE_OR_FAIL(name, fd, buf, size); } - close(fd); + free(name); + + if ( ! simulate ) + close(fd); if ( image->layout ) { @@ -534,11 +537,12 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { } } - free(layout_name); - WRITE_OR_FAIL(layout_name, fd, image->layout, (int)strlen(image->layout)); - close(fd); + free(layout_name); + + if ( ! simulate ) + close(fd); } -- cgit v1.2.3 From dfc021d7c416b47576631016ac931271318df268 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 29 Sep 2014 00:43:15 +0200 Subject: image: Fix memory leaks --- src/image.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/image.c b/src/image.c index 44655fb..48d80d8 100644 --- a/src/image.c +++ b/src/image.c @@ -88,14 +88,13 @@ static void image_missing_values_from_name(struct image * image, const char * na if ( image->devices && image->devices->device && ! image->devices->hwrevs ) image->devices->hwrevs = hwrevs_alloc_from_string(hwrevs); - else - free(hwrevs); if ( ! image->version ) image->version = version; else free(version); + free(hwrevs); free(str); } @@ -135,8 +134,10 @@ char * image_name_alloc_from_values(struct image * image) { length += 1 + strlen(image->version); name = calloc(1, length); - if ( ! name ) + if ( ! name ) { + free(hwrevs); ALLOC_ERROR_RETURN(NULL); + } strcpy(name, type); ptr = name + strlen(name); -- cgit v1.2.3 From 4356b2124eafa3c537586bc462d9005ae1efcfa1 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 29 Sep 2014 00:43:54 +0200 Subject: local: Fix memory corruptions --- src/local.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/local.c b/src/local.c index 499be92..4d28833 100644 --- a/src/local.c +++ b/src/local.c @@ -322,8 +322,8 @@ int local_dump_image(enum image_type image, const char * file) { if ( fd < 0 ) continue; - buf[0] = 0; - if ( read(fd, buf, sizeof(buf)) < 0 ) + memset(buf, 0, sizeof(buf)); + if ( read(fd, buf, sizeof(buf)-1) < 0 ) buf[0] = 0; close(fd); @@ -410,7 +410,7 @@ int local_dump_image(enum image_type image, const char * file) { VERBOSE("Detected internal mmc device: '%s'\n", blk); - strncat(blk, "p1", sizeof(blk)); + strncat(blk, "p1", sizeof(blk)-strlen(blk)-1); printf("Using MyDocs mmc device: '%s'\n", blk); -- cgit v1.2.3 From 1610debbd5aa1f9b2754c83968c81b9e4b76c20f Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 29 Sep 2014 00:44:19 +0200 Subject: usb-device: Fix memory leak --- src/usb-device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/usb-device.c b/src/usb-device.c index 039e82e..b0a45bf 100644 --- a/src/usb-device.c +++ b/src/usb-device.c @@ -198,6 +198,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { ERROR("Device mishmash"); fprintf(stderr, "\n"); usb_close(udev); + free(ret); return NULL; } } -- cgit v1.2.3 From 03c6c3899f6b2e1b9f3ff08817ef491eee99286f Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 29 Sep 2014 00:45:17 +0200 Subject: main: Fix memory corruption --- src/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index fdd2b4b..2daf848 100644 --- a/src/main.c +++ b/src/main.c @@ -210,7 +210,7 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) { exit(1); } lseek(fd, 0, SEEK_SET); - layout = malloc(len); + layout = malloc(len+1); if ( ! layout ) { ALLOC_ERROR(); exit(1); @@ -219,6 +219,8 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) { ERROR_INFO("Cannot read %lu bytes from layout file %s", len, layout_file); exit(1); } + layout[len] = 0; + close(fd); } image = image_alloc_from_file(file, type, device, hwrevs, version, layout); -- cgit v1.2.3 From 84fc04f647d425a38f3e5f0a77def3ab346520bd Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 29 Sep 2014 00:48:13 +0200 Subject: main: Implement -t (filter by type) for -e (dump images) --- src/main.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 2daf848..6aa4870 100644 --- a/src/main.c +++ b/src/main.c @@ -1177,9 +1177,21 @@ int main(int argc, char **argv) { buf[0] = 0; } - for ( i = 0; i < IMAGE_COUNT; ++i ) - if ( image_tmp_name(i) ) - dev_dump_image(dev, i, image_tmp_name(i)); + if ( filter_type ) { + enum image_type type = image_type_from_string(filter_type_arg); + if ( ! type || ! image_tmp_name(type) ) { + ERROR("Specified unknown image type for filtering: %s", filter_type_arg); + ret = 1; + goto clean; + } + ret = dev_dump_image(dev, type, image_tmp_name(type)); + if ( ret != 0 ) + goto clean; + } else { + for ( i = 0; i < IMAGE_COUNT; ++i ) + if ( image_tmp_name(i) ) + dev_dump_image(dev, i, image_tmp_name(i)); + } if ( buf[0] ) if ( chdir(buf) < 0 ) -- cgit v1.2.3 From c88e5264c979a10efe6d2209393c8df248ffc5bd Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 29 Sep 2014 00:48:37 +0200 Subject: main: Update usage --- src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 6aa4870..041299d 100644 --- a/src/main.c +++ b/src/main.c @@ -53,8 +53,8 @@ static void show_usage(void) { " -f flash all specified images\n" " -c cold flash 2nd and secondary images\n" " -x [/dev/mtd] check for bad blocks on mtd device (default: all)\n" - " -E file dump all device images to one fiasco image, see -t\n" - " -e [dir] dump all device images to directory, see -t (default: current)\n" + " -E file dump all device images to one fiasco image\n" + " -e [dir] dump all device images (or one -t) to directory (default: current)\n" "\n" "Device configuration:\n" @@ -84,7 +84,7 @@ static void show_usage(void) { "\n" "Image filters:\n" - " -t types filter images by type\n" + " -t type filter images by type\n" " -d dev filter images by device\n" " -w hw filter images by HW revision\n" "\n" -- cgit v1.2.3 From d6eba113578b653cd752018a2c509dbdd2eca1a6 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 19 Oct 2014 18:26:47 +0200 Subject: fiasco: fiasco_alloc_from_file: check if hwrevs has enough size --- src/fiasco.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/fiasco.c b/src/fiasco.c index 2d22747..0c404bc 100644 --- a/src/fiasco.c +++ b/src/fiasco.c @@ -192,9 +192,12 @@ struct fiasco * fiasco_alloc_from_file(const char * file) { if ( ! hwrevs[0] ) strcpy(hwrevs, hwrev); else { - /* TODO: check if hwrevs has enough size */ - strcat(hwrevs, ","); - strcat(hwrevs, hwrev); + size_t len1 = strlen(hwrevs); + size_t len2 = strlen(hwrev); + if ( len1 + len2 + 2 < sizeof(hwrevs) ) { + hwrevs[len1] = ','; + memcpy(hwrevs+len1+1, hwrev, len2+1); + } } VERBOSE(" hw revision: %s\n", hwrev); pbuf += strlen(hwrev) + 1; -- cgit v1.2.3 From b1564909d79b79e5e33b355a803d25bc3dc8bafa Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 19 Oct 2014 20:17:06 +0200 Subject: nolo: Fix size of snprintf buffer --- src/nolo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nolo.c b/src/nolo.c index 238336d..e247698 100644 --- a/src/nolo.c +++ b/src/nolo.c @@ -311,7 +311,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i if ( bufs ) { memset(buf, 0, sizeof(buf)); - snprintf(buf, 8, "%d", dev->hwrev); + snprintf(buf, 8+1, "%d", dev->hwrev); for ( i = 0; bufs[i]; ++i ) { len = ((uint8_t*)bufs[i])[0]; @@ -763,7 +763,7 @@ int nolo_set_hwrev(struct usb_device_info * dev, int16_t hwrev) { char buf[9]; memset(buf, 0, sizeof(buf)); - snprintf(buf, 8, "%d", hwrev); + snprintf(buf, sizeof(buf), "%d", hwrev); printf("Setting HW revision to: %s\n", buf); return nolo_set_string(dev, "hw_rev", buf); -- cgit v1.2.3 From 9a1f63c5aed6e197033747e64d85e471aea3402f Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 19 Oct 2014 20:17:29 +0200 Subject: nolo: Check return value of sprintf --- src/nolo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nolo.c b/src/nolo.c index e247698..9ba5a06 100644 --- a/src/nolo.c +++ b/src/nolo.c @@ -176,7 +176,8 @@ static int nolo_get_version_string(struct usb_device_info * dev, const char * st if ( strlen(str) > 500 ) return -1; - sprintf(buf, "version:%s", str); + if ( sprintf(buf, "version:%s", str) <= 0 ) + return -1; ret = nolo_get_string(dev, buf, out, size); -- cgit v1.2.3 From a8986bf631aff030483c695bfb1eed1584e73677 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 19 Oct 2014 20:18:02 +0200 Subject: local: Check return value of snprintf --- src/local.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/local.c b/src/local.c index 4d28833..86d3b78 100644 --- a/src/local.c +++ b/src/local.c @@ -316,7 +316,8 @@ int local_dump_image(enum image_type image, const char * file) { while ( ( dirent = readdir(dir) ) ) { - snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/slot_name", dirent->d_name); + if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/slot_name", dirent->d_name) <= 0 ) + continue; fd = open(buf, O_RDONLY); if ( fd < 0 ) @@ -330,7 +331,8 @@ int local_dump_image(enum image_type image, const char * file) { if ( strncmp(buf, "internal", strlen("internal")) != 0 ) continue; - snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/", dirent->d_name, dirent->d_name); + if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/", dirent->d_name, dirent->d_name) <= 0 ) + continue; dir2 = opendir(buf); if ( ! dir2 ) @@ -341,7 +343,8 @@ int local_dump_image(enum image_type image, const char * file) { if ( strncmp(dirent2->d_name, "block:mmcblk", strlen("block:mmcblk")) != 0 ) continue; - snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/%s/dev", dirent->d_name, dirent->d_name, dirent2->d_name); + if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/%s/dev", dirent->d_name, dirent->d_name, dirent2->d_name) <= 0 ) + continue; f = fopen(buf, "r"); if ( ! f ) @@ -385,7 +388,8 @@ int local_dump_image(enum image_type image, const char * file) { while ( ( dirent = readdir(dir) ) ) { - snprintf(buf, sizeof(buf), "/dev/%s", dirent->d_name); + if ( snprintf(buf, sizeof(buf), "/dev/%s", dirent->d_name) <= 0 ) + continue; if ( stat(buf, &st) != 0 ) continue; -- cgit v1.2.3 From 8d52950ede71561d1f266833f06e747b7d6e0768 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 19 Oct 2014 20:18:47 +0200 Subject: main: Use snprintf instead sprintf and initialize buffer to NULL term --- src/main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 041299d..ff99dc3 100644 --- a/src/main.c +++ b/src/main.c @@ -1210,7 +1210,8 @@ int main(int argc, char **argv) { if ( ! image_tmp_name(i) ) continue; - sprintf(buf, "%hd", dev->detected_hwrev); + buf[0] = 0; + snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev); switch ( i ) { case IMAGE_2ND: @@ -1312,14 +1313,16 @@ int main(int argc, char **argv) { break; } - sprintf(buf, "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr); + buf[0] = 0; + snprintf(buf, sizeof(buf), "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr); printf("Renaming %s image file to %s...\n", image_type_to_string(i), buf); if ( rename(image_tmp_name(i), buf) < 0 ) { ERROR_INFO("Renaming failed"); - sprintf(buf, "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr); + buf[0] = 0; + snprintf(buf, sizeof(buf), "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr); printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf); if ( rename(image_tmp_name(i), buf) < 0 ) -- cgit v1.2.3 From f0712d5b23073fcb7d73085132ef72748fa31ae8 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 19 Oct 2014 20:23:21 +0200 Subject: all: Replace strlen() call on const string with sizeof()-1 --- src/fiasco.c | 2 +- src/local.c | 14 +++++++------- src/nolo.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/fiasco.c b/src/fiasco.c index 0c404bc..74d089f 100644 --- a/src/fiasco.c +++ b/src/fiasco.c @@ -495,7 +495,7 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { if ( image->layout ) { - layout_name = calloc(1, strlen(name) + strlen(".layout") + 1); + layout_name = calloc(1, strlen(name) + sizeof(".layout")-1 + 1); if ( ! layout_name ) { free(name); ALLOC_ERROR_RETURN(-1); diff --git a/src/local.c b/src/local.c index 86d3b78..c7f3ad1 100644 --- a/src/local.c +++ b/src/local.c @@ -127,9 +127,9 @@ int local_init(void) { while ( fgets(buf, sizeof(buf), file) ) { - if ( strncmp(buf, "Hardware", strlen("Hardware")) == 0 ) { + if ( strncmp(buf, "Hardware", sizeof("Hardware")-1) == 0 ) { - ptr = buf + strlen("Hardware"); + ptr = buf + sizeof("Hardware")-1; while ( ptr < buf + sizeof(buf) && *ptr > 0 && *ptr <= 32 ) ++ptr; @@ -328,7 +328,7 @@ int local_dump_image(enum image_type image, const char * file) { buf[0] = 0; close(fd); - if ( strncmp(buf, "internal", strlen("internal")) != 0 ) + if ( strncmp(buf, "internal", sizeof("internal")-1) != 0 ) continue; if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/", dirent->d_name, dirent->d_name) <= 0 ) @@ -340,7 +340,7 @@ int local_dump_image(enum image_type image, const char * file) { while ( ( dirent2 = readdir(dir2) ) ) { - if ( strncmp(dirent2->d_name, "block:mmcblk", strlen("block:mmcblk")) != 0 ) + if ( strncmp(dirent2->d_name, "block:mmcblk", sizeof("block:mmcblk")-1) != 0 ) continue; if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/%s/dev", dirent->d_name, dirent->d_name, dirent2->d_name) <= 0 ) @@ -540,7 +540,7 @@ int local_set_usb_host_mode(int enable) { int local_get_rd_mode(void) { - if ( strncmp(rd_mode, "master", strlen("master")) == 0 ) + if ( strncmp(rd_mode, "master", sizeof("master")-1) == 0 ) return 1; else return 0; @@ -559,8 +559,8 @@ int local_get_rd_flags(char * flags, size_t size) { const char * ptr; - if ( strncmp(rd_mode, "master", strlen("master")) == 0 ) - ptr = rd_mode + strlen("master"); + if ( strncmp(rd_mode, "master", sizeof("master")-1) == 0 ) + ptr = rd_mode + sizeof("master")-1; else ptr = rd_mode; diff --git a/src/nolo.c b/src/nolo.c index 9ba5a06..77d49e9 100644 --- a/src/nolo.c +++ b/src/nolo.c @@ -464,7 +464,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { if ( nolo_get_string(dev, "cmt:status", buf, sizeof(buf)) < 0 ) NOLO_ERROR_RETURN("cmt:status failed", -1); - if ( strncmp(buf, "idle", strlen("idle")) == 0 ) + if ( strncmp(buf, "idle", sizeof("idle")-1) == 0 ) state = 4; else printf("Erasing CMT...\n"); @@ -476,7 +476,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { NOLO_ERROR_RETURN("cmt:status failed", -1); } - if ( strncmp(buf, "finished", strlen("finished")) == 0 ) { + if ( strncmp(buf, "finished", sizeof("finished")-1) == 0 ) { if ( state <= 0 ) { printf_progressbar(last_total, last_total); @@ -537,9 +537,9 @@ int nolo_boot_device(struct usb_device_info * dev, const char * cmdline) { int size = 0; int mode = NOLO_BOOT_MODE_NORMAL; - if ( cmdline && strncmp(cmdline, "update", strlen("update")) == 0 && cmdline[strlen("update")] <= 32 ) { + if ( cmdline && strncmp(cmdline, "update", sizeof("update")-1) == 0 && cmdline[sizeof("update")-1] <= 32 ) { mode = NOLO_BOOT_MODE_UPDATE; - cmdline += strlen("update"); + cmdline += sizeof("update")-1; if ( *cmdline ) ++cmdline; while ( *cmdline && *cmdline <= 32 ) ++cmdline; -- cgit v1.2.3 From 99608d2b3f1015c530dbcfd2b337968f6810e231 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 9 Nov 2014 21:51:51 +0100 Subject: usb-device: Reattach kernel driver --- src/usb-device.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src') diff --git a/src/usb-device.c b/src/usb-device.c index b0a45bf..bf1241e 100644 --- a/src/usb-device.c +++ b/src/usb-device.c @@ -27,6 +27,10 @@ #include +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP +#include +#endif + #include "global.h" #include "device.h" #include "usb-device.h" @@ -73,6 +77,25 @@ static void usb_flash_device_info_print(const struct usb_flash_device * dev) { } +static void usb_reattach_kernel_driver(usb_dev_handle * udev, int interface) { + +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP + struct { + int ifno; + int ioctl_code; + void * data; + } command = { + .ifno = interface, + .ioctl_code = _IO('U', 23), + .data = NULL, + }; + + usb_release_interface(udev, interface); + ioctl(*((int *)udev), _IOWR('U', 18, command), &command); +#endif + +} + static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device * dev, char * product, size_t size) { char buf[1024]; @@ -145,6 +168,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { if ( usb_claim_interface(udev, usb_devices[i].interface) < 0 ) { PRINTF_ERROR("usb_claim_interface failed"); fprintf(stderr, "\n"); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); return NULL; } @@ -154,6 +178,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) { PRINTF_ERROR("usb_claim_interface failed"); fprintf(stderr, "\n"); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); return NULL; } @@ -164,6 +189,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { if ( usb_set_configuration(udev, usb_devices[i].configuration) < 0 ) { PRINTF_ERROR("usb_set_configuration failed"); fprintf(stderr, "\n"); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); return NULL; } @@ -172,6 +198,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { ret = calloc(1, sizeof(struct usb_device_info)); if ( ! ret ) { ALLOC_ERROR(); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); return NULL; } @@ -197,6 +224,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { if ( ! *device ) { ERROR("Device mishmash"); fprintf(stderr, "\n"); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); free(ret); return NULL; @@ -309,6 +337,7 @@ struct usb_device_info * usb_open_and_wait_for_device(void) { void usb_close_device(struct usb_device_info * dev) { + usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface); usb_close(dev->udev); free(dev); -- cgit v1.2.3 From 79a171e823872747cfe6a19f2af4d61b424eaa62 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 18:04:45 +0100 Subject: printf-utils: Fix division by zero if total is zero --- src/printf-utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/printf-utils.c b/src/printf-utils.c index 939cf54..3520d0b 100644 --- a/src/printf-utils.c +++ b/src/printf-utils.c @@ -39,7 +39,7 @@ void printf_progressbar(unsigned long long part, unsigned long long total) { int tmp, cols = 80; /* percentage calculation */ - pc = (int)(part*100/total); + pc = total==0?100:(int)(part*100/total); (pc<0)?pc=0:(pc>100)?pc=100:0; PRINTF_BACK(); -- cgit v1.2.3 From f3d203c205c9d4f1192f7e989eeeb80187c230fc Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 18:06:22 +0100 Subject: main: Correctly set and free processed images This will fix more memory corruptions (specially at quit). --- src/main.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index ff99dc3..34ebffd 100644 --- a/src/main.c +++ b/src/main.c @@ -663,6 +663,9 @@ int main(int argc, char **argv) { goto clean; } filter_images_by_type(type, &image_first); + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; } /* filter images by device */ @@ -674,11 +677,18 @@ int main(int argc, char **argv) { goto clean; } filter_images_by_device(device, &image_first); + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; } /* filter images by hwrev */ - if ( filter_hwrev ) + if ( filter_hwrev ) { filter_images_by_hwrev(atoi(filter_hwrev_arg), &image_first); + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; + } /* reorder images for flashing (first x-loader, second secondary) */ /* set 2nd and secondary images for cold-flashing */ @@ -742,11 +752,12 @@ int main(int argc, char **argv) { image_ptr = next; } + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; + } - /* make sure that fiasco_in has valid images*/ - if ( fiasco_in ) - fiasco_in->first = image_first; /* identify images */ if ( image_ident ) { @@ -784,8 +795,9 @@ int main(int argc, char **argv) { WARNING("Removing unknown image (specified by %s %s)", image_ptr->image->orig_filename ? "file" : "fiasco", image_ptr->image->orig_filename ? image_ptr->image->orig_filename : "image"); if ( image_ptr == image_first ) image_first = next; - image_list_unlink(image_ptr); - free(image_ptr); + if ( fiasco_in && image_ptr == fiasco_in->first ) + fiasco_in->first = fiasco_in->first->next; + image_list_del(image_ptr); } image_ptr = next; } @@ -985,6 +997,8 @@ int main(int argc, char **argv) { filter_images_by_device(dev->detected_device, &image_first); if ( detected_hwrev ) filter_images_by_hwrev(dev->detected_hwrev, &image_first); + if ( fiasco_in && ( detected_device || detected_hwrev ) ) + fiasco_in->first = image_first; /* set kernel and initfs images for loading */ if ( dev_load ) { @@ -1049,8 +1063,7 @@ int main(int argc, char **argv) { if ( fiasco_in && image_kernel == fiasco_in->first ) fiasco_in->first = fiasco_in->first->next; - image_list_unlink(image_kernel); - free(image_kernel); + image_list_del(image_kernel); image_kernel = NULL; } @@ -1061,11 +1074,10 @@ int main(int argc, char **argv) { if ( image_initfs == image_first ) image_first = image_first->next; - if ( fiasco_in && image_kernel == fiasco_in->first ) + if ( fiasco_in && image_initfs == fiasco_in->first ) fiasco_in->first = fiasco_in->first->next; - image_list_unlink(image_initfs); - free(image_initfs); + image_list_del(image_initfs); image_initfs = NULL; } } @@ -1081,11 +1093,10 @@ int main(int argc, char **argv) { if ( image_ptr == image_first ) image_first = image_first->next; - if ( fiasco_in && image_kernel == fiasco_in->first ) + if ( fiasco_in && image_ptr == fiasco_in->first ) fiasco_in->first = fiasco_in->first->next; - image_list_unlink(image_ptr); - free(image_ptr); + image_list_del(image_ptr); image_ptr = next; } } -- cgit v1.2.3 From 26b6f86f84f04c1b1461e257bb843881a58ff057 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 18:07:59 +0100 Subject: nolo: Fix parsing cmt status Now flashing cmt images should work without problems --- src/nolo.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nolo.c b/src/nolo.c index 77d49e9..86a39eb 100644 --- a/src/nolo.c +++ b/src/nolo.c @@ -419,8 +419,8 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { unsigned long long int part; unsigned long long int total; unsigned long long int last_total; - char status[20]; char buf[128]; + char * ptr; if ( image->type == IMAGE_ROOTFS ) flash = 1; @@ -491,18 +491,29 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { state = 4; + } else if ( strncmp(buf, "error", sizeof("error")-1) == 0 ) { + + PRINTF_ERROR_RETURN("cmt:status error", -1); + } else { - if ( sscanf(buf, "%s:%llu/%llu", status, &part, &total) != 3 ) + ptr = strchr(buf, ':'); + if ( ! ptr ) + PRINTF_ERROR_RETURN("cmt:status unknown", -1); + + *ptr = 0; + ptr++; + + if ( sscanf(ptr, "%llu/%llu", &part, &total) != 2 ) PRINTF_ERROR_RETURN("cmt:status unknown", -1); - if ( strcmp(status, "program") == 0 && state <= 0 ) { + if ( strcmp(buf, "program") == 0 && state <= 0 ) { printf_progressbar(last_total, last_total); printf("Done\n"); state = 1; } - if ( strcmp(status, "program") == 0 && state <= 1 ) { + if ( strcmp(buf, "program") == 0 && state <= 1 ) { printf("Programming CMT...\n"); state = 2; } @@ -510,12 +521,12 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { printf_progressbar(part, total); last_total = total; - if ( strcmp(status, "erase") == 0 && state <= 0 && part == total ) { + if ( strcmp(buf, "erase") == 0 && state <= 0 && part == total ) { printf("Done\n"); state = 1; } - if ( strcmp(status, "program") == 0 && state <= 2 && part == total ) { + if ( strcmp(buf, "program") == 0 && state <= 2 && part == total ) { printf("Done\n"); state = 3; } -- cgit v1.2.3 From 65888448bf184a830d0b2c0938491bdb6e269893 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 18:09:06 +0100 Subject: main: When doing normal flash filter all 2nd images This will fix infinite loop after successfull fiasco image flash --- src/main.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src') diff --git a/src/main.c b/src/main.c index 34ebffd..0552593 100644 --- a/src/main.c +++ b/src/main.c @@ -758,6 +758,23 @@ int main(int argc, char **argv) { } + /* remove 2nd image when doing normal flash */ + if ( dev_flash ) { + image_ptr = image_first; + while ( image_ptr ) { + struct image_list * next = image_ptr->next; + if ( image_ptr->image->type == IMAGE_2ND ) { + if ( image_ptr == image_first ) + image_first = next; + image_list_del(image_ptr); + } + image_ptr = next; + } + + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; + } /* identify images */ if ( image_ident ) { -- cgit v1.2.3 From cfd3b662a58961b9c8307dfc95846ee5f8309042 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 18:09:30 +0100 Subject: Makefile: Fix compilation of libusb-sniff libraries --- src/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index d1df391..b436ee6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -31,10 +31,10 @@ $(BIN).1: $(BIN) $(MANGEN) $(DEPENDS) ../doc/examples mv $@.tmp $@ libusb-sniff-32.so: libusb-sniff.c $(DEPENDS) - $(CC) $(CFLAGS) $(LDFLAGS) -fPIC -ldl -shared -m32 -o $@ $< + $(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m32 -o $@ libusb-sniff-64.so: libusb-sniff.c $(DEPENDS) - $(CC) $(CFLAGS) $(LDFLAGS) -fPIC -ldl -shared -m64 -o $@ $< + $(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m64 -o $@ %.o: %.c $(DEPENDS) $(CROSS_CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -- cgit v1.2.3 From 89566f559b6fba25de2f3c7a7064417e10ee81aa Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 18:49:32 +0100 Subject: fiasco: Fix memory leaks --- src/fiasco.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/fiasco.c b/src/fiasco.c index 74d089f..993b43d 100644 --- a/src/fiasco.c +++ b/src/fiasco.c @@ -413,6 +413,7 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) { WRITE_OR_FAIL(file, fd, "2", 1); /* 2 - device & hwrevs */ WRITE_OR_FAIL(file, fd, &device_hwrevs_bufs[i][0], 1); WRITE_OR_FAIL(file, fd, device_hwrevs_bufs[i]+1, ((uint8_t *)(device_hwrevs_bufs[i]))[0]); + /* FIXME: memory leak: device_hwrevs_bufs */ } free(device_hwrevs_bufs); @@ -513,6 +514,8 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644); if ( fd < 0 ) { ERROR_INFO("Cannot create output file %s", name); + free(name); + free(layout_name); return -1; } } @@ -522,7 +525,15 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { size = image_read(image, buf, sizeof(buf)); if ( size == 0 ) break; - WRITE_OR_FAIL(name, fd, buf, size); + if ( ! simulate ) { + if ( write(fd, buf, size) != (ssize_t)size ) { + ERROR_INFO_STR(name, "Cannot write %d bytes", size); + close(fd); + free(name); + free(layout_name); + return -1; + } + } } free(name); @@ -538,9 +549,16 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { ERROR_INFO("Cannot create layout file %s", layout_name); return -1; } - } - WRITE_OR_FAIL(layout_name, fd, image->layout, (int)strlen(image->layout)); + size = strlen(image->layout); + + if ( write(fd, image->layout, size) != (ssize_t)size ) { + ERROR_INFO_STR(layout_name, "Cannot write %d bytes", size); + close(fd); + free(layout_name); + return -1; + } + } free(layout_name); -- cgit v1.2.3 From 142ef93ddc8fe78c136547f2d127502aacc633e4 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 20:14:23 +0100 Subject: fiasco: Fix initializing variables --- src/fiasco.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/fiasco.c b/src/fiasco.c index 993b43d..06c8312 100644 --- a/src/fiasco.c +++ b/src/fiasco.c @@ -453,9 +453,9 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) { int fiasco_unpack(struct fiasco * fiasco, const char * dir) { - int fd = -1; - char * name = NULL; - char * layout_name = NULL; + int fd; + char * name; + char * layout_name; struct image * image; struct image_list * image_list; uint32_t size; @@ -484,6 +484,10 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { while ( image_list ) { + fd = -1; + name = NULL; + layout_name = NULL; + image = image_list->image; name = image_name_alloc_from_values(image); -- cgit v1.2.3 From 8c788bad62ff31f1034e92144ccfc19b0883121e Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 20:15:14 +0100 Subject: nolo: Do not call NOLO_ERROR_LOG when not needed --- src/nolo.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nolo.c b/src/nolo.c index 86a39eb..e437ef7 100644 --- a/src/nolo.c +++ b/src/nolo.c @@ -84,12 +84,14 @@ static void nolo_error_log(struct usb_device_info * dev, int only_clear) { char buf[2048]; size_t i, count; + int ret; for ( count = 0; count < 20; ++count ) { memset(buf, 0, sizeof(buf)); - if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, buf, sizeof(buf), 2000) <= 0 ) + ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, buf, sizeof(buf), 2000); + if ( ret < 0 ) break; if ( ! only_clear ) { @@ -103,6 +105,9 @@ static void nolo_error_log(struct usb_device_info * dev, int only_clear) { } + if ( (size_t)ret < sizeof(buf) ) + break; + } } @@ -180,11 +185,10 @@ static int nolo_get_version_string(struct usb_device_info * dev, const char * st return -1; ret = nolo_get_string(dev, buf, out, size); - - nolo_error_log(dev, 1); - - if ( ret < 0 ) + if ( ret < 0 ) { + nolo_error_log(dev, 1); return ret; + } if ( ! out[0] ) return -1; -- cgit v1.2.3 From e443393aa52ed662b594284d9d053299dace58fb Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 20:31:16 +0100 Subject: fiasco: Fix possible memory leak --- src/fiasco.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/fiasco.c b/src/fiasco.c index 06c8312..a2cd55a 100644 --- a/src/fiasco.c +++ b/src/fiasco.c @@ -551,6 +551,7 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { fd = open(layout_name, O_RDWR|O_CREAT|O_TRUNC, 0644); if ( fd < 0 ) { ERROR_INFO("Cannot create layout file %s", layout_name); + free(layout_name); return -1; } -- cgit v1.2.3 From b286e79ddb7340540bae07744fea915efbe67b9d Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Tue, 18 Nov 2014 23:19:54 +0100 Subject: cold-flash: struct xloader_msg must be packed --- src/cold-flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cold-flash.c b/src/cold-flash.c index 6441187..8874b32 100644 --- a/src/cold-flash.c +++ b/src/cold-flash.c @@ -130,7 +130,7 @@ struct xloader_msg { uint32_t size; /* 4 bytes - size of file */ uint32_t crc1; /* 4 bytes - crc32 of file */ uint32_t crc2; /* 4 bytes - crc32 of first 12 bytes of message */ -}; +} __attribute__((__packed__)); #define XLOADER_MSG_TYPE_PING 0x6301326E #define XLOADER_MSG_TYPE_SEND 0x6302326E -- cgit v1.2.3