All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans de Goede <hdegoede@redhat.com>
To: Mark Pearson <markpearson@lenovo.com>
Cc: mgross@linux.intel.com, platform-driver-x86@vger.kernel.org,
	divya.bharathi@dell.com, prasanth.ksr@dell.com
Subject: Re: [External] Re: [PATCH v2 3/3] platform/x86: think-lmi: Add WMI interface support on Lenovo platforms
Date: Fri, 21 May 2021 10:10:34 +0200	[thread overview]
Message-ID: <1c21c3d3-7ff1-a7b2-86d0-245050426760@redhat.com> (raw)
In-Reply-To: <ac30f95e-8398-fb11-8c94-b50050a3f88f@lenovo.com>

Hi Mark,

On 5/20/21 7:18 PM, Mark Pearson wrote:
> Thanks for the review Hans,

You're welcome.

> On 2021-05-19 1:06 p.m., Hans de Goede wrote:
>> Hi,
>>
>> On 5/9/21 3:57 AM, Mark Pearson wrote:
> <snip>
>>>
>>> diff --git a/Documentation/ABI/testing/sysfs-class-firmware-attributes b/Documentation/ABI/testing/sysfs-class-firmware-attributes
>>> index 8ea59fea4..31d1becfa 100644
>>> --- a/Documentation/ABI/testing/sysfs-class-firmware-attributes
>>> +++ b/Documentation/ABI/testing/sysfs-class-firmware-attributes
>>> @@ -185,6 +185,17 @@ Description:
>>>  					A write only value that when used in tandem with
>>>  					current_password will reset a system or admin password.
>>>  
>>> +		encoding:
>>> +					For platforms that require it (currently Lenovo) the
>>> +					encoding method that is used. This can be either "ascii"
>>> +					or "scancode". Default is set to "ascii"
>>> +
>>> +		kbdlang:
>>> +					For platforms that require it (currently Lenovo only) the
>>> +					keyboard language method that is used. This is generally a
>>> +					two char code (e.g. "us", "fr", "gr") and may vary per platform.
>>> +					Default is set to "us"
>>> +
>>
>> I should have caught this during my review of v1, these are Lenovo specific, so please prefix
>> them with lenovo_ (the same is already done for dell specific sysfs attributes) and move them
>> to a separate "Lenovo specific class extensions" part of the doc.
>>
> No problem
> 
> <snip>
> 
>>>  
>>>  What:		/sys/class/firmware-attributes/*/attributes/pending_reboot
>>> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
>>> index b0e1e5f65..0511c54fc 100644
>>> --- a/drivers/platform/x86/Kconfig
>>> +++ b/drivers/platform/x86/Kconfig
>>> @@ -639,6 +639,18 @@ config THINKPAD_ACPI_HOTKEY_POLL
>>>  	  If you are not sure, say Y here.  The driver enables polling only if
>>>  	  it is strictly necessary to do so.
>>>  
>>> +config THINKPAD_LMI
>>> +	tristate "Lenovo WMI-based systems management driver"
>>> +	default m
>>
>> default n (or no default at all) please.
> Ack
> 
> <snip>
>>> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
>>> new file mode 100644
>>> index 000000000..2fa989e98
>>> --- /dev/null
>>> +++ b/drivers/platform/x86/think-lmi.c
>>> @@ -0,0 +1,890 @@
> <snip>
>>> +
>>> +/* ---- Authentication sysfs --------------------------------------------------------- */
>>> +static ssize_t is_enabled_show(struct kobject *kobj, struct kobj_attribute *attr,
>>> +					  char *buf)
>>> +{
>>> +	struct tlmi_pwd_setting *setting = container_of(kobj, struct tlmi_pwd_setting, kobj);
>>> +
>>> +	if (setting->valid)
>>> +		return sysfs_emit(buf, "1\n");
>>> +	else
>>> +		return sysfs_emit(buf, "0\n");
>>
>> Maybe use:
>>
>> 	sysfs_emit(buf, "%d\n", settings->valid);
>>
>> instead?
> Definitely :)
> 
>>
>>
>>> +}
>>> +
>>> +static struct kobj_attribute auth_is_pass_set = __ATTR_RO(is_enabled);
>>> +
>>> +static ssize_t current_password_store(struct kobject *kobj,
>>> +				      struct kobj_attribute *attr,
>>> +				      const char *buf, size_t count)
>>> +{
>>> +	struct tlmi_pwd_setting *setting = container_of(kobj, struct tlmi_pwd_setting, kobj);
>>> +	int length;
>>> +
>>> +	length = strlen(buf);
>>> +	if (buf[length-1] == '\n')
>>> +		length--;
>>> +
>>> +	if (length >= TLMI_PWD_MAXLEN)
>>> +		return -EINVAL;
>>> +
>>> +	memcpy(setting->password, buf, length);
>>> +	setting->password[length] = '\0';
>>> +	return count;
>>> +}
>>> +
>>> +static struct kobj_attribute auth_current_password = __ATTR_WO(current_password);
>>> +
>>> +static ssize_t new_password_store(struct kobject *kobj,
>>> +				  struct kobj_attribute *attr,
>>> +				  const char *buf, size_t count)
>>> +{
>>> +	struct tlmi_pwd_setting *setting = container_of(kobj, struct tlmi_pwd_setting, kobj);
>>> +	char *p, *new_pwd;
>>> +	char *auth_str;
>>> +	int ret = 0, len;
>>> +
>>> +	if (!capable(CAP_SYS_ADMIN))
>>> +		return -EPERM;
>>> +
>>> +	if (!tlmi_priv.can_set_bios_password)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	new_pwd = kstrdup(buf, GFP_KERNEL);
>>> +	if (!new_pwd)
>>> +		return -ENOMEM;
>>> +
>>> +	p = strchr(new_pwd, '\n');
>>> +	if (p)
>>> +		*p = '\0';
>>> +
>>> +	if (strlen(new_pwd) > setting->maxlen) {
>>> +		ret = -EINVAL;
>>> +		goto out;
>>> +	}
>>> +
>>> +	/* Format: 'PasswordType,CurrentPw,NewPw,Encoding,KbdLang;' */
>>> +	len = strlen(setting->password) + strlen(encoding_options[setting->encoding])
>>> +		+ strlen(setting->kbdlang) + 3 /* type */
>>> +		+ strlen(new_pwd) + 6 /* punctuation and terminator*/;
>>> +	auth_str = kzalloc(len, GFP_KERNEL);
>>> +	snprintf(auth_str, len, "%s,%s,%s,%s,%s;",
>>> +		 setting->pwd_type, setting->password, new_pwd,
>>> +		 encoding_options[setting->encoding], setting->kbdlang);
>>> +	ret = tlmi_simple_call(LENOVO_SET_BIOS_PASSWORD_GUID, auth_str);
>>
>> So I guess on success any subsequent calls need to use the new password,
>> so the user is expected to write the new password to the current_password
>> file after changing the password this way?
>>
>> I just checked the dell-wmi-sysman code and that does this:
>>
>>         /* clear current_password here and use user input from wmi_priv.current_password */
>>         if (!ret)
>>                 memset(current_password, 0, MAX_BUFF);
>>
>> Where current_password points to either the user or admin cached password,
>> depending on which one is being changed.
>>
>> So that seems to work the same way as what you are doing here (the user needs to
>> write the new password to current_password after changing it through the
>> new_password sysfs attribute). Can you add a patch to the patch-set documenting
>> this in Documentation/ABI/testing/sysfs-class-firmware-attributes ?
>>
>> Also you may want to consider clearing out the old cached password on success
>> like the Dell code is doing.
>>
> Would you have any objections/concerns if, on a successful password
> update, this function just updates the stored password setting to the
> new password.
> Seems nicer from a user point of view then having to go and feed the
> current_password field again.
> e.g: strncpy(new_pwd, setting->password, TLMI_PWD_MAXLEN)

Please use strscpy, strncpy has horrible syntax and using it is easy
to get wrong.

e.g. the above example is wrong if strlen(new_pwd) >= TLMI_PWD_MAXLEN
the resulting setting->password will not be 0 terminated (and you
seem to have swapped src and dst, but that is unrelated to strncpy
being a sucky function).

This also make me realize that the code has 2 max-pwd-lengths:

setting->maxlen
TLMI_PWD_MAXLEN

I think you should put a:

	if (WARN_ON(pwdcfg.max_length > TLMI_PWD_MAXLEN))
		pwdcfg.max_length = TLMI_PWD_MAXLEN;

in tlmi_analyze() so that we get a kernel-backtrace (and thus bugreports
if this condition ever becomes true.

And then use pwdcfg.max_length everywhere (e.g. also for the check in
current_password_store()).

Also the length checks in current_password_store() and new_password_store() 
should probably also check against settings->minlen ?


> I know it would make Dell and Lenovo operate differently (I can add that
> detail to the documentation) but it just feels like a nicer design.

That works for me. Perhaps you can also do a (compile tested only) RFC
patch for the Dell code to do the same thing (replace the memset 0 with
the strscpy) to see if the Dell folks are ok with also doing things this
way ?

Regards,

Hans



  reply	other threads:[~2021-05-21  8:11 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-09  1:57 [PATCH v2 1/3] platform/x86: firmware_attributes_class: Create helper file for handling firmware-attributes class registration events Mark Pearson
2021-05-09  1:57 ` [PATCH v2 2/3] platform/x86: dell-wmi-sysman: Use firmware_attributes_class helper Mark Pearson
2021-05-19 16:17   ` Hans de Goede
2021-05-09  1:57 ` [PATCH v2 3/3] platform/x86: think-lmi: Add WMI interface support on Lenovo platforms Mark Pearson
2021-05-19 17:06   ` Hans de Goede
2021-05-20 17:18     ` [External] " Mark Pearson
2021-05-21  8:10       ` Hans de Goede [this message]
2021-05-21  9:37         ` Hans de Goede
2021-05-21 15:55         ` Mark Pearson
2021-05-21 16:55           ` Hans de Goede
2021-05-21 19:00             ` Mark Pearson
2021-05-24 10:19             ` Ksr, Prasanth
2021-05-24 15:27               ` Hans de Goede
2021-05-25 14:02                 ` Mark Pearson
2021-05-22 11:04   ` Andy Shevchenko
2021-05-25 15:14     ` [External] " Mark Pearson
2021-05-25 16:18       ` Andy Shevchenko
2021-05-25 16:50         ` Mark Pearson
2021-05-25 16:29       ` Hans de Goede
2021-05-25 16:52         ` Mark Pearson
2021-05-19 16:15 ` [PATCH v2 1/3] platform/x86: firmware_attributes_class: Create helper file for handling firmware-attributes class registration events Hans de Goede
2021-05-19 16:45   ` [External] " Mark Pearson
2021-05-19 16:19 ` Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1c21c3d3-7ff1-a7b2-86d0-245050426760@redhat.com \
    --to=hdegoede@redhat.com \
    --cc=divya.bharathi@dell.com \
    --cc=markpearson@lenovo.com \
    --cc=mgross@linux.intel.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=prasanth.ksr@dell.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.