From patchwork Mon May 22 21:53:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enrico Jorns X-Patchwork-Id: 684817 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E561C77B75 for ; Mon, 22 May 2023 21:53:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231821AbjEVVxc (ORCPT ); Mon, 22 May 2023 17:53:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52976 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233602AbjEVVxb (ORCPT ); Mon, 22 May 2023 17:53:31 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9EFD1DB for ; Mon, 22 May 2023 14:53:30 -0700 (PDT) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1q1DT7-0001qn-2j; Mon, 22 May 2023 23:53:29 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1q1DT5-0026B1-Kn; Mon, 22 May 2023 23:53:27 +0200 Received: from ejo by dude04.red.stw.pengutronix.de with local (Exim 4.94.2) (envelope-from ) id 1q1DT5-008YMq-25; Mon, 22 May 2023 23:53:27 +0200 From: Enrico Jorns To: linux-mmc@vger.kernel.org Cc: Avri Altman , Ulf Hansson , ejo@pengutronix.de Subject: [PATCH 1/2] mmc-utils: introduce optional --verify argument for 'extcsd write' Date: Mon, 22 May 2023 23:53:09 +0200 Message-Id: <20230522215310.2038669-1-ejo@pengutronix.de> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ejo@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-mmc@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Registers can be write-once but ioctl does not necessarily return with an error. Thus it is a good idea to allow verifying the data written. Signed-off-by: Enrico Jorns --- mmc.c | 7 ++++--- mmc_cmds.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/mmc.c b/mmc.c index 795b4e3..3f813b4 100644 --- a/mmc.c +++ b/mmc.c @@ -56,9 +56,10 @@ static struct Command commands[] = { "Print extcsd data from .", NULL }, - { do_write_extcsd, 3, - "extcsd write", " \n" - "Write at offset to 's extcsd.", + { do_write_extcsd, -3, + "extcsd write", " [--verify]\n" + "Write at offset to 's extcsd.\n" + " --verify Verify data written", NULL }, { do_writeprotect_boot_get, -1, diff --git a/mmc_cmds.c b/mmc_cmds.c index df66986..154020e 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -1986,9 +1986,10 @@ int do_write_extcsd(int nargs, char **argv) int fd, ret; int offset, value; char *device; + int verify = 0; - if (nargs != 4) { - fprintf(stderr, "Usage: mmc extcsd write \n"); + if (nargs != 4 && nargs != 5) { + fprintf(stderr, "Usage: mmc extcsd write [--verify]\n"); exit(1); } @@ -1996,6 +1997,14 @@ int do_write_extcsd(int nargs, char **argv) value = strtol(argv[2], NULL, 0); device = argv[3]; + if (nargs == 5) { + if (strcmp(argv[4], "--verify") == 0) { + verify = 1; + } else { + fprintf(stderr, "Unknown argument: '%s'\n", argv[4]); + } + } + fd = open(device, O_RDWR); if (fd < 0) { perror("open"); @@ -2010,6 +2019,21 @@ int do_write_extcsd(int nargs, char **argv) exit(1); } + if (verify) { + __u8 ext_csd[512]; + + ret = read_extcsd(fd, ext_csd); + if (ret) { + fprintf(stderr, "Could not read EXT_CSD from %s\n", device); + exit(1); + } + + if (ext_csd[offset] != value) { + fprintf(stderr, "Verification failed: expected 0x%x, got 0x%x\n", value, ext_csd[offset]); + exit(1); + } + } + return ret; } From patchwork Mon May 22 21:53:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enrico Jorns X-Patchwork-Id: 685224 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D79A0C77B73 for ; Mon, 22 May 2023 21:53:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229723AbjEVVxc (ORCPT ); Mon, 22 May 2023 17:53:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231821AbjEVVxb (ORCPT ); Mon, 22 May 2023 17:53:31 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC411F1 for ; Mon, 22 May 2023 14:53:29 -0700 (PDT) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1q1DT6-0001qo-Ag; Mon, 22 May 2023 23:53:28 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1q1DT5-0026B3-Lv; Mon, 22 May 2023 23:53:27 +0200 Received: from ejo by dude04.red.stw.pengutronix.de with local (Exim 4.94.2) (envelope-from ) id 1q1DT5-008YMt-2b; Mon, 22 May 2023 23:53:27 +0200 From: Enrico Jorns To: linux-mmc@vger.kernel.org Cc: Avri Altman , Ulf Hansson , ejo@pengutronix.de Subject: [PATCH 2/2] mmc-utils: add error handling to 'extcsd write' input value parsing Date: Mon, 22 May 2023 23:53:10 +0200 Message-Id: <20230522215310.2038669-2-ejo@pengutronix.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230522215310.2038669-1-ejo@pengutronix.de> References: <20230522215310.2038669-1-ejo@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ejo@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-mmc@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org 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 --- 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) {