diff options
author | Johan Hovold <johan@kernel.org> | 2025-08-29 15:21:52 +0200 |
---|---|---|
committer | Sudeep Holla <sudeep.holla@arm.com> | 2025-09-02 11:23:42 +0100 |
commit | 572ce546390d1b7c99b16c38cae1b680c716216c (patch) | |
tree | 004dac67b9d3835aa0a585ae4000501645a54939 | |
parent | 72ca981dba5e98c2b1c2956016cc4be934d9fbea (diff) |
firmware: arm_scmi: quirk: Prevent writes to string constants
The quirk version range is typically a string constant and must not be
modified (e.g. as it may be stored in read-only memory). Attempting
to do so can trigger faults such as:
| Unable to handle kernel write to read-only memory at virtual
| address ffffc036d998a947
Update the range parsing so that it operates on a copy of the version
range string, and mark all the quirk strings as const to reduce the
risk of introducing similar future issues.
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220437
Fixes: 487c407d57d6 ("firmware: arm_scmi: Add common framework to handle firmware quirks")
Cc: stable@vger.kernel.org # 6.16
Cc: Cristian Marussi <cristian.marussi@arm.com>
Reported-by: Jan Palus <jpalus@fastmail.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Message-Id: <20250829132152.28218-1-johan@kernel.org>
[sudeep.holla: minor commit message rewording; switch to cleanup helpers]
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
-rw-r--r-- | drivers/firmware/arm_scmi/quirks.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/firmware/arm_scmi/quirks.c b/drivers/firmware/arm_scmi/quirks.c index 03960aca3610..03848283c2a0 100644 --- a/drivers/firmware/arm_scmi/quirks.c +++ b/drivers/firmware/arm_scmi/quirks.c @@ -71,6 +71,7 @@ */ #include <linux/ctype.h> +#include <linux/cleanup.h> #include <linux/device.h> #include <linux/export.h> #include <linux/hashtable.h> @@ -89,9 +90,9 @@ struct scmi_quirk { bool enabled; const char *name; - char *vendor; - char *sub_vendor_id; - char *impl_ver_range; + const char *vendor; + const char *sub_vendor_id; + const char *impl_ver_range; u32 start_range; u32 end_range; struct static_key_false *key; @@ -217,7 +218,7 @@ static unsigned int scmi_quirk_signature(const char *vend, const char *sub_vend) static int scmi_quirk_range_parse(struct scmi_quirk *quirk) { - const char *last, *first = quirk->impl_ver_range; + const char *last, *first __free(kfree) = NULL; size_t len; char *sep; int ret; @@ -228,8 +229,12 @@ static int scmi_quirk_range_parse(struct scmi_quirk *quirk) if (!len) return 0; + first = kmemdup(quirk->impl_ver_range, len + 1, GFP_KERNEL); + if (!first) + return -ENOMEM; + last = first + len - 1; - sep = strchr(quirk->impl_ver_range, '-'); + sep = strchr(first, '-'); if (sep) *sep = '\0'; |