summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2016-04-18 11:56:00 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2016-04-19 08:26:51 +0200
commitcb8cf33ce849f71f7fe1d717aa02b5669a54a19e (patch)
tree6d6f9692573033e1b516a896a8fb1333f25d1a37
parent24a6b3f8eabf08b589a2860aee9b670fa88cd085 (diff)
downloadbarebox-cb8cf33ce849f71f7fe1d717aa02b5669a54a19e.tar.gz
barebox-cb8cf33ce849f71f7fe1d717aa02b5669a54a19e.tar.xz
fix erasing/protecting flashes with unspecified size
fixes: 81737c1 mtd: Fix erasing of devices >4GiB Several places erased a complete flash partition passing ~0 as count to erase(). With the above commit count to erase was changed from an unsigned type to a signed type, so the (count > f->size - offset) check in erase() no longer triggers and the ~0 count is no longer adjusted to the whole device size. Among other things this results in saveenv failures on NOR flashes. This patch fixes this by introducing an explicit macro for erasing the whole device which is tested for in erase(). All other negative values are rejected. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Reported-by: Giorgio <giorgio.nicole@arcor.de>
-rw-r--r--arch/arm/mach-omap/am33xx_bbu_nand.c2
-rw-r--r--arch/arm/mach-omap/am33xx_bbu_spi_mlo.c2
-rw-r--r--commands/flash.c2
-rw-r--r--common/environment.c3
-rw-r--r--drivers/usb/gadget/dfu.c4
-rw-r--r--drivers/usb/gadget/f_fastboot.c2
-rw-r--r--fs/fs.c4
-rw-r--r--include/fs.h1
8 files changed, 12 insertions, 8 deletions
diff --git a/arch/arm/mach-omap/am33xx_bbu_nand.c b/arch/arm/mach-omap/am33xx_bbu_nand.c
index ee767d32e4..25f0e79ee6 100644
--- a/arch/arm/mach-omap/am33xx_bbu_nand.c
+++ b/arch/arm/mach-omap/am33xx_bbu_nand.c
@@ -40,7 +40,7 @@ static int write_image(const char *devfile, const void *image, size_t size)
return fd;
}
- ret = erase(fd, ~0, 0);
+ ret = erase(fd, ERASE_SIZE_ALL, 0);
if (ret < 0) {
pr_err("could not erase %s: %s\n", devfile,
errno_str());
diff --git a/arch/arm/mach-omap/am33xx_bbu_spi_mlo.c b/arch/arm/mach-omap/am33xx_bbu_spi_mlo.c
index 702bb9af59..69a73ffb06 100644
--- a/arch/arm/mach-omap/am33xx_bbu_spi_mlo.c
+++ b/arch/arm/mach-omap/am33xx_bbu_spi_mlo.c
@@ -70,7 +70,7 @@ static int spi_nor_mlo_handler(struct bbu_handler *handler,
goto out;
}
- ret = erase(dstfd, ~0, 0);
+ ret = erase(dstfd, ERASE_SIZE_ALL, 0);
if (ret < 0) {
printf("could not erase %s: %s", data->devicefile, errno_str());
goto out1;
diff --git a/commands/flash.c b/commands/flash.c
index 99d3cb7c3f..d881b4d399 100644
--- a/commands/flash.c
+++ b/commands/flash.c
@@ -32,7 +32,7 @@ static int do_flerase(int argc, char *argv[])
int fd;
char *filename = NULL;
struct stat s;
- loff_t start = 0, size = ~0;
+ loff_t start = 0, size;
int ret = 0;
if (argc == 1)
diff --git a/common/environment.c b/common/environment.c
index 9cf44a0f06..be102db3d2 100644
--- a/common/environment.c
+++ b/common/environment.c
@@ -88,6 +88,7 @@ static int do_compare_file(const char *filename, const char *base)
}
#else
+#define ERASE_SIZE_ALL 0
static inline int protect(int fd, size_t count, unsigned long offset, int prot)
{
return 0;
@@ -329,7 +330,7 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags)
goto out;
}
- ret = erase(envfd, ~0, 0);
+ ret = erase(envfd, ERASE_SIZE_ALL, 0);
/* ENOSYS and EOPNOTSUPP aren't errors here, many devices don't need it */
if (ret && errno != ENOSYS && errno != EOPNOTSUPP) {
diff --git a/drivers/usb/gadget/dfu.c b/drivers/usb/gadget/dfu.c
index 351b584796..d7bf92cdff 100644
--- a/drivers/usb/gadget/dfu.c
+++ b/drivers/usb/gadget/dfu.c
@@ -359,7 +359,7 @@ static int handle_dnload(struct usb_function *f, const struct usb_ctrlrequest *c
ret = -EINVAL;
goto err_out;
}
- ret = erase(fd, ~0, 0);
+ ret = erase(fd, ERASE_SIZE_ALL, 0);
close(fd);
if (ret && ret != -ENOSYS) {
perror("erase");
@@ -479,7 +479,7 @@ static int dfu_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
goto out;
}
- ret = erase(dfufd, ~0, 0);
+ ret = erase(dfufd, ERASE_SIZE_ALL, 0);
if (ret && ret != -ENOSYS) {
dfu->dfu_status = DFU_STATUS_errERASE;
perror("erase");
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 0df08c9a2b..aaf784913b 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -784,7 +784,7 @@ static void cb_erase(struct usb_ep *ep, struct usb_request *req, const char *cmd
if (fd < 0)
fastboot_tx_print(f_fb, "FAIL%s", strerror(-fd));
- ret = erase(fd, ~0, 0);
+ ret = erase(fd, ERASE_SIZE_ALL, 0);
close(fd);
diff --git a/fs/fs.c b/fs/fs.c
index 440adae14c..966abe9408 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -935,8 +935,10 @@ int erase(int fd, loff_t count, loff_t offset)
f = &files[fd];
if (offset >= f->size)
return 0;
- if (count > f->size - offset)
+ if (count == ERASE_SIZE_ALL || count > f->size - offset)
count = f->size - offset;
+ if (count < 0)
+ return -EINVAL;
fsdrv = f->fsdev->driver;
if (fsdrv->erase)
diff --git a/include/fs.h b/include/fs.h
index b9d1e6e09a..943ba55439 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -147,6 +147,7 @@ int umount(const char *pathname);
int umount_by_cdev(struct cdev *cdev);
/* not-so-standard functions */
+#define ERASE_SIZE_ALL ((loff_t) - 1)
int erase(int fd, loff_t count, loff_t offset);
int protect(int fd, size_t count, loff_t offset, int prot);
int protect_file(const char *file, int prot);