diff options
| author | Thorsten Blum <thorsten.blum@linux.dev> | 2026-08-18 17:16:35 +0200 |
|---|---|---|
| committer | Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | 2026-08-18 19:28:32 +0300 |
| commit | 54745d563114b74f6fecebce68cd020d06c1772b (patch) | |
| tree | 18e43273e4a38088ed671bd371ea10a2e49f57dc | |
| parent | e0d6312578e1fd03738fc2ac8ac21c8bd84e965e (diff) | |
| download | linux-next-54745d563114b74f6fecebce68cd020d06c1772b.tar.gz linux-next-54745d563114b74f6fecebce68cd020d06c1772b.zip | |
platform/x86: think-lmi: Fix current password length check
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>
| -rw-r--r-- | drivers/platform/x86/lenovo/think-lmi.c | 7 |
1 files changed, 3 insertions, 4 deletions
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; } |
