drivers/mmc/core/core.c | 21 +++++++++++++++++++++ drivers/mmc/core/core.h | 1 + drivers/mmc/core/mmc.c | 3 +-- drivers/mmc/core/sd.c | 3 +-- 4 files changed, 24 insertions(+), 4 deletions(-)
Some devices return nonprintable or non-ASCII bytes in CID product
names. One example device reports H8G4a followed by 0x92.
This led to downstream problems like in pyparted[1] or systemd[2] where
the consumers assumed the names were effectively ASCII-like.
Commit 3b791214c8bc ("mmc: core: Trim trailing whitespace from card
product names") established parse time normalization for CID names.
Extend that normalization by replacing bytes outside printable ASCII
with a question mark after the existing whitespace trimming.
The raw CID remains untouched. This patch doesn't change the lengths of
the sanitized names.
[1] https://github.com/dcantrell/pyparted/issues/76 (already fixed)
[2] https://github.com/systemd/systemd/issues/42930
Assisted-by: Codex:GPT-5
Signed-off-by: Jakub Stasiak <jakub@stasiak.at>
---
drivers/mmc/core/core.c | 21 +++++++++++++++++++++
drivers/mmc/core/core.h | 1 +
drivers/mmc/core/mmc.c | 3 +--
drivers/mmc/core/sd.c | 3 +--
4 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 29e80e5f928e..0de2a0133f13 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -8,6 +8,7 @@
* MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
*/
#include <linux/module.h>
+#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
@@ -23,6 +24,7 @@
#include <linux/fault-inject.h>
#include <linux/random.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/of.h>
#include <linux/mmc/card.h>
@@ -52,6 +54,25 @@
static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
+/**
+ * mmc_sanitize_cid_name() - sanitize a CID product name in place
+ * @name: NUL-terminated CID product name to sanitize
+ *
+ * Trim trailing whitespace and replace bytes outside printable ASCII with '?'.
+ */
+void mmc_sanitize_cid_name(char *name)
+{
+ char *p;
+
+ /* some product names may include trailing whitespace */
+ strim(name);
+
+ /* Keep product names safe for sysfs and uevent consumers. */
+ for (p = name; *p; p++)
+ if (!isascii(*p) || !isprint(*p))
+ *p = '?';
+}
+
/*
* Enabling software CRCs on the data blocks can be a significant (30%)
* performance cost, and for other reasons may not always be desired.
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index a028b48be164..0ec5ad66fb7c 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -41,6 +41,7 @@ struct device_node *mmc_of_find_child_device(struct mmc_host *host,
unsigned func_num);
void mmc_init_erase(struct mmc_card *card);
+void mmc_sanitize_cid_name(char *name);
void mmc_set_chip_select(struct mmc_host *host, int mode);
void mmc_set_clock(struct mmc_host *host, unsigned int hz);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 05444ecf3909..dca76be9f0dd 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -117,8 +117,7 @@ static int mmc_decode_cid(struct mmc_card *card)
return -EINVAL;
}
- /* some product names include trailing whitespace */
- strim(card->cid.prod_name);
+ mmc_sanitize_cid_name(card->cid.prod_name);
return 0;
}
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index c763efb10f64..7dc2b791f44c 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -97,8 +97,7 @@ void mmc_decode_cid(struct mmc_card *card)
card->cid.year += 2000; /* SD cards year offset */
- /* some product names may include trailing whitespace */
- strim(card->cid.prod_name);
+ mmc_sanitize_cid_name(card->cid.prod_name);
}
/*
--
2.55.0
On Sun, Aug 23, 2026 at 3:22 AM Jakub Stasiak <jakub@stasiak.at> wrote:
>
> Some devices return nonprintable or non-ASCII bytes in CID product
> names. One example device reports H8G4a followed by 0x92.
>
> This led to downstream problems like in pyparted[1] or systemd[2] where
> the consumers assumed the names were effectively ASCII-like.
>
> Commit 3b791214c8bc ("mmc: core: Trim trailing whitespace from card
> product names") established parse time normalization for CID names.
> Extend that normalization by replacing bytes outside printable ASCII
> with a question mark after the existing whitespace trimming.
>
> The raw CID remains untouched. This patch doesn't change the lengths of
> the sanitized names.
>
> [1] https://github.com/dcantrell/pyparted/issues/76 (already fixed)
> [2] https://github.com/systemd/systemd/issues/42930
>
> Assisted-by: Codex:GPT-5
> Signed-off-by: Jakub Stasiak <jakub@stasiak.at>
> ---
> drivers/mmc/core/core.c | 21 +++++++++++++++++++++
> drivers/mmc/core/core.h | 1 +
I would rather see that the new helper function gets declared in
mmc_ops.h and implemented in mmc_ops.c.
> drivers/mmc/core/mmc.c | 3 +--
> drivers/mmc/core/sd.c | 3 +--
> 4 files changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 29e80e5f928e..0de2a0133f13 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -8,6 +8,7 @@
> * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
> */
> #include <linux/module.h>
> +#include <linux/ctype.h>
> #include <linux/init.h>
> #include <linux/interrupt.h>
> #include <linux/completion.h>
> @@ -23,6 +24,7 @@
> #include <linux/fault-inject.h>
> #include <linux/random.h>
> #include <linux/slab.h>
> +#include <linux/string.h>
> #include <linux/of.h>
>
> #include <linux/mmc/card.h>
> @@ -52,6 +54,25 @@
>
> static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
>
> +/**
> + * mmc_sanitize_cid_name() - sanitize a CID product name in place
> + * @name: NUL-terminated CID product name to sanitize
> + *
> + * Trim trailing whitespace and replace bytes outside printable ASCII with '?'.
> + */
> +void mmc_sanitize_cid_name(char *name)
Nitpick.
We have an eMMC command called "sanitize", which makes me think we
should find another name for this function, to avoid confusion.
Perhaps just mmc_cleanup_string() or if you can find something even better.
> +{
> + char *p;
> +
> + /* some product names may include trailing whitespace */
> + strim(name);
> +
> + /* Keep product names safe for sysfs and uevent consumers. */
> + for (p = name; *p; p++)
> + if (!isascii(*p) || !isprint(*p))
> + *p = '?';
> +}
> +
> /*
> * Enabling software CRCs on the data blocks can be a significant (30%)
> * performance cost, and for other reasons may not always be desired.
> diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
> index a028b48be164..0ec5ad66fb7c 100644
> --- a/drivers/mmc/core/core.h
> +++ b/drivers/mmc/core/core.h
> @@ -41,6 +41,7 @@ struct device_node *mmc_of_find_child_device(struct mmc_host *host,
> unsigned func_num);
>
> void mmc_init_erase(struct mmc_card *card);
> +void mmc_sanitize_cid_name(char *name);
>
> void mmc_set_chip_select(struct mmc_host *host, int mode);
> void mmc_set_clock(struct mmc_host *host, unsigned int hz);
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 05444ecf3909..dca76be9f0dd 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -117,8 +117,7 @@ static int mmc_decode_cid(struct mmc_card *card)
> return -EINVAL;
> }
>
> - /* some product names include trailing whitespace */
> - strim(card->cid.prod_name);
> + mmc_sanitize_cid_name(card->cid.prod_name);
>
> return 0;
> }
> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> index c763efb10f64..7dc2b791f44c 100644
> --- a/drivers/mmc/core/sd.c
> +++ b/drivers/mmc/core/sd.c
> @@ -97,8 +97,7 @@ void mmc_decode_cid(struct mmc_card *card)
>
> card->cid.year += 2000; /* SD cards year offset */
>
> - /* some product names may include trailing whitespace */
> - strim(card->cid.prod_name);
> + mmc_sanitize_cid_name(card->cid.prod_name);
> }
>
> /*
> --
> 2.55.0
>
Kind regards
Uffe
© 2016 - 2026 Red Hat, Inc.