From: Bean Huo <[email protected]>
Hi Uffe,
Two changes for mmc-utils, please have a take look at it.
Kind regards,
Bean
Bean Huo (2):
mmc-utils: Use memcpy instead of strncpy
mmc-utils: Add note for CMDQ_MODE_EN runtime value
mmc_cmds.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--
2.25.1
From: Bean Huo <[email protected]>
The -Wstringop-truncation warning added in GCC 8.0:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82944
If you use the GCC > v8.0, you probably will get this compilation error:
error: ‘__builtin_strncpy’ output may be truncated copying 8
bytes from a string of length 511 [-Werror=stringop-truncation]
Use memcpy instead of strncpy to avoid this compilation error.
Signed-off-by: Bean Huo <[email protected]>
---
mmc_cmds.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mmc_cmds.c b/mmc_cmds.c
index 205e6e5b89f9..ecbde3937c81 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -1835,7 +1835,8 @@ int do_read_extcsd(int nargs, char **argv)
if (ext_csd_rev >= 7) {
memset(lbuf, 0, sizeof(lbuf));
- strncpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
+ memcpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
+ lbuf[8] = '\0';
printf("eMMC Firmware Version: %s\n", lbuf);
printf("eMMC Life Time Estimation A [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]: 0x%02x\n",
ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]);
--
2.25.1
From: Bean Huo <[email protected]>
Since the Linux kernel commit 70b52f090805 ("mmc: block: Disable CMDQ on
the ioctl path"), CMDQ in CMDQ_MODE_EN[15] is disabled before reading EXT_CSD.
Therefore, it is more accurate to use sysfs node to check CMDQ_MODE_EN value.
Add a note print to highlight.
Signed-off-by: Bean Huo <[email protected]>
---
mmc_cmds.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mmc_cmds.c b/mmc_cmds.c
index ecbde3937c81..46c5f5faae02 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -1885,6 +1885,8 @@ int do_read_extcsd(int nargs, char **argv)
(ext_csd[EXT_CSD_CMDQ_DEPTH] & 0x1f) + 1);
printf("Command Enabled [CMDQ_MODE_EN]: 0x%02x\n",
ext_csd[EXT_CSD_CMDQ_MODE_EN]);
+ printf("Note: CMDQ_MODE_EN may not indicate the runtime CMDQ ON or OFF.\n"
+ "Please check sysfs node '/sys/devices/.../mmc_host/mmcX/mmcX:XXXX/cmdq_en'\n");
}
out_free:
return ret;
--
2.25.1
Hi Bean.
> - strncpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
> + memcpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
> + lbuf[8] = '\0';
Above copies exactly 8 bytes, without any regard to the sizes of
destination-buffer (lbuf) or source-buffer (ext_csd). Thus, there are
high chances of overflow/underflow/out-of-bounds.
If ext_csd contains, say a string 5 characters long, you would want to
copy 6 characters (5 for length, 1 for null-terminator).
I guess you are trying to copy as-many-bytes as possible to lbuf,
including the null-character.
Thus, strlcpy/strscpy should be used here.
Something like :
strlcpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], sizeof(lbuf));
or
strscpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], sizeof(lbuf));
Note that you do not need to worry about putting the null-terminator.
strlcpy/strscpy already take care of that for you.
Thanks and Regards,
Ajay
Hi Bean,
>
> The -Wstringop-truncation warning added in GCC 8.0:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82944
>
> If you use the GCC > v8.0, you probably will get this compilation error:
>
> error: ‘__builtin_strncpy’ output may be truncated copying 8 bytes from a
> string of length 511 [-Werror=stringop-truncation]
>
> Use memcpy instead of strncpy to avoid this compilation error.
>
> Signed-off-by: Bean Huo <[email protected]>
Looking into the link above, it say that this warning:
"... is specifically intended to highlight likely unintended uses of the strncpy function that truncate the terminating NUL charcter from the source string."
As this is not the case here, I wouldn't worry about this warning.
Thanks,
Avri
> ---
> mmc_cmds.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/mmc_cmds.c b/mmc_cmds.c
> index 205e6e5b89f9..ecbde3937c81 100644
> --- a/mmc_cmds.c
> +++ b/mmc_cmds.c
> @@ -1835,7 +1835,8 @@ int do_read_extcsd(int nargs, char **argv)
>
> if (ext_csd_rev >= 7) {
> memset(lbuf, 0, sizeof(lbuf));
> - strncpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
> + memcpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
> + lbuf[8] = '\0';
> printf("eMMC Firmware Version: %s\n", lbuf);
> printf("eMMC Life Time Estimation A
> [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]: 0x%02x\n",
> ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]);
> --
> 2.25.1
> From: Bean Huo <[email protected]>
>
> Since the Linux kernel commit 70b52f090805 ("mmc: block: Disable CMDQ on
> the ioctl path"), CMDQ in CMDQ_MODE_EN[15] is disabled before reading
> EXT_CSD.
> Therefore, it is more accurate to use sysfs node to check CMDQ_MODE_EN
> value.
> Add a note print to highlight.
>
> Signed-off-by: Bean Huo <[email protected]>
Acked-by: Avri Altman <[email protected]>
> ---
> mmc_cmds.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/mmc_cmds.c b/mmc_cmds.c
> index ecbde3937c81..46c5f5faae02 100644
> --- a/mmc_cmds.c
> +++ b/mmc_cmds.c
> @@ -1885,6 +1885,8 @@ int do_read_extcsd(int nargs, char **argv)
> (ext_csd[EXT_CSD_CMDQ_DEPTH] & 0x1f) + 1);
> printf("Command Enabled [CMDQ_MODE_EN]: 0x%02x\n",
> ext_csd[EXT_CSD_CMDQ_MODE_EN]);
> + printf("Note: CMDQ_MODE_EN may not indicate the runtime
> CMDQ ON or OFF.\n"
> + "Please check sysfs node
> + '/sys/devices/.../mmc_host/mmcX/mmcX:XXXX/cmdq_en'\n");
> }
> out_free:
> return ret;
> --
> 2.25.1
Hi Ajay,
thanks for your review.
On Mon, 2021-11-15 at 12:39 +0530, Ajay Garg wrote:
> Hi Bean.
>
> > - strncpy(lbuf,
> > (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
> > + memcpy(lbuf,
> > (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
> > + lbuf[8] = '\0';
>
> Above copies exactly 8 bytes, without any regard to the sizes of
> destination-buffer (lbuf) or source-buffer (ext_csd). Thus, there are
> high chances of overflow/underflow/out-of-bounds.
>
I don't understand how above memcpy() overflow/underflow/out-of-bounds?
would you please provide more specific reason?
memcpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
here lbuf is a char array lbuf[10], and ext_csd is a __u8 array, __u8
ext_csd[512].
> If ext_csd contains, say a string 5 characters long, you would want
> to
> copy 6 characters (5 for length, 1 for null-terminator).
>
> I guess you are trying to copy as-many-bytes as possible to lbuf,
> including the null-character.
> Thus, strlcpy/strscpy should be used here.
>
> Something like :
>
> strlcpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION],
> sizeof(lbuf));
> or
> strscpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION],
> sizeof(lbuf));
>
> Note that you do not need to worry about putting the null-terminator.
> strlcpy/strscpy already take care of that for you.
>
Yes, but please remember that mmc-utils is mainly used for embedded
platforms, they are not easy/inconvenient to update to the latest
library to support these two APIs(strlcpy needs libbsd-dev, and strscpy
needs some one else.). If we use strlcpy or strscpy, mmc-utils will
not be portable. Do you know any other API that can be used and make
code more portable and simpler?
Kind regards,
Bean
>
> Thanks and Regards,
> Ajay
> I don't understand how above memcpy() overflow/underflow/out-of-bounds?
> would you please provide more specific reason?
>
> memcpy(lbuf, (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION], 8);
>
> here lbuf is a char array lbuf[10], and ext_csd is a __u8 array, __u8
> ext_csd[512].
Ok, in the given information parameters, it might work fine at runtime.
But still, using 8 as the magic number makes the code illegible for a
third-party. Plus the code is also unoptimised, eg :
i)
If ext = "abc", then we need to copy (3 + 1) bytes.
However, currently memcpy would copy (8 + 1) bytes.
ii)
If ext = "abcdefghijklmnopqrst", then we need to copy (9 + 1) bytes.
However, currently memcpy would copy (8 + 1) bytes.
> Yes, but please remember that mmc-utils is mainly used for embedded
> platforms, they are not easy/inconvenient to update to the latest
> library to support these two APIs(strlcpy needs libbsd-dev, and strscpy
> needs some one else.). If we use strlcpy or strscpy, mmc-utils will
> not be portable. Do you know any other API that can be used and make
> code more portable and simpler?
>
Hmm, you can always start adding code locally in your codebase.
Anyways, if you *must* use only "already available code", snprintf is
an alternative.
snprintf(lbuf, sizeof(lbuf), (char*)&ext_csd[EXT_CSD_FIRMWARE_VERSION]);
On Sun, 14 Nov 2021 at 21:43, Bean Huo <[email protected]> wrote:
>
> From: Bean Huo <[email protected]>
>
> Since the Linux kernel commit 70b52f090805 ("mmc: block: Disable CMDQ on
> the ioctl path"), CMDQ in CMDQ_MODE_EN[15] is disabled before reading EXT_CSD.
> Therefore, it is more accurate to use sysfs node to check CMDQ_MODE_EN value.
> Add a note print to highlight.
>
> Signed-off-by: Bean Huo <[email protected]>
Applied for master at git.kernel.org/pub/scm/utils/mmc/mmc-utils.git, thanks!
Kind regards
Uffe
> ---
> mmc_cmds.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/mmc_cmds.c b/mmc_cmds.c
> index ecbde3937c81..46c5f5faae02 100644
> --- a/mmc_cmds.c
> +++ b/mmc_cmds.c
> @@ -1885,6 +1885,8 @@ int do_read_extcsd(int nargs, char **argv)
> (ext_csd[EXT_CSD_CMDQ_DEPTH] & 0x1f) + 1);
> printf("Command Enabled [CMDQ_MODE_EN]: 0x%02x\n",
> ext_csd[EXT_CSD_CMDQ_MODE_EN]);
> + printf("Note: CMDQ_MODE_EN may not indicate the runtime CMDQ ON or OFF.\n"
> + "Please check sysfs node '/sys/devices/.../mmc_host/mmcX/mmcX:XXXX/cmdq_en'\n");
> }
> out_free:
> return ret;
> --
> 2.25.1
>