From 66ecce9a3d11cb21b687fa9711cedc8a4fa58230 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Mon, 9 Jan 2017 22:56:33 +0100 Subject: disk: Remove check which is always false Type unsigned long long int according to C99 can store at least 2^64-1. --- src/disk.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index 6bdd974..0b6b494 100644 --- a/src/disk.c +++ b/src/disk.c @@ -207,11 +207,6 @@ int disk_dump_dev(int fd, const char * file) { #endif - if ( blksize > ULLONG_MAX ) { - ERROR("Block device is too big"); - return -1; - } - if ( blksize == 0 ) { ERROR("Block device has zero size"); return -1; -- cgit v1.2.3 From 27a55c3367a3c66b075a2ef622f6aa1a3d19c24b Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 6 Jul 2017 20:55:41 +0200 Subject: disk: Choose correct partition in disk_open_dev() --- src/disk.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index 0b6b494..6a75b35 100644 --- a/src/disk.c +++ b/src/disk.c @@ -127,9 +127,15 @@ int disk_open_dev(int maj, int min, int partition, int readonly) { return -1; } - memcpy(blkdev+len, "p1", 3); + if ( snprintf(blkdev+len, sizeof(blkdev)-len, "p%d", partition) >= (int)(sizeof(blkdev)-len) ) { + ERROR("Block device name is too long"); + return -1; + } if ( stat(blkdev, &st) != 0 || ! S_ISBLK(st.st_mode) ) { - memcpy(blkdev+len, "1", 2); + if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) { + ERROR("Block device name is too long"); + return -1; + } if ( stat(blkdev, &st) != 0 || ! S_ISBLK(st.st_mode) ) { blkdev[len] = 0; fd = open(blkdev, O_RDONLY); -- cgit v1.2.3 From 31569c169a94640759a28acd420f27e0f39d9d3f Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 9 Jul 2017 14:56:30 +0200 Subject: disk: Fix detection of correct device in disk_open_dev() --- src/disk.c | 58 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 20 deletions(-) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index 6a75b35..486f50d 100644 --- a/src/disk.c +++ b/src/disk.c @@ -51,6 +51,7 @@ int disk_open_dev(int maj, int min, int partition, int readonly) { DIR * dir; struct dirent * dirent; int found; + int old_errno; size_t len; char blkdev[1024]; @@ -117,6 +118,19 @@ int disk_open_dev(int maj, int min, int partition, int readonly) { blkdev[len] = 0; + fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL); + if ( fd < 0 ) { + if ( errno != ENOMEDIUM ) + ERROR_INFO("Cannot open block device %s", blkdev); + return -1; + } else { + if ( fstat(fd, &st) != 0 || ! S_ISBLK(st.st_mode) || makedev(maj, min) != st.st_rdev ) { + ERROR("Block device %s does not have id %d:%d\n", blkdev, maj, min); + close(fd); + return -1; + } + } + } else if ( partition > 0 ) { /* Select partition */ @@ -131,37 +145,41 @@ int disk_open_dev(int maj, int min, int partition, int readonly) { ERROR("Block device name is too long"); return -1; } - if ( stat(blkdev, &st) != 0 || ! S_ISBLK(st.st_mode) ) { + fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL); + if ( fd < 0 && errno == ENOENT ) { if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) { ERROR("Block device name is too long"); return -1; } - if ( stat(blkdev, &st) != 0 || ! S_ISBLK(st.st_mode) ) { - blkdev[len] = 0; - fd = open(blkdev, O_RDONLY); - if ( fd < 0 ) { - if ( errno != ENOMEDIUM ) { - ERROR_INFO("Cannot open block device %s", blkdev); - return -1; - } - } else { - close(fd); - ERROR("Block device does not have partitions"); - return -1; - } + fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL); + } + if ( fd < 0 && errno == ENOENT ) { + blkdev[len] = 0; + fd = open(blkdev, O_RDONLY); + if ( fd < 0 ) { + if ( errno != ENOMEDIUM ) + ERROR_INFO("Cannot open block device %s", blkdev); + } else { + close(fd); + ERROR("Block device %s does not have partitions", blkdev); } + return -1; } + if ( fd < 0 ) + old_errno = errno; printf("Found block device %s for partition %d\n", blkdev, partition); - } + if ( fd < 0 ) { + errno = old_errno; + ERROR_INFO("Cannot open block device %s", blkdev); + } - fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL); + } else { + + ERROR("Invalid partition %d for block device %s", partition, blkdev); + fd = -1; - if ( fd < 0 ) { - if ( errno != ENOMEDIUM ) - ERROR_INFO("Cannot open block device %s", blkdev); - return -1; } return fd; -- cgit v1.2.3 From ccec7a182f1373fb15051a1c03d28e44c4188cce Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 9 Jul 2017 14:57:41 +0200 Subject: disk: Close device file handle when freeing structures --- src/disk.c | 7 +++++++ src/disk.h | 1 + src/operations.c | 5 ++++- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index 486f50d..b0d4499 100644 --- a/src/disk.c +++ b/src/disk.c @@ -413,6 +413,13 @@ int disk_init(struct usb_device_info * dev) { } +void disk_exit(struct usb_device_info * dev) { + + if ( dev->data >= 0 ) + close(dev->data); + +} + enum device disk_get_device(struct usb_device_info * dev) { return dev->device; diff --git a/src/disk.h b/src/disk.h index d5f367d..15eb127 100644 --- a/src/disk.h +++ b/src/disk.h @@ -24,6 +24,7 @@ #include "usb-device.h" int disk_init(struct usb_device_info * dev); +void disk_exit(struct usb_device_info * dev); enum device disk_get_device(struct usb_device_info * dev); diff --git a/src/operations.c b/src/operations.c index cd7ef44..b3be2c7 100644 --- a/src/operations.c +++ b/src/operations.c @@ -91,8 +91,11 @@ clean: void dev_free(struct device_info * dev) { - if ( dev->usb ) + if ( dev->usb ) { + if ( dev->usb->flash_device->protocol == FLASH_DISK ) + disk_exit(dev->usb); usb_close_device(dev->usb); + } free(dev); } -- cgit v1.2.3 From 559fe2a3bde61ccac3619fe2281dd6faaeeebd33 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 9 Jul 2017 17:26:13 +0200 Subject: disk: After opening blkdev, check that it is really block device --- src/disk.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index b0d4499..c8d218c 100644 --- a/src/disk.c +++ b/src/disk.c @@ -173,6 +173,10 @@ int disk_open_dev(int maj, int min, int partition, int readonly) { if ( fd < 0 ) { errno = old_errno; ERROR_INFO("Cannot open block device %s", blkdev); + } else if ( fstat(fd, &st) != 0 || ! S_ISBLK(st.st_mode) ) { + ERROR("Block device %s is not block device\n", blkdev); + close(fd); + return -1; } } else { -- cgit v1.2.3 From e685787e67c431579f8e2cf717a19174f154fe6c Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 8 Feb 2018 19:24:11 +0100 Subject: disk: Ensure that maj1:min1 is first device and maj2:min2 is second device --- src/disk.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index c8d218c..bb8ae02 100644 --- a/src/disk.c +++ b/src/disk.c @@ -304,6 +304,7 @@ int disk_init(struct usb_device_info * dev) { int maj2; int min1; int min2; + int tmp; maj1 = -1; maj2 = -1; @@ -390,6 +391,16 @@ int disk_init(struct usb_device_info * dev) { return -1; } + /* Ensure that maj1:min1 is first device and maj2:min2 is second device */ + if ( min2 < min1 ) { + tmp = min1; + min1 = min2; + min2 = tmp; + tmp = maj1; + maj1 = maj2; + maj2 = tmp; + } + /* TODO: change 1 to 0 when disk_flash_dev will be implemented */ /* RX-51 and RM-680 export MyDocs in first usb device and just first partion, so host system see whole device without MBR table */ -- cgit v1.2.3 From a6c20b5ee46c39cf5c9e86bc6cd938ba56909dff Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 8 Feb 2018 19:48:34 +0100 Subject: disk: Open whole block device with O_NONBLOCK This would simplify handling of ENOMEDIUM error. --- src/disk.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index bb8ae02..2db197b 100644 --- a/src/disk.c +++ b/src/disk.c @@ -118,10 +118,9 @@ int disk_open_dev(int maj, int min, int partition, int readonly) { blkdev[len] = 0; - fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL); + fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK); if ( fd < 0 ) { - if ( errno != ENOMEDIUM ) - ERROR_INFO("Cannot open block device %s", blkdev); + ERROR_INFO("Cannot open block device %s", blkdev); return -1; } else { if ( fstat(fd, &st) != 0 || ! S_ISBLK(st.st_mode) || makedev(maj, min) != st.st_rdev ) { @@ -155,10 +154,9 @@ int disk_open_dev(int maj, int min, int partition, int readonly) { } if ( fd < 0 && errno == ENOENT ) { blkdev[len] = 0; - fd = open(blkdev, O_RDONLY); + fd = open(blkdev, O_RDONLY | O_NONBLOCK); if ( fd < 0 ) { - if ( errno != ENOMEDIUM ) - ERROR_INFO("Cannot open block device %s", blkdev); + ERROR_INFO("Cannot open block device %s", blkdev); } else { close(fd); ERROR("Block device %s does not have partitions", blkdev); -- cgit v1.2.3 From ca1db966904a17097f4ffa2a73bc6ca58b4dd145 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 8 Feb 2018 19:49:13 +0100 Subject: disk: Fix compile warning: comparison between signed and unsigned integer expressions --- src/disk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index 2db197b..a608693 100644 --- a/src/disk.c +++ b/src/disk.c @@ -221,7 +221,7 @@ int disk_dump_dev(int fd, const char * file) { #else blksize = lseek(fd, 0, SEEK_END); - if ( blksize == (off_t)-1 ) { + if ( (off_t)blksize == (off_t)-1 ) { ERROR_INFO("Cannot get size of block device"); return -1; } -- cgit v1.2.3 From 2fd11378c8a350e124183dd833470c0a904375fd Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 8 Feb 2018 20:28:31 +0100 Subject: disk: Fix swapping maj1:min1 and maj2:min2 --- src/disk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index a608693..87e2c39 100644 --- a/src/disk.c +++ b/src/disk.c @@ -390,7 +390,7 @@ int disk_init(struct usb_device_info * dev) { } /* Ensure that maj1:min1 is first device and maj2:min2 is second device */ - if ( min2 < min1 ) { + if ( min2 != -1 && min2 < min1 ) { tmp = min1; min1 = min2; min2 = tmp; -- cgit v1.2.3 From e987dcd94853d0355e36d44e766bfabba62c0df5 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 8 Feb 2018 20:35:12 +0100 Subject: disk: Remove remaining ENOMEDIUM --- src/disk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index 87e2c39..c048a56 100644 --- a/src/disk.c +++ b/src/disk.c @@ -410,7 +410,7 @@ int disk_init(struct usb_device_info * dev) { else fd = disk_open_dev(maj1, min1, 1, 1); - if ( fd < 0 && errno != ENOMEDIUM ) + if ( fd < 0 ) return -1; dev->data = fd; -- cgit v1.2.3 From 33442482c65acf3805d24b76b3567ec97c2492ef Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 8 Feb 2018 23:20:14 +0100 Subject: disk: Fix detection of busnum Unpatched version of libusb on linux platform does not set location, but Debian's version of libusb has a patch which set it. For compatibility with other systems without unpatched libusb version, read busnum from dirname which seems to be always set. Fixes: https://github.com/pali/0xFFFF/issues/5 --- src/disk.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/disk.c') diff --git a/src/disk.c b/src/disk.c index c048a56..f58b1dd 100644 --- a/src/disk.c +++ b/src/disk.c @@ -363,9 +363,17 @@ int disk_init(struct usb_device_info * dev) { fclose(f); - if ( devnum != device->devnum || device->bus->location != busnum ) + if ( device->devnum != devnum ) continue; + if ( device->bus->location ) { + if ( device->bus->location != busnum ) + continue; + } else if ( device->bus->dirname[0] ) { + if ( atoi(device->bus->dirname) != (int)busnum ) + continue; + } + if ( sscanf(dirent->d_name, "%d:%d", &maj2, &min2) != 2 ) { maj2 = -1; min2 = -1; -- cgit v1.2.3