* FAILED: patch "[PATCH] platform/x86: think-lmi: Fix current password length check" failed to apply to 6.1-stable tree
@ 2026-09-03 14:49 gregkh
2026-09-09 16:27 ` [PATCH 6.1.y 1/4] lib/string_helpers: Add kstrdup_and_replace() helper Sasha Levin
0 siblings, 1 reply; 5+ messages in thread
From: gregkh @ 2026-09-03 14:49 UTC (permalink / raw)
To: thorsten.blum, ilpo.jarvinen, mpearson-lenovo; +Cc: stable
The patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 54745d563114b74f6fecebce68cd020d06c1772b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026090342-duct-salutary-5524@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 54745d563114b74f6fecebce68cd020d06c1772b Mon Sep 17 00:00:00 2001
From: Thorsten Blum <thorsten.blum@linux.dev>
Date: Tue, 18 Aug 2026 17:16:35 +0200
Subject: [PATCH] platform/x86: think-lmi: Fix current password length check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
current_password_store() checks the password length before removing the
trailing newline, which can reject valid passwords that are exactly
->maxlen bytes long.
It also passes ->maxlen to strscpy(), which truncates passwords without
a newline.
Use strchrnul() to measure the password length up to the newline, then
copy that many bytes and add a trailing NUL terminator using strscpy().
Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms")
Cc: stable@vger.kernel.org
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://patch.msgid.link/20260818151635.37094-2-thorsten.blum@linux.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
diff --git a/drivers/platform/x86/lenovo/think-lmi.c b/drivers/platform/x86/lenovo/think-lmi.c
index ca266657e16c..a0e3fa766e37 100644
--- a/drivers/platform/x86/lenovo/think-lmi.c
+++ b/drivers/platform/x86/lenovo/think-lmi.c
@@ -438,14 +438,13 @@ static ssize_t current_password_store(struct kobject *kobj,
struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
size_t pwdlen;
- pwdlen = strlen(buf);
+ /* Strip newline; setting password won't work if one is present. */
+ pwdlen = strchrnul(buf, '\n') - buf;
/* pwdlen == 0 is allowed to clear the password */
if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen)))
return -EINVAL;
- strscpy(setting->password, buf, setting->maxlen);
- /* Strip out CR if one is present, setting password won't work if it is present */
- strreplace(setting->password, '\n', '\0');
+ strscpy(setting->password, buf, pwdlen + 1);
return count;
}
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.1.y 1/4] lib/string_helpers: Add kstrdup_and_replace() helper
2026-09-03 14:49 FAILED: patch "[PATCH] platform/x86: think-lmi: Fix current password length check" failed to apply to 6.1-stable tree gregkh
@ 2026-09-09 16:27 ` Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 2/4] platform/x86: think-lmi: Replace kstrdup() + strreplace() with kstrdup_and_replace() Sasha Levin
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Sasha Levin @ 2026-09-09 16:27 UTC (permalink / raw)
To: stable; +Cc: Andy Shevchenko, Stephen Boyd, Sasha Levin
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 045ad46441a1cf2ff358af0126f8c57f337804fa ]
Duplicate a NULL-terminated string and replace all occurrences of
the old character with a new one. In other words, provide functionality
of kstrdup() + strreplace().
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20230804143910.15504-2-andriy.shevchenko@linux.intel.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Stable-dep-of: 54745d563114 ("platform/x86: think-lmi: Fix current password length check")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/string_helpers.h | 2 ++
lib/string_helpers.c | 15 +++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index 8530c73282692..7a1304f71f644 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -103,6 +103,8 @@ char *kstrdup_quotable(const char *src, gfp_t gfp);
char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp);
char *kstrdup_quotable_file(struct file *file, gfp_t gfp);
+char *kstrdup_and_replace(const char *src, char old, char new, gfp_t gfp);
+
char **kasprintf_strarray(gfp_t gfp, const char *prefix, size_t n);
void kfree_strarray(char **array, size_t n);
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index df3ecc167ccf4..2f975395b49e5 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -719,6 +719,21 @@ char *kstrdup_quotable_file(struct file *file, gfp_t gfp)
}
EXPORT_SYMBOL_GPL(kstrdup_quotable_file);
+/*
+ * Returns duplicate string in which the @old characters are replaced by @new.
+ */
+char *kstrdup_and_replace(const char *src, char old, char new, gfp_t gfp)
+{
+ char *dst;
+
+ dst = kstrdup(src, gfp);
+ if (!dst)
+ return NULL;
+
+ return strreplace(dst, old, new);
+}
+EXPORT_SYMBOL_GPL(kstrdup_and_replace);
+
/**
* kasprintf_strarray - allocate and fill array of sequential strings
* @gfp: flags for the slab allocator
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.1.y 2/4] platform/x86: think-lmi: Replace kstrdup() + strreplace() with kstrdup_and_replace()
2026-09-09 16:27 ` [PATCH 6.1.y 1/4] lib/string_helpers: Add kstrdup_and_replace() helper Sasha Levin
@ 2026-09-09 16:27 ` Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 3/4] platform/x86: think-lmi: Use strreplace() to replace a character by nul Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 4/4] platform/x86: think-lmi: Fix current password length check Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-09-09 16:27 UTC (permalink / raw)
To: stable; +Cc: Andy Shevchenko, Ilpo Järvinen, Hans de Goede, Sasha Levin
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit e621198016e99cddc097d32cd3b56b15cee27d91 ]
Replace open coded functionalify of kstrdup_and_replace() with a call.
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20230918135116.1248560-1-andriy.shevchenko@linux.intel.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Adapt the current_value_store() conversion to the 6.1 tree, which lacks
bulk-save support. Keep the existing permission and save behavior instead
of introducing references to absent save_mode and reboot_required fields.
Also replace the remaining strip_cr() call in current_password_store()
with strreplace() and remove the now-unused helper. This supplies the
context expected by 54745d563114 ("platform/x86: think-lmi: Fix current
password length check") without adding functions or changing the password
length checks in this dependency.
The earlier kstrdup_and_replace() dependency also assumes the upstream
strreplace() return-value change from d01a77afd6be. In this stable tree,
strreplace() still returns the string's end, so explicitly return dst from
kstrdup_and_replace() after performing the replacement. This preserves the
allocation pointer for the newly converted callers and their frees.
Stable-dep-of: 54745d563114 ("platform/x86: think-lmi: Fix current password length check")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/think-lmi.c | 53 ++++++++++----------------------
lib/string_helpers.c | 3 +-
2 files changed, 18 insertions(+), 38 deletions(-)
diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
index e7605bc97f2b0..58c070198e59f 100644
--- a/drivers/platform/x86/think-lmi.c
+++ b/drivers/platform/x86/think-lmi.c
@@ -15,7 +15,7 @@
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/mutex.h>
-#include <linux/string.h>
+#include <linux/string_helpers.h>
#include <linux/types.h>
#include <linux/dmi.h>
#include <linux/wmi.h>
@@ -198,14 +198,6 @@ static struct think_lmi tlmi_priv;
static struct class *fw_attr_class;
static DEFINE_MUTEX(tlmi_mutex);
-/* ------ Utility functions ------------*/
-/* Strip out CR if one is present */
-static void strip_cr(char *str)
-{
- char *p = strchrnul(str, '\n');
- *p = '\0';
-}
-
/* Convert BIOS WMI error string to suitable error code */
static int tlmi_errstr_to_err(const char *errstr)
{
@@ -411,7 +403,7 @@ static ssize_t current_password_store(struct kobject *kobj,
strscpy(setting->password, buf, setting->maxlen);
/* Strip out CR if one is present, setting password won't work if it is present */
- strip_cr(setting->password);
+ strreplace(setting->password, '\n', '\0');
return count;
}
@@ -432,13 +424,11 @@ static ssize_t new_password_store(struct kobject *kobj,
if (!tlmi_priv.can_set_bios_password)
return -EOPNOTSUPP;
- new_pwd = kstrdup(buf, GFP_KERNEL);
+ /* Strip out CR if one is present, setting password won't work if it is present */
+ new_pwd = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
if (!new_pwd)
return -ENOMEM;
- /* Strip out CR if one is present, setting password won't work if it is present */
- strip_cr(new_pwd);
-
/* Use lock in case multiple WMI operations needed */
mutex_lock(&tlmi_mutex);
@@ -709,13 +699,11 @@ static ssize_t cert_to_password_store(struct kobject *kobj,
if (!setting->signature || !setting->signature[0])
return -EACCES;
- passwd = kstrdup(buf, GFP_KERNEL);
+ /* Strip out CR if one is present */
+ passwd = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
if (!passwd)
return -ENOMEM;
- /* Strip out CR if one is present */
- strip_cr(passwd);
-
/* Format: 'Password,Signature' */
auth_str = kasprintf(GFP_KERNEL, "%s,%s", passwd, setting->signature);
if (!auth_str) {
@@ -765,11 +753,10 @@ static ssize_t certificate_store(struct kobject *kobj,
return ret ?: count;
}
- new_cert = kstrdup(buf, GFP_KERNEL);
+ /* Strip out CR if one is present */
+ new_cert = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
if (!new_cert)
return -ENOMEM;
- /* Strip out CR if one is present */
- strip_cr(new_cert);
if (setting->cert_installed) {
/* Certificate is installed so this is an update */
@@ -817,13 +804,11 @@ static ssize_t signature_store(struct kobject *kobj,
if (!tlmi_priv.certificate_support)
return -EOPNOTSUPP;
- new_signature = kstrdup(buf, GFP_KERNEL);
+ /* Strip out CR if one is present */
+ new_signature = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
if (!new_signature)
return -ENOMEM;
- /* Strip out CR if one is present */
- strip_cr(new_signature);
-
/* Free any previous signature */
kfree(setting->signature);
setting->signature = new_signature;
@@ -846,13 +831,11 @@ static ssize_t save_signature_store(struct kobject *kobj,
if (!tlmi_priv.certificate_support)
return -EOPNOTSUPP;
- new_signature = kstrdup(buf, GFP_KERNEL);
+ /* Strip out CR if one is present */
+ new_signature = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
if (!new_signature)
return -ENOMEM;
- /* Strip out CR if one is present */
- strip_cr(new_signature);
-
/* Free any previous signature */
kfree(setting->save_signature);
setting->save_signature = new_signature;
@@ -981,13 +964,11 @@ static ssize_t current_value_store(struct kobject *kobj,
if (!tlmi_priv.can_set_bios_settings)
return -EOPNOTSUPP;
- new_setting = kstrdup(buf, GFP_KERNEL);
+ /* Strip out CR if one is present */
+ new_setting = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
if (!new_setting)
return -ENOMEM;
- /* Strip out CR if one is present */
- strip_cr(new_setting);
-
/* Use lock in case multiple WMI operations needed */
mutex_lock(&tlmi_mutex);
@@ -1160,13 +1141,11 @@ static ssize_t debug_cmd_store(struct kobject *kobj, struct kobj_attribute *attr
if (!tlmi_priv.can_debug_cmd)
return -EOPNOTSUPP;
- new_setting = kstrdup(buf, GFP_KERNEL);
+ /* Strip out CR if one is present */
+ new_setting = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
if (!new_setting)
return -ENOMEM;
- /* Strip out CR if one is present */
- strip_cr(new_setting);
-
if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
tlmi_priv.pwd_admin->password,
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index 2f975395b49e5..9be6a3cfaed4a 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -730,7 +730,8 @@ char *kstrdup_and_replace(const char *src, char old, char new, gfp_t gfp)
if (!dst)
return NULL;
- return strreplace(dst, old, new);
+ strreplace(dst, old, new);
+ return dst;
}
EXPORT_SYMBOL_GPL(kstrdup_and_replace);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.1.y 3/4] platform/x86: think-lmi: Use strreplace() to replace a character by nul
2026-09-09 16:27 ` [PATCH 6.1.y 1/4] lib/string_helpers: Add kstrdup_and_replace() helper Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 2/4] platform/x86: think-lmi: Replace kstrdup() + strreplace() with kstrdup_and_replace() Sasha Levin
@ 2026-09-09 16:27 ` Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 4/4] platform/x86: think-lmi: Fix current password length check Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-09-09 16:27 UTC (permalink / raw)
To: stable; +Cc: Andy Shevchenko, Ilpo Järvinen, Hans de Goede, Sasha Levin
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 6cb9c8637c672584d4915559001020237840acba ]
We can replace
p = strchrnul(str, '$OLD');
*p = '\0';
with
strreplace(str, '$OLD', '\0');
that does the compatible modification without a need of the temporary variable.
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20230918135116.1248560-2-andriy.shevchenko@linux.intel.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Stable-dep-of: 54745d563114 ("platform/x86: think-lmi: Fix current password length check")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/think-lmi.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
index 58c070198e59f..00d0cf34196d4 100644
--- a/drivers/platform/x86/think-lmi.c
+++ b/drivers/platform/x86/think-lmi.c
@@ -909,7 +909,7 @@ static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *at
static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
- char *item, *value, *p;
+ char *item, *value;
int ret;
ret = tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID);
@@ -922,8 +922,7 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a
ret = -EINVAL;
else {
/* On Workstations remove the Options part after the value */
- p = strchrnul(value, ';');
- *p = '\0';
+ strreplace(value, ';', '\0');
ret = sysfs_emit(buf, "%s\n", value + 1);
}
kfree(item);
@@ -1430,7 +1429,6 @@ static int tlmi_analyze(void)
for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) {
struct tlmi_attr_setting *setting;
char *item = NULL;
- char *p;
tlmi_priv.setting[i] = NULL;
status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID);
@@ -1447,8 +1445,7 @@ static int tlmi_analyze(void)
strreplace(item, '/', '\\');
/* Remove the value part */
- p = strchrnul(item, ',');
- *p = '\0';
+ strreplace(item, ',', '\0');
/* Create a setting entry */
setting = kzalloc(sizeof(*setting), GFP_KERNEL);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.1.y 4/4] platform/x86: think-lmi: Fix current password length check
2026-09-09 16:27 ` [PATCH 6.1.y 1/4] lib/string_helpers: Add kstrdup_and_replace() helper Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 2/4] platform/x86: think-lmi: Replace kstrdup() + strreplace() with kstrdup_and_replace() Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 3/4] platform/x86: think-lmi: Use strreplace() to replace a character by nul Sasha Levin
@ 2026-09-09 16:27 ` Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-09-09 16:27 UTC (permalink / raw)
To: stable; +Cc: Thorsten Blum, Mark Pearson, Ilpo Järvinen, Sasha Levin
From: Thorsten Blum <thorsten.blum@linux.dev>
[ Upstream commit 54745d563114b74f6fecebce68cd020d06c1772b ]
current_password_store() checks the password length before removing the
trailing newline, which can reject valid passwords that are exactly
->maxlen bytes long.
It also passes ->maxlen to strscpy(), which truncates passwords without
a newline.
Use strchrnul() to measure the password length up to the newline, then
copy that many bytes and add a trailing NUL terminator using strscpy().
Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms")
Cc: stable@vger.kernel.org
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://patch.msgid.link/20260818151635.37094-2-thorsten.blum@linux.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/think-lmi.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
index 00d0cf34196d4..e3faed0565266 100644
--- a/drivers/platform/x86/think-lmi.c
+++ b/drivers/platform/x86/think-lmi.c
@@ -396,14 +396,13 @@ static ssize_t current_password_store(struct kobject *kobj,
struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
size_t pwdlen;
- pwdlen = strlen(buf);
+ /* Strip newline; setting password won't work if one is present. */
+ pwdlen = strchrnul(buf, '\n') - buf;
/* pwdlen == 0 is allowed to clear the password */
if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen)))
return -EINVAL;
- strscpy(setting->password, buf, setting->maxlen);
- /* Strip out CR if one is present, setting password won't work if it is present */
- strreplace(setting->password, '\n', '\0');
+ strscpy(setting->password, buf, pwdlen + 1);
return count;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-09 16:27 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-03 14:49 FAILED: patch "[PATCH] platform/x86: think-lmi: Fix current password length check" failed to apply to 6.1-stable tree gregkh
2026-09-09 16:27 ` [PATCH 6.1.y 1/4] lib/string_helpers: Add kstrdup_and_replace() helper Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 2/4] platform/x86: think-lmi: Replace kstrdup() + strreplace() with kstrdup_and_replace() Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 3/4] platform/x86: think-lmi: Use strreplace() to replace a character by nul Sasha Levin
2026-09-09 16:27 ` [PATCH 6.1.y 4/4] platform/x86: think-lmi: Fix current password length check Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox