[PATCH 2/2] mmc-utils: add error handling to 'extcsd write' input value parsing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



So far, any value was silently accepted, even a

  mmc extcsd write 0x100 yeah /dev/mmcblk1

which resulted in write of value 0x0 at offset 0x0 since the parsing
error of 'yeah' was ignored and the returned value of 0 was taken
unconditionally.
The 0x100 was then implicitly casted down to the expected __u8 input for
the offset and also ended up as 0.

This is not the behavior one would expect when dealing with eMMC
registers that might, depending on which we write to, be writable only
once in the eMMC's lifetime.

This introduces the str_to_u8() helper function that checks if input
values are parsable and have a proper size. Internally it also uses
strtoul() instead of strtol() since input is always expected to be
non-negative. Also, use proper input variables (unsigned long instead
of int) to remove another layer of implicit down casts.

Signed-off-by: Enrico Jorns <ejo@xxxxxxxxxxxxxx>
---
 mmc_cmds.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/mmc_cmds.c b/mmc_cmds.c
index 154020e..e348651 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -1981,10 +1981,28 @@ out_free:
 	return ret;
 }
 
+__u8 str_to_u8(const char* input)
+{
+	unsigned long parsedval;
+	char *endptr;
+
+	parsedval = strtoul(input, &endptr, 0);
+	if (*endptr != '\0') {
+		fprintf(stderr, "Invalid input: %s. Cannot parse to 8 bit integer.\n", input);
+		exit(1);
+	}
+	if (parsedval >= UINT8_MAX) {
+		fprintf(stderr, "Invalid input: Value %s too large 8 bit integer.\n", input);
+		exit(1);
+	}
+
+	return (__u8) parsedval;
+}
+
 int do_write_extcsd(int nargs, char **argv)
 {
 	int fd, ret;
-	int offset, value;
+	__u8 offset, value;
 	char *device;
 	int verify = 0;
 
@@ -1993,8 +2011,8 @@ int do_write_extcsd(int nargs, char **argv)
 		exit(1);
 	}
 
-	offset = strtol(argv[1], NULL, 0);
-	value  = strtol(argv[2], NULL, 0);
+	offset = str_to_u8(argv[1]);
+	value = str_to_u8(argv[2]);
 	device = argv[3];
 
 	if (nargs == 5) {
-- 
2.39.2




[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux