1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Think LMI BIOS configuration driver
4  *
5  * Copyright(C) 2019-2021 Lenovo
6  *
7  * Original code from Thinkpad-wmi project https://github.com/iksaif/thinkpad-wmi
8  * Copyright(C) 2017 Corentin Chary <[email protected]>
9  * Distributed under the GPL-2.0 license
10  */
11 
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 
14 #include <linux/acpi.h>
15 #include <linux/array_size.h>
16 #include <linux/errno.h>
17 #include <linux/fs.h>
18 #include <linux/mutex.h>
19 #include <linux/string_helpers.h>
20 #include <linux/types.h>
21 #include <linux/dmi.h>
22 #include <linux/wmi.h>
23 #include "firmware_attributes_class.h"
24 #include "think-lmi.h"
25 
26 static bool debug_support;
27 module_param(debug_support, bool, 0444);
28 MODULE_PARM_DESC(debug_support, "Enable debug command support");
29 
30 /*
31  * Name: BiosSetting
32  * Description: Get item name and settings for current LMI instance.
33  * Type: Query
34  * Returns: "Item,Value"
35  * Example: "WakeOnLAN,Enable"
36  */
37 #define LENOVO_BIOS_SETTING_GUID "51F5230E-9677-46CD-A1CF-C0B23EE34DB7"
38 
39 /*
40  * Name: SetBiosSetting
41  * Description: Change the BIOS setting to the desired value using the SetBiosSetting
42  *  class. To save the settings, use the SaveBiosSetting class.
43  *  BIOS settings and values are case sensitive.
44  *  After making changes to the BIOS settings, you must reboot the computer
45  *  before the changes will take effect.
46  * Type: Method
47  * Arguments: "Item,Value,Password,Encoding,KbdLang;"
48  * Example: "WakeOnLAN,Disable,pa55w0rd,ascii,us;"
49  */
50 #define LENOVO_SET_BIOS_SETTINGS_GUID "98479A64-33F5-4E33-A707-8E251EBBC3A1"
51 
52 /*
53  * Name: SaveBiosSettings
54  * Description: Save any pending changes in settings.
55  * Type: Method
56  * Arguments: "Password,Encoding,KbdLang;"
57  * Example: "pa55w0rd,ascii,us;"
58  */
59 #define LENOVO_SAVE_BIOS_SETTINGS_GUID "6A4B54EF-A5ED-4D33-9455-B0D9B48DF4B3"
60 
61 /*
62  * Name: BiosPasswordSettings
63  * Description: Return BIOS Password settings
64  * Type: Query
65  * Returns: PasswordMode, PasswordState, MinLength, MaxLength,
66  *  SupportedEncoding, SupportedKeyboard
67  */
68 #define LENOVO_BIOS_PASSWORD_SETTINGS_GUID "8ADB159E-1E32-455C-BC93-308A7ED98246"
69 
70 /*
71  * Name: SetBiosPassword
72  * Description: Change a specific password.
73  *  - BIOS settings cannot be changed at the same boot as power-on
74  *    passwords (POP) and hard disk passwords (HDP). If you want to change
75  *    BIOS settings and POP or HDP, you must reboot the system after changing
76  *    one of them.
77  *  - A password cannot be set using this method when one does not already
78  *    exist. Passwords can only be updated or cleared.
79  * Type: Method
80  * Arguments: "PasswordType,CurrentPassword,NewPassword,Encoding,KbdLang;"
81  * Example: "pop,pa55w0rd,newpa55w0rd,ascii,us;”
82  */
83 #define LENOVO_SET_BIOS_PASSWORD_GUID "2651D9FD-911C-4B69-B94E-D0DED5963BD7"
84 
85 /*
86  * Name: GetBiosSelections
87  * Description: Return a list of valid settings for a given item.
88  * Type: Method
89  * Arguments: "Item"
90  * Returns: "Value1,Value2,Value3,..."
91  * Example:
92  *  -> "FlashOverLAN"
93  *  <- "Enabled,Disabled"
94  */
95 #define LENOVO_GET_BIOS_SELECTIONS_GUID	"7364651A-132F-4FE7-ADAA-40C6C7EE2E3B"
96 
97 /*
98  * Name: DebugCmd
99  * Description: Debug entry method for entering debug commands to the BIOS
100  */
101 #define LENOVO_DEBUG_CMD_GUID "7FF47003-3B6C-4E5E-A227-E979824A85D1"
102 
103 /*
104  * Name: OpcodeIF
105  * Description: Opcode interface which provides the ability to set multiple
106  *  parameters and then trigger an action with a final command.
107  *  This is particularly useful for simplifying setting passwords.
108  *  With this support comes the ability to set System, HDD and NVMe
109  *  passwords.
110  *  This is currently available on ThinkCenter and ThinkStations platforms
111  */
112 #define LENOVO_OPCODE_IF_GUID "DFDDEF2C-57D4-48ce-B196-0FB787D90836"
113 
114 /*
115  * Name: SetBiosCert
116  * Description: Install BIOS certificate.
117  * Type: Method
118  * Arguments: "Certificate,Password"
119  * You must reboot the computer before the changes will take effect.
120  */
121 #define LENOVO_SET_BIOS_CERT_GUID    "26861C9F-47E9-44C4-BD8B-DFE7FA2610FE"
122 
123 /*
124  * Name: UpdateBiosCert
125  * Description: Update BIOS certificate.
126  * Type: Method
127  * Format: "Certificate,Signature"
128  * You must reboot the computer before the changes will take effect.
129  */
130 #define LENOVO_UPDATE_BIOS_CERT_GUID "9AA3180A-9750-41F7-B9F7-D5D3B1BAC3CE"
131 
132 /*
133  * Name: ClearBiosCert
134  * Description: Uninstall BIOS certificate.
135  * Type: Method
136  * Format: "Serial,Signature"
137  * You must reboot the computer before the changes will take effect.
138  */
139 #define LENOVO_CLEAR_BIOS_CERT_GUID  "B2BC39A7-78DD-4D71-B059-A510DEC44890"
140 /*
141  * Name: CertToPassword
142  * Description: Switch from certificate to password authentication.
143  * Type: Method
144  * Format: "Password,Signature"
145  * You must reboot the computer before the changes will take effect.
146  */
147 #define LENOVO_CERT_TO_PASSWORD_GUID "0DE8590D-5510-4044-9621-77C227F5A70D"
148 
149 /*
150  * Name: SetBiosSettingCert
151  * Description: Set attribute using certificate authentication.
152  * Type: Method
153  * Format: "Item,Value,Signature"
154  */
155 #define LENOVO_SET_BIOS_SETTING_CERT_GUID  "34A008CC-D205-4B62-9E67-31DFA8B90003"
156 
157 /*
158  * Name: SaveBiosSettingCert
159  * Description: Save any pending changes in settings.
160  * Type: Method
161  * Format: "Signature"
162  */
163 #define LENOVO_SAVE_BIOS_SETTING_CERT_GUID "C050FB9D-DF5F-4606-B066-9EFC401B2551"
164 
165 /*
166  * Name: CertThumbprint
167  * Description: Display Certificate thumbprints
168  * Type: Query
169  * Returns: MD5, SHA1 & SHA256 thumbprints
170  */
171 #define LENOVO_CERT_THUMBPRINT_GUID "C59119ED-1C0D-4806-A8E9-59AA318176C4"
172 
173 #define TLMI_POP_PWD  BIT(0) /* Supervisor */
174 #define TLMI_PAP_PWD  BIT(1) /* Power-on */
175 #define TLMI_HDD_PWD  BIT(2) /* HDD/NVME */
176 #define TLMI_SMP_PWD  BIT(6) /* System Management */
177 #define TLMI_CERT_SVC BIT(7) /* Admin Certificate Based */
178 #define TLMI_CERT_SMC BIT(8) /* System Certificate Based */
179 
180 static const struct tlmi_err_codes tlmi_errs[] = {
181 	{"Success", 0},
182 	{"Not Supported", -EOPNOTSUPP},
183 	{"Invalid Parameter", -EINVAL},
184 	{"Access Denied", -EACCES},
185 	{"System Busy", -EBUSY},
186 };
187 
188 static const char * const encoding_options[] = {
189 	[TLMI_ENCODING_ASCII] = "ascii",
190 	[TLMI_ENCODING_SCANCODE] = "scancode",
191 };
192 static const char * const level_options[] = {
193 	[TLMI_LEVEL_USER] = "user",
194 	[TLMI_LEVEL_MASTER] = "master",
195 };
196 static struct think_lmi tlmi_priv;
197 static DEFINE_MUTEX(tlmi_mutex);
198 
to_tlmi_pwd_setting(struct kobject * kobj)199 static inline struct tlmi_pwd_setting *to_tlmi_pwd_setting(struct kobject *kobj)
200 {
201 	return container_of(kobj, struct tlmi_pwd_setting, kobj);
202 }
203 
to_tlmi_attr_setting(struct kobject * kobj)204 static inline struct tlmi_attr_setting *to_tlmi_attr_setting(struct kobject *kobj)
205 {
206 	return container_of(kobj, struct tlmi_attr_setting, kobj);
207 }
208 
209 /* Convert BIOS WMI error string to suitable error code */
tlmi_errstr_to_err(const char * errstr)210 static int tlmi_errstr_to_err(const char *errstr)
211 {
212 	int i;
213 
214 	for (i = 0; i < sizeof(tlmi_errs)/sizeof(struct tlmi_err_codes); i++) {
215 		if (!strcmp(tlmi_errs[i].err_str, errstr))
216 			return tlmi_errs[i].err_code;
217 	}
218 	return -EPERM;
219 }
220 
221 /* Extract error string from WMI return buffer */
tlmi_extract_error(const struct acpi_buffer * output)222 static int tlmi_extract_error(const struct acpi_buffer *output)
223 {
224 	const union acpi_object *obj;
225 
226 	obj = output->pointer;
227 	if (!obj)
228 		return -ENOMEM;
229 	if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer)
230 		return -EIO;
231 
232 	return tlmi_errstr_to_err(obj->string.pointer);
233 }
234 
235 /* Utility function to execute WMI call to BIOS */
tlmi_simple_call(const char * guid,const char * arg)236 static int tlmi_simple_call(const char *guid, const char *arg)
237 {
238 	const struct acpi_buffer input = { strlen(arg), (char *)arg };
239 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
240 	acpi_status status;
241 	int i, err;
242 
243 	/*
244 	 * Duplicated call required to match BIOS workaround for behavior
245 	 * seen when WMI accessed via scripting on other OS.
246 	 */
247 	for (i = 0; i < 2; i++) {
248 		/* (re)initialize output buffer to default state */
249 		output.length = ACPI_ALLOCATE_BUFFER;
250 		output.pointer = NULL;
251 
252 		status = wmi_evaluate_method(guid, 0, 0, &input, &output);
253 		if (ACPI_FAILURE(status)) {
254 			kfree(output.pointer);
255 			return -EIO;
256 		}
257 		err = tlmi_extract_error(&output);
258 		kfree(output.pointer);
259 		if (err)
260 			return err;
261 	}
262 	return 0;
263 }
264 
265 /* Extract output string from WMI return buffer */
tlmi_extract_output_string(const struct acpi_buffer * output,char ** string)266 static int tlmi_extract_output_string(const struct acpi_buffer *output,
267 				      char **string)
268 {
269 	const union acpi_object *obj;
270 	char *s;
271 
272 	obj = output->pointer;
273 	if (!obj)
274 		return -ENOMEM;
275 	if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer)
276 		return -EIO;
277 
278 	s = kstrdup(obj->string.pointer, GFP_KERNEL);
279 	if (!s)
280 		return -ENOMEM;
281 	*string = s;
282 	return 0;
283 }
284 
285 /* ------ Core interface functions ------------*/
286 
287 /* Get password settings from BIOS */
tlmi_get_pwd_settings(struct tlmi_pwdcfg * pwdcfg)288 static int tlmi_get_pwd_settings(struct tlmi_pwdcfg *pwdcfg)
289 {
290 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
291 	const union acpi_object *obj;
292 	acpi_status status;
293 	int copy_size;
294 
295 	if (!tlmi_priv.can_get_password_settings)
296 		return -EOPNOTSUPP;
297 
298 	status = wmi_query_block(LENOVO_BIOS_PASSWORD_SETTINGS_GUID, 0,
299 				 &output);
300 	if (ACPI_FAILURE(status))
301 		return -EIO;
302 
303 	obj = output.pointer;
304 	if (!obj)
305 		return -ENOMEM;
306 	if (obj->type != ACPI_TYPE_BUFFER || !obj->buffer.pointer) {
307 		kfree(obj);
308 		return -EIO;
309 	}
310 	/*
311 	 * The size of thinkpad_wmi_pcfg on ThinkStation is larger than ThinkPad.
312 	 * To make the driver compatible on different brands, we permit it to get
313 	 * the data in below case.
314 	 * Settings must have at minimum the core fields available
315 	 */
316 	if (obj->buffer.length < sizeof(struct tlmi_pwdcfg_core)) {
317 		pr_warn("Unknown pwdcfg buffer length %d\n", obj->buffer.length);
318 		kfree(obj);
319 		return -EIO;
320 	}
321 
322 	copy_size = min_t(size_t, obj->buffer.length, sizeof(struct tlmi_pwdcfg));
323 
324 	memcpy(pwdcfg, obj->buffer.pointer, copy_size);
325 	kfree(obj);
326 
327 	if (WARN_ON(pwdcfg->core.max_length >= TLMI_PWD_BUFSIZE))
328 		pwdcfg->core.max_length = TLMI_PWD_BUFSIZE - 1;
329 	return 0;
330 }
331 
tlmi_save_bios_settings(const char * password)332 static int tlmi_save_bios_settings(const char *password)
333 {
334 	return tlmi_simple_call(LENOVO_SAVE_BIOS_SETTINGS_GUID,
335 				password);
336 }
337 
tlmi_opcode_setting(char * setting,const char * value)338 static int tlmi_opcode_setting(char *setting, const char *value)
339 {
340 	char *opcode_str;
341 	int ret;
342 
343 	opcode_str = kasprintf(GFP_KERNEL, "%s:%s;", setting, value);
344 	if (!opcode_str)
345 		return -ENOMEM;
346 
347 	ret = tlmi_simple_call(LENOVO_OPCODE_IF_GUID, opcode_str);
348 	kfree(opcode_str);
349 	return ret;
350 }
351 
tlmi_setting(int item,char ** value,const char * guid_string)352 static int tlmi_setting(int item, char **value, const char *guid_string)
353 {
354 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
355 	acpi_status status;
356 	int ret;
357 
358 	status = wmi_query_block(guid_string, item, &output);
359 	if (ACPI_FAILURE(status)) {
360 		kfree(output.pointer);
361 		return -EIO;
362 	}
363 
364 	ret = tlmi_extract_output_string(&output, value);
365 	kfree(output.pointer);
366 	return ret;
367 }
368 
tlmi_get_bios_selections(const char * item,char ** value)369 static int tlmi_get_bios_selections(const char *item, char **value)
370 {
371 	const struct acpi_buffer input = { strlen(item), (char *)item };
372 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
373 	acpi_status status;
374 	int ret;
375 
376 	status = wmi_evaluate_method(LENOVO_GET_BIOS_SELECTIONS_GUID,
377 				     0, 0, &input, &output);
378 
379 	if (ACPI_FAILURE(status)) {
380 		kfree(output.pointer);
381 		return -EIO;
382 	}
383 
384 	ret = tlmi_extract_output_string(&output, value);
385 	kfree(output.pointer);
386 	return ret;
387 }
388 
389 /* ---- Authentication sysfs --------------------------------------------------------- */
is_enabled_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)390 static ssize_t is_enabled_show(struct kobject *kobj, struct kobj_attribute *attr,
391 					  char *buf)
392 {
393 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
394 
395 	return sysfs_emit(buf, "%d\n", setting->pwd_enabled || setting->cert_installed);
396 }
397 
398 static struct kobj_attribute auth_is_pass_set = __ATTR_RO(is_enabled);
399 
current_password_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)400 static ssize_t current_password_store(struct kobject *kobj,
401 				      struct kobj_attribute *attr,
402 				      const char *buf, size_t count)
403 {
404 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
405 	size_t pwdlen;
406 
407 	pwdlen = strlen(buf);
408 	/* pwdlen == 0 is allowed to clear the password */
409 	if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen)))
410 		return -EINVAL;
411 
412 	strscpy(setting->password, buf, setting->maxlen);
413 	/* Strip out CR if one is present, setting password won't work if it is present */
414 	strreplace(setting->password, '\n', '\0');
415 	return count;
416 }
417 
418 static struct kobj_attribute auth_current_password = __ATTR_WO(current_password);
419 
new_password_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)420 static ssize_t new_password_store(struct kobject *kobj,
421 				  struct kobj_attribute *attr,
422 				  const char *buf, size_t count)
423 {
424 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
425 	char *auth_str, *new_pwd;
426 	size_t pwdlen;
427 	int ret;
428 
429 	if (!capable(CAP_SYS_ADMIN))
430 		return -EPERM;
431 
432 	if (!tlmi_priv.can_set_bios_password)
433 		return -EOPNOTSUPP;
434 
435 	/* Strip out CR if one is present, setting password won't work if it is present */
436 	new_pwd = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
437 	if (!new_pwd)
438 		return -ENOMEM;
439 
440 	/* Use lock in case multiple WMI operations needed */
441 	mutex_lock(&tlmi_mutex);
442 
443 	pwdlen = strlen(new_pwd);
444 	/* pwdlen == 0 is allowed to clear the password */
445 	if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen))) {
446 		ret = -EINVAL;
447 		goto out;
448 	}
449 
450 	/* If opcode support is present use that interface */
451 	if (tlmi_priv.opcode_support) {
452 		char pwd_type[8];
453 
454 		/* Special handling required for HDD and NVMe passwords */
455 		if (setting == tlmi_priv.pwd_hdd) {
456 			if (setting->level == TLMI_LEVEL_USER)
457 				sprintf(pwd_type, "uhdp%d", setting->index);
458 			else
459 				sprintf(pwd_type, "mhdp%d", setting->index);
460 		} else if (setting == tlmi_priv.pwd_nvme) {
461 			if (setting->level == TLMI_LEVEL_USER)
462 				sprintf(pwd_type, "udrp%d", setting->index);
463 			else
464 				sprintf(pwd_type, "adrp%d", setting->index);
465 		} else {
466 			sprintf(pwd_type, "%s", setting->pwd_type);
467 		}
468 
469 		ret = tlmi_opcode_setting("WmiOpcodePasswordType", pwd_type);
470 		if (ret)
471 			goto out;
472 
473 		/*
474 		 * Note admin password is not always required if SMPControl enabled in BIOS,
475 		 * So only set if it's configured.
476 		 * Let BIOS figure it out - we'll get an error if operation is not permitted
477 		 */
478 		if (tlmi_priv.pwd_admin->pwd_enabled && strlen(tlmi_priv.pwd_admin->password)) {
479 			ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
480 					tlmi_priv.pwd_admin->password);
481 			if (ret)
482 				goto out;
483 		}
484 		ret = tlmi_opcode_setting("WmiOpcodePasswordCurrent01", setting->password);
485 		if (ret)
486 			goto out;
487 		ret = tlmi_opcode_setting("WmiOpcodePasswordNew01", new_pwd);
488 		if (ret)
489 			goto out;
490 		ret = tlmi_simple_call(LENOVO_OPCODE_IF_GUID, "WmiOpcodePasswordSetUpdate;");
491 	} else {
492 		/* Format: 'PasswordType,CurrentPw,NewPw,Encoding,KbdLang;' */
493 		auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s,%s,%s;",
494 				setting->pwd_type, setting->password, new_pwd,
495 				encoding_options[setting->encoding], setting->kbdlang);
496 		if (!auth_str) {
497 			ret = -ENOMEM;
498 			goto out;
499 		}
500 		ret = tlmi_simple_call(LENOVO_SET_BIOS_PASSWORD_GUID, auth_str);
501 		kfree(auth_str);
502 	}
503 out:
504 	mutex_unlock(&tlmi_mutex);
505 	kfree(new_pwd);
506 	return ret ?: count;
507 }
508 
509 static struct kobj_attribute auth_new_password = __ATTR_WO(new_password);
510 
min_password_length_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)511 static ssize_t min_password_length_show(struct kobject *kobj, struct kobj_attribute *attr,
512 			 char *buf)
513 {
514 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
515 
516 	return sysfs_emit(buf, "%d\n", setting->minlen);
517 }
518 
519 static struct kobj_attribute auth_min_pass_length = __ATTR_RO(min_password_length);
520 
max_password_length_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)521 static ssize_t max_password_length_show(struct kobject *kobj, struct kobj_attribute *attr,
522 			 char *buf)
523 {
524 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
525 
526 	return sysfs_emit(buf, "%d\n", setting->maxlen);
527 }
528 static struct kobj_attribute auth_max_pass_length = __ATTR_RO(max_password_length);
529 
mechanism_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)530 static ssize_t mechanism_show(struct kobject *kobj, struct kobj_attribute *attr,
531 			 char *buf)
532 {
533 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
534 
535 	if (setting->cert_installed)
536 		return sysfs_emit(buf, "certificate\n");
537 	return sysfs_emit(buf, "password\n");
538 }
539 static struct kobj_attribute auth_mechanism = __ATTR_RO(mechanism);
540 
encoding_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)541 static ssize_t encoding_show(struct kobject *kobj, struct kobj_attribute *attr,
542 			 char *buf)
543 {
544 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
545 
546 	return sysfs_emit(buf, "%s\n", encoding_options[setting->encoding]);
547 }
548 
encoding_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)549 static ssize_t encoding_store(struct kobject *kobj,
550 				  struct kobj_attribute *attr,
551 				  const char *buf, size_t count)
552 {
553 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
554 	int i;
555 
556 	/* Scan for a matching profile */
557 	i = sysfs_match_string(encoding_options, buf);
558 	if (i < 0)
559 		return -EINVAL;
560 
561 	setting->encoding = i;
562 	return count;
563 }
564 
565 static struct kobj_attribute auth_encoding = __ATTR_RW(encoding);
566 
kbdlang_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)567 static ssize_t kbdlang_show(struct kobject *kobj, struct kobj_attribute *attr,
568 			 char *buf)
569 {
570 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
571 
572 	return sysfs_emit(buf, "%s\n", setting->kbdlang);
573 }
574 
kbdlang_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)575 static ssize_t kbdlang_store(struct kobject *kobj,
576 				  struct kobj_attribute *attr,
577 				  const char *buf, size_t count)
578 {
579 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
580 	int length;
581 
582 	/* Calculate length till '\n' or terminating 0 */
583 	length = strchrnul(buf, '\n') - buf;
584 	if (!length || length >= TLMI_LANG_MAXLEN)
585 		return -EINVAL;
586 
587 	memcpy(setting->kbdlang, buf, length);
588 	setting->kbdlang[length] = '\0';
589 	return count;
590 }
591 
592 static struct kobj_attribute auth_kbdlang = __ATTR_RW(kbdlang);
593 
role_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)594 static ssize_t role_show(struct kobject *kobj, struct kobj_attribute *attr,
595 			 char *buf)
596 {
597 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
598 
599 	return sysfs_emit(buf, "%s\n", setting->role);
600 }
601 static struct kobj_attribute auth_role = __ATTR_RO(role);
602 
index_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)603 static ssize_t index_show(struct kobject *kobj, struct kobj_attribute *attr,
604 			 char *buf)
605 {
606 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
607 
608 	return sysfs_emit(buf, "%d\n", setting->index);
609 }
610 
index_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)611 static ssize_t index_store(struct kobject *kobj,
612 				  struct kobj_attribute *attr,
613 				  const char *buf, size_t count)
614 {
615 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
616 	int err, val;
617 
618 	err = kstrtoint(buf, 10, &val);
619 	if (err < 0)
620 		return err;
621 
622 	if (val < 0 || val > TLMI_INDEX_MAX)
623 		return -EINVAL;
624 
625 	setting->index = val;
626 	return count;
627 }
628 
629 static struct kobj_attribute auth_index = __ATTR_RW(index);
630 
level_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)631 static ssize_t level_show(struct kobject *kobj, struct kobj_attribute *attr,
632 			 char *buf)
633 {
634 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
635 
636 	return sysfs_emit(buf, "%s\n", level_options[setting->level]);
637 }
638 
level_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)639 static ssize_t level_store(struct kobject *kobj,
640 				  struct kobj_attribute *attr,
641 				  const char *buf, size_t count)
642 {
643 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
644 	int i;
645 
646 	/* Scan for a matching profile */
647 	i = sysfs_match_string(level_options, buf);
648 	if (i < 0)
649 		return -EINVAL;
650 
651 	setting->level = i;
652 	return count;
653 }
654 
655 static struct kobj_attribute auth_level = __ATTR_RW(level);
656 
cert_command(struct tlmi_pwd_setting * setting,const char * arg1,const char * arg2)657 static char *cert_command(struct tlmi_pwd_setting *setting, const char *arg1, const char *arg2)
658 {
659 	/* Prepend with SVC or SMC if multicert supported */
660 	if (tlmi_priv.pwdcfg.core.password_mode >= TLMI_PWDCFG_MODE_MULTICERT)
661 		return kasprintf(GFP_KERNEL, "%s,%s,%s",
662 				 setting == tlmi_priv.pwd_admin ? "SVC" : "SMC",
663 				 arg1, arg2);
664 	else
665 		return kasprintf(GFP_KERNEL, "%s,%s", arg1, arg2);
666 }
667 
cert_thumbprint(char * buf,const char * arg,int count)668 static ssize_t cert_thumbprint(char *buf, const char *arg, int count)
669 {
670 	const struct acpi_buffer input = { strlen(arg), (char *)arg };
671 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
672 	const union acpi_object *obj;
673 	acpi_status status;
674 
675 	status = wmi_evaluate_method(LENOVO_CERT_THUMBPRINT_GUID, 0, 0, &input, &output);
676 	if (ACPI_FAILURE(status)) {
677 		kfree(output.pointer);
678 		return -EIO;
679 	}
680 	obj = output.pointer;
681 	if (!obj)
682 		return -ENOMEM;
683 	if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer) {
684 		kfree(output.pointer);
685 		return -EIO;
686 	}
687 	count += sysfs_emit_at(buf, count, "%s : %s\n", arg, (char *)obj->string.pointer);
688 	kfree(output.pointer);
689 
690 	return count;
691 }
692 
693 static char *thumbtypes[] = {"Md5", "Sha1", "Sha256"};
694 
certificate_thumbprint_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)695 static ssize_t certificate_thumbprint_show(struct kobject *kobj, struct kobj_attribute *attr,
696 			 char *buf)
697 {
698 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
699 	unsigned int i;
700 	int count = 0;
701 	char *wmistr;
702 
703 	if (!tlmi_priv.certificate_support || !setting->cert_installed)
704 		return -EOPNOTSUPP;
705 
706 	for (i = 0; i < ARRAY_SIZE(thumbtypes); i++) {
707 		if (tlmi_priv.pwdcfg.core.password_mode >= TLMI_PWDCFG_MODE_MULTICERT) {
708 			/* Format: 'SVC | SMC, Thumbtype' */
709 			wmistr = kasprintf(GFP_KERNEL, "%s,%s",
710 					   setting == tlmi_priv.pwd_admin ? "SVC" : "SMC",
711 					   thumbtypes[i]);
712 		} else {
713 			/* Format: 'Thumbtype' */
714 			wmistr = kasprintf(GFP_KERNEL, "%s", thumbtypes[i]);
715 		}
716 		if (!wmistr)
717 			return -ENOMEM;
718 		count += cert_thumbprint(buf, wmistr, count);
719 		kfree(wmistr);
720 	}
721 
722 	return count;
723 }
724 
725 static struct kobj_attribute auth_cert_thumb = __ATTR_RO(certificate_thumbprint);
726 
cert_to_password_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)727 static ssize_t cert_to_password_store(struct kobject *kobj,
728 				  struct kobj_attribute *attr,
729 				  const char *buf, size_t count)
730 {
731 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
732 	char *auth_str, *passwd;
733 	int ret;
734 
735 	if (!capable(CAP_SYS_ADMIN))
736 		return -EPERM;
737 
738 	if (!tlmi_priv.certificate_support)
739 		return -EOPNOTSUPP;
740 
741 	if (!setting->cert_installed)
742 		return -EINVAL;
743 
744 	if (!setting->signature || !setting->signature[0])
745 		return -EACCES;
746 
747 	/* Strip out CR if one is present */
748 	passwd = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
749 	if (!passwd)
750 		return -ENOMEM;
751 
752 	/* Format: 'Password,Signature' */
753 	auth_str = cert_command(setting, passwd, setting->signature);
754 	if (!auth_str) {
755 		kfree_sensitive(passwd);
756 		return -ENOMEM;
757 	}
758 	ret = tlmi_simple_call(LENOVO_CERT_TO_PASSWORD_GUID, auth_str);
759 	kfree(auth_str);
760 	kfree_sensitive(passwd);
761 
762 	return ret ?: count;
763 }
764 
765 static struct kobj_attribute auth_cert_to_password = __ATTR_WO(cert_to_password);
766 
767 enum cert_install_mode {
768 	TLMI_CERT_INSTALL,
769 	TLMI_CERT_UPDATE,
770 };
771 
certificate_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)772 static ssize_t certificate_store(struct kobject *kobj,
773 				  struct kobj_attribute *attr,
774 				  const char *buf, size_t count)
775 {
776 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
777 	enum cert_install_mode install_mode = TLMI_CERT_INSTALL;
778 	char *auth_str, *new_cert;
779 	char *signature;
780 	char *guid;
781 	int ret;
782 
783 	if (!capable(CAP_SYS_ADMIN))
784 		return -EPERM;
785 
786 	if (!tlmi_priv.certificate_support)
787 		return -EOPNOTSUPP;
788 
789 	/* If empty then clear installed certificate */
790 	if ((buf[0] == '\0') || (buf[0] == '\n')) { /* Clear installed certificate */
791 		/* Check that signature is set */
792 		if (!setting->signature || !setting->signature[0])
793 			return -EACCES;
794 
795 		/* Format: 'serial#, signature' */
796 		auth_str = cert_command(setting,
797 					dmi_get_system_info(DMI_PRODUCT_SERIAL),
798 					setting->signature);
799 		if (!auth_str)
800 			return -ENOMEM;
801 
802 		ret = tlmi_simple_call(LENOVO_CLEAR_BIOS_CERT_GUID, auth_str);
803 		kfree(auth_str);
804 
805 		return ret ?: count;
806 	}
807 
808 	/* Strip out CR if one is present */
809 	new_cert = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
810 	if (!new_cert)
811 		return -ENOMEM;
812 
813 	if (setting->cert_installed) {
814 		/* Certificate is installed so this is an update */
815 		install_mode = TLMI_CERT_UPDATE;
816 		/* If admin account enabled - need to use its signature */
817 		if (tlmi_priv.pwd_admin->pwd_enabled)
818 			signature = tlmi_priv.pwd_admin->signature;
819 		else
820 			signature = setting->signature;
821 	} else { /* Cert install */
822 		/* Check if SMC and SVC already installed */
823 		if ((setting == tlmi_priv.pwd_system) && tlmi_priv.pwd_admin->cert_installed) {
824 			/* This gets treated as a cert update */
825 			install_mode = TLMI_CERT_UPDATE;
826 			signature = tlmi_priv.pwd_admin->signature;
827 		} else { /* Regular cert install */
828 			install_mode = TLMI_CERT_INSTALL;
829 			signature = setting->signature;
830 		}
831 	}
832 
833 	if (install_mode == TLMI_CERT_UPDATE) {
834 		/* This is a certificate update */
835 		if (!signature || !signature[0]) {
836 			kfree(new_cert);
837 			return -EACCES;
838 		}
839 		guid = LENOVO_UPDATE_BIOS_CERT_GUID;
840 		/* Format: 'Certificate,Signature' */
841 		auth_str = cert_command(setting, new_cert, signature);
842 	} else {
843 		/* This is a fresh install */
844 		/* To set admin cert, a password must be enabled */
845 		if ((setting == tlmi_priv.pwd_admin) &&
846 		    (!setting->pwd_enabled || !setting->password[0])) {
847 			kfree(new_cert);
848 			return -EACCES;
849 		}
850 		guid = LENOVO_SET_BIOS_CERT_GUID;
851 		/* Format: 'Certificate, password' */
852 		auth_str = cert_command(setting, new_cert, setting->password);
853 	}
854 	kfree(new_cert);
855 	if (!auth_str)
856 		return -ENOMEM;
857 
858 	ret = tlmi_simple_call(guid, auth_str);
859 	kfree(auth_str);
860 
861 	return ret ?: count;
862 }
863 
864 static struct kobj_attribute auth_certificate = __ATTR_WO(certificate);
865 
signature_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)866 static ssize_t signature_store(struct kobject *kobj,
867 				  struct kobj_attribute *attr,
868 				  const char *buf, size_t count)
869 {
870 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
871 	char *new_signature;
872 
873 	if (!capable(CAP_SYS_ADMIN))
874 		return -EPERM;
875 
876 	if (!tlmi_priv.certificate_support)
877 		return -EOPNOTSUPP;
878 
879 	/* Strip out CR if one is present */
880 	new_signature = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
881 	if (!new_signature)
882 		return -ENOMEM;
883 
884 	/* Free any previous signature */
885 	kfree(setting->signature);
886 	setting->signature = new_signature;
887 
888 	return count;
889 }
890 
891 static struct kobj_attribute auth_signature = __ATTR_WO(signature);
892 
save_signature_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)893 static ssize_t save_signature_store(struct kobject *kobj,
894 				  struct kobj_attribute *attr,
895 				  const char *buf, size_t count)
896 {
897 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
898 	char *new_signature;
899 
900 	if (!capable(CAP_SYS_ADMIN))
901 		return -EPERM;
902 
903 	if (!tlmi_priv.certificate_support)
904 		return -EOPNOTSUPP;
905 
906 	/* Strip out CR if one is present */
907 	new_signature = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
908 	if (!new_signature)
909 		return -ENOMEM;
910 
911 	/* Free any previous signature */
912 	kfree(setting->save_signature);
913 	setting->save_signature = new_signature;
914 
915 	return count;
916 }
917 
918 static struct kobj_attribute auth_save_signature = __ATTR_WO(save_signature);
919 
auth_attr_is_visible(struct kobject * kobj,struct attribute * attr,int n)920 static umode_t auth_attr_is_visible(struct kobject *kobj,
921 					     struct attribute *attr, int n)
922 {
923 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
924 
925 	/* We only want to display level and index settings on HDD/NVMe */
926 	if (attr == &auth_index.attr || attr == &auth_level.attr) {
927 		if ((setting == tlmi_priv.pwd_hdd) || (setting == tlmi_priv.pwd_nvme))
928 			return attr->mode;
929 		return 0;
930 	}
931 
932 	/* We only display certificates, if supported */
933 	if (attr == &auth_certificate.attr ||
934 	    attr == &auth_signature.attr ||
935 	    attr == &auth_save_signature.attr ||
936 	    attr == &auth_cert_thumb.attr ||
937 	    attr == &auth_cert_to_password.attr) {
938 		if (tlmi_priv.certificate_support) {
939 			if (setting == tlmi_priv.pwd_admin)
940 				return attr->mode;
941 			if ((tlmi_priv.pwdcfg.core.password_mode >= TLMI_PWDCFG_MODE_MULTICERT) &&
942 			    (setting == tlmi_priv.pwd_system))
943 				return attr->mode;
944 		}
945 		return 0;
946 	}
947 
948 	/* Don't display un-needed settings if opcode available */
949 	if ((attr == &auth_encoding.attr || attr == &auth_kbdlang.attr) &&
950 	    tlmi_priv.opcode_support)
951 		return 0;
952 
953 	return attr->mode;
954 }
955 
956 static struct attribute *auth_attrs[] = {
957 	&auth_is_pass_set.attr,
958 	&auth_min_pass_length.attr,
959 	&auth_max_pass_length.attr,
960 	&auth_current_password.attr,
961 	&auth_new_password.attr,
962 	&auth_role.attr,
963 	&auth_mechanism.attr,
964 	&auth_encoding.attr,
965 	&auth_kbdlang.attr,
966 	&auth_index.attr,
967 	&auth_level.attr,
968 	&auth_certificate.attr,
969 	&auth_signature.attr,
970 	&auth_save_signature.attr,
971 	&auth_cert_thumb.attr,
972 	&auth_cert_to_password.attr,
973 	NULL
974 };
975 
976 static const struct attribute_group auth_attr_group = {
977 	.is_visible = auth_attr_is_visible,
978 	.attrs = auth_attrs,
979 };
980 
981 /* ---- Attributes sysfs --------------------------------------------------------- */
display_name_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)982 static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *attr,
983 		char *buf)
984 {
985 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
986 
987 	return sysfs_emit(buf, "%s\n", setting->display_name);
988 }
989 
current_value_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)990 static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
991 {
992 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
993 	char *item, *value;
994 	int ret;
995 
996 	ret = tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID);
997 	if (ret)
998 		return ret;
999 
1000 	/* validate and split from `item,value` -> `value` */
1001 	value = strpbrk(item, ",");
1002 	if (!value || value == item || !strlen(value + 1))
1003 		ret = -EINVAL;
1004 	else {
1005 		/* On Workstations remove the Options part after the value */
1006 		strreplace(value, ';', '\0');
1007 		ret = sysfs_emit(buf, "%s\n", value + 1);
1008 	}
1009 	kfree(item);
1010 
1011 	return ret;
1012 }
1013 
possible_values_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)1014 static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1015 {
1016 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
1017 
1018 	return sysfs_emit(buf, "%s\n", setting->possible_values);
1019 }
1020 
type_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)1021 static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr,
1022 		char *buf)
1023 {
1024 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
1025 
1026 	if (setting->possible_values) {
1027 		/* Figure out what setting type is as BIOS does not return this */
1028 		if (strchr(setting->possible_values, ';'))
1029 			return sysfs_emit(buf, "enumeration\n");
1030 	}
1031 	/* Anything else is going to be a string */
1032 	return sysfs_emit(buf, "string\n");
1033 }
1034 
current_value_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)1035 static ssize_t current_value_store(struct kobject *kobj,
1036 		struct kobj_attribute *attr,
1037 		const char *buf, size_t count)
1038 {
1039 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
1040 	char *set_str = NULL, *new_setting = NULL;
1041 	char *auth_str = NULL;
1042 	int ret;
1043 
1044 	if (!tlmi_priv.can_set_bios_settings)
1045 		return -EOPNOTSUPP;
1046 
1047 	/*
1048 	 * If we are using bulk saves a reboot should be done once save has
1049 	 * been called
1050 	 */
1051 	if (tlmi_priv.save_mode == TLMI_SAVE_BULK && tlmi_priv.reboot_required)
1052 		return -EPERM;
1053 
1054 	/* Strip out CR if one is present */
1055 	new_setting = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
1056 	if (!new_setting)
1057 		return -ENOMEM;
1058 
1059 	/* Use lock in case multiple WMI operations needed */
1060 	mutex_lock(&tlmi_mutex);
1061 
1062 	/* Check if certificate authentication is enabled and active */
1063 	if (tlmi_priv.certificate_support && tlmi_priv.pwd_admin->cert_installed) {
1064 		if (!tlmi_priv.pwd_admin->signature || !tlmi_priv.pwd_admin->save_signature) {
1065 			ret = -EINVAL;
1066 			goto out;
1067 		}
1068 		set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->display_name,
1069 					new_setting, tlmi_priv.pwd_admin->signature);
1070 		if (!set_str) {
1071 			ret = -ENOMEM;
1072 			goto out;
1073 		}
1074 
1075 		ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTING_CERT_GUID, set_str);
1076 		if (ret)
1077 			goto out;
1078 		if (tlmi_priv.save_mode == TLMI_SAVE_BULK)
1079 			tlmi_priv.save_required = true;
1080 		else
1081 			ret = tlmi_simple_call(LENOVO_SAVE_BIOS_SETTING_CERT_GUID,
1082 					       tlmi_priv.pwd_admin->save_signature);
1083 	} else if (tlmi_priv.opcode_support) {
1084 		/*
1085 		 * If opcode support is present use that interface.
1086 		 * Note - this sets the variable and then the password as separate
1087 		 * WMI calls. Function tlmi_save_bios_settings will error if the
1088 		 * password is incorrect.
1089 		 * Workstation's require the opcode to be set before changing the
1090 		 * attribute.
1091 		 */
1092 		if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
1093 			ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
1094 						  tlmi_priv.pwd_admin->password);
1095 			if (ret)
1096 				goto out;
1097 		}
1098 
1099 		set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->display_name,
1100 				    new_setting);
1101 		if (!set_str) {
1102 			ret = -ENOMEM;
1103 			goto out;
1104 		}
1105 
1106 		ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTINGS_GUID, set_str);
1107 		if (ret)
1108 			goto out;
1109 
1110 		if (tlmi_priv.save_mode == TLMI_SAVE_BULK)
1111 			tlmi_priv.save_required = true;
1112 		else
1113 			ret = tlmi_save_bios_settings("");
1114 	} else { /* old non-opcode based authentication method (deprecated) */
1115 		if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
1116 			auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
1117 					tlmi_priv.pwd_admin->password,
1118 					encoding_options[tlmi_priv.pwd_admin->encoding],
1119 					tlmi_priv.pwd_admin->kbdlang);
1120 			if (!auth_str) {
1121 				ret = -ENOMEM;
1122 				goto out;
1123 			}
1124 		}
1125 
1126 		if (auth_str)
1127 			set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->display_name,
1128 					new_setting, auth_str);
1129 		else
1130 			set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->display_name,
1131 					new_setting);
1132 		if (!set_str) {
1133 			ret = -ENOMEM;
1134 			goto out;
1135 		}
1136 
1137 		ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTINGS_GUID, set_str);
1138 		if (ret)
1139 			goto out;
1140 
1141 		if (tlmi_priv.save_mode == TLMI_SAVE_BULK) {
1142 			tlmi_priv.save_required = true;
1143 		} else {
1144 			if (auth_str)
1145 				ret = tlmi_save_bios_settings(auth_str);
1146 			else
1147 				ret = tlmi_save_bios_settings("");
1148 		}
1149 	}
1150 	if (!ret && !tlmi_priv.pending_changes) {
1151 		tlmi_priv.pending_changes = true;
1152 		/* let userland know it may need to check reboot pending again */
1153 		kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
1154 	}
1155 out:
1156 	mutex_unlock(&tlmi_mutex);
1157 	kfree(auth_str);
1158 	kfree(set_str);
1159 	kfree(new_setting);
1160 	return ret ?: count;
1161 }
1162 
1163 static struct kobj_attribute attr_displ_name = __ATTR_RO(display_name);
1164 
1165 static struct kobj_attribute attr_possible_values = __ATTR_RO(possible_values);
1166 
1167 static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 0600);
1168 
1169 static struct kobj_attribute attr_type = __ATTR_RO(type);
1170 
attr_is_visible(struct kobject * kobj,struct attribute * attr,int n)1171 static umode_t attr_is_visible(struct kobject *kobj,
1172 					     struct attribute *attr, int n)
1173 {
1174 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
1175 
1176 	/* We don't want to display possible_values attributes if not available */
1177 	if ((attr == &attr_possible_values.attr) && (!setting->possible_values))
1178 		return 0;
1179 
1180 	return attr->mode;
1181 }
1182 
1183 static struct attribute *tlmi_attrs[] = {
1184 	&attr_displ_name.attr,
1185 	&attr_current_val.attr,
1186 	&attr_possible_values.attr,
1187 	&attr_type.attr,
1188 	NULL
1189 };
1190 
1191 static const struct attribute_group tlmi_attr_group = {
1192 	.is_visible = attr_is_visible,
1193 	.attrs = tlmi_attrs,
1194 };
1195 
tlmi_attr_setting_release(struct kobject * kobj)1196 static void tlmi_attr_setting_release(struct kobject *kobj)
1197 {
1198 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
1199 
1200 	kfree(setting->possible_values);
1201 	kfree(setting);
1202 }
1203 
tlmi_pwd_setting_release(struct kobject * kobj)1204 static void tlmi_pwd_setting_release(struct kobject *kobj)
1205 {
1206 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
1207 
1208 	kfree(setting);
1209 }
1210 
1211 static const struct kobj_type tlmi_attr_setting_ktype = {
1212 	.release        = &tlmi_attr_setting_release,
1213 	.sysfs_ops	= &kobj_sysfs_ops,
1214 };
1215 
1216 static const struct kobj_type tlmi_pwd_setting_ktype = {
1217 	.release        = &tlmi_pwd_setting_release,
1218 	.sysfs_ops	= &kobj_sysfs_ops,
1219 };
1220 
pending_reboot_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)1221 static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr,
1222 				   char *buf)
1223 {
1224 	return sprintf(buf, "%d\n", tlmi_priv.pending_changes);
1225 }
1226 
1227 static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
1228 
1229 static const char * const save_mode_strings[] = {
1230 	[TLMI_SAVE_SINGLE] = "single",
1231 	[TLMI_SAVE_BULK] = "bulk",
1232 	[TLMI_SAVE_SAVE] = "save"
1233 };
1234 
save_settings_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)1235 static ssize_t save_settings_show(struct kobject *kobj, struct kobj_attribute *attr,
1236 				  char *buf)
1237 {
1238 	/* Check that setting is valid */
1239 	if (WARN_ON(tlmi_priv.save_mode < TLMI_SAVE_SINGLE ||
1240 		    tlmi_priv.save_mode > TLMI_SAVE_BULK))
1241 		return -EIO;
1242 	return sysfs_emit(buf, "%s\n", save_mode_strings[tlmi_priv.save_mode]);
1243 }
1244 
save_settings_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)1245 static ssize_t save_settings_store(struct kobject *kobj, struct kobj_attribute *attr,
1246 				   const char *buf, size_t count)
1247 {
1248 	char *auth_str = NULL;
1249 	int ret = 0;
1250 	int cmd;
1251 
1252 	cmd = sysfs_match_string(save_mode_strings, buf);
1253 	if (cmd < 0)
1254 		return cmd;
1255 
1256 	/* Use lock in case multiple WMI operations needed */
1257 	mutex_lock(&tlmi_mutex);
1258 
1259 	switch (cmd) {
1260 	case TLMI_SAVE_SINGLE:
1261 	case TLMI_SAVE_BULK:
1262 		tlmi_priv.save_mode = cmd;
1263 		goto out;
1264 	case TLMI_SAVE_SAVE:
1265 		/* Check if supported*/
1266 		if (!tlmi_priv.can_set_bios_settings ||
1267 		    tlmi_priv.save_mode == TLMI_SAVE_SINGLE) {
1268 			ret = -EOPNOTSUPP;
1269 			goto out;
1270 		}
1271 		/* Check there is actually something to save */
1272 		if (!tlmi_priv.save_required) {
1273 			ret = -ENOENT;
1274 			goto out;
1275 		}
1276 		/* Check if certificate authentication is enabled and active */
1277 		if (tlmi_priv.certificate_support && tlmi_priv.pwd_admin->cert_installed) {
1278 			if (!tlmi_priv.pwd_admin->signature ||
1279 			    !tlmi_priv.pwd_admin->save_signature) {
1280 				ret = -EINVAL;
1281 				goto out;
1282 			}
1283 			ret = tlmi_simple_call(LENOVO_SAVE_BIOS_SETTING_CERT_GUID,
1284 					       tlmi_priv.pwd_admin->save_signature);
1285 			if (ret)
1286 				goto out;
1287 		} else if (tlmi_priv.opcode_support) {
1288 			if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
1289 				ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
1290 							  tlmi_priv.pwd_admin->password);
1291 				if (ret)
1292 					goto out;
1293 			}
1294 			ret = tlmi_save_bios_settings("");
1295 		} else { /* old non-opcode based authentication method (deprecated) */
1296 			if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
1297 				auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
1298 						     tlmi_priv.pwd_admin->password,
1299 						     encoding_options[tlmi_priv.pwd_admin->encoding],
1300 						     tlmi_priv.pwd_admin->kbdlang);
1301 				if (!auth_str) {
1302 					ret = -ENOMEM;
1303 					goto out;
1304 				}
1305 			}
1306 
1307 			if (auth_str)
1308 				ret = tlmi_save_bios_settings(auth_str);
1309 			else
1310 				ret = tlmi_save_bios_settings("");
1311 		}
1312 		tlmi_priv.save_required = false;
1313 		tlmi_priv.reboot_required = true;
1314 
1315 		if (!ret && !tlmi_priv.pending_changes) {
1316 			tlmi_priv.pending_changes = true;
1317 			/* let userland know it may need to check reboot pending again */
1318 			kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
1319 		}
1320 		break;
1321 	}
1322 out:
1323 	mutex_unlock(&tlmi_mutex);
1324 	kfree(auth_str);
1325 	return ret ?: count;
1326 }
1327 
1328 static struct kobj_attribute save_settings = __ATTR_RW(save_settings);
1329 
1330 /* ---- Debug interface--------------------------------------------------------- */
debug_cmd_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)1331 static ssize_t debug_cmd_store(struct kobject *kobj, struct kobj_attribute *attr,
1332 				const char *buf, size_t count)
1333 {
1334 	char *set_str = NULL, *new_setting = NULL;
1335 	char *auth_str = NULL;
1336 	int ret;
1337 
1338 	if (!tlmi_priv.can_debug_cmd)
1339 		return -EOPNOTSUPP;
1340 
1341 	/* Strip out CR if one is present */
1342 	new_setting = kstrdup_and_replace(buf, '\n', '\0', GFP_KERNEL);
1343 	if (!new_setting)
1344 		return -ENOMEM;
1345 
1346 	if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
1347 		auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
1348 				tlmi_priv.pwd_admin->password,
1349 				encoding_options[tlmi_priv.pwd_admin->encoding],
1350 				tlmi_priv.pwd_admin->kbdlang);
1351 		if (!auth_str) {
1352 			ret = -ENOMEM;
1353 			goto out;
1354 		}
1355 	}
1356 
1357 	if (auth_str)
1358 		set_str = kasprintf(GFP_KERNEL, "%s,%s", new_setting, auth_str);
1359 	else
1360 		set_str = kasprintf(GFP_KERNEL, "%s;", new_setting);
1361 	if (!set_str) {
1362 		ret = -ENOMEM;
1363 		goto out;
1364 	}
1365 
1366 	ret = tlmi_simple_call(LENOVO_DEBUG_CMD_GUID, set_str);
1367 	if (ret)
1368 		goto out;
1369 
1370 	if (!ret && !tlmi_priv.pending_changes) {
1371 		tlmi_priv.pending_changes = true;
1372 		/* let userland know it may need to check reboot pending again */
1373 		kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
1374 	}
1375 out:
1376 	kfree(auth_str);
1377 	kfree(set_str);
1378 	kfree(new_setting);
1379 	return ret ?: count;
1380 }
1381 
1382 static struct kobj_attribute debug_cmd = __ATTR_WO(debug_cmd);
1383 
1384 /* ---- Initialisation --------------------------------------------------------- */
tlmi_release_attr(void)1385 static void tlmi_release_attr(void)
1386 {
1387 	int i;
1388 
1389 	/* Attribute structures */
1390 	for (i = 0; i < TLMI_SETTINGS_COUNT; i++) {
1391 		if (tlmi_priv.setting[i]) {
1392 			sysfs_remove_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group);
1393 			kobject_put(&tlmi_priv.setting[i]->kobj);
1394 		}
1395 	}
1396 	sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr);
1397 	sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &save_settings.attr);
1398 
1399 	if (tlmi_priv.can_debug_cmd && debug_support)
1400 		sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr);
1401 
1402 	kset_unregister(tlmi_priv.attribute_kset);
1403 
1404 	/* Free up any saved signatures */
1405 	kfree(tlmi_priv.pwd_admin->signature);
1406 	kfree(tlmi_priv.pwd_admin->save_signature);
1407 
1408 	/* Authentication structures */
1409 	sysfs_remove_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group);
1410 	kobject_put(&tlmi_priv.pwd_admin->kobj);
1411 	sysfs_remove_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group);
1412 	kobject_put(&tlmi_priv.pwd_power->kobj);
1413 
1414 	if (tlmi_priv.opcode_support) {
1415 		sysfs_remove_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group);
1416 		kobject_put(&tlmi_priv.pwd_system->kobj);
1417 		sysfs_remove_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group);
1418 		kobject_put(&tlmi_priv.pwd_hdd->kobj);
1419 		sysfs_remove_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group);
1420 		kobject_put(&tlmi_priv.pwd_nvme->kobj);
1421 	}
1422 
1423 	kset_unregister(tlmi_priv.authentication_kset);
1424 }
1425 
tlmi_validate_setting_name(struct kset * attribute_kset,char * name)1426 static int tlmi_validate_setting_name(struct kset *attribute_kset, char *name)
1427 {
1428 	struct kobject *duplicate;
1429 
1430 	if (!strcmp(name, "Reserved"))
1431 		return -EINVAL;
1432 
1433 	duplicate = kset_find_obj(attribute_kset, name);
1434 	if (duplicate) {
1435 		pr_debug("Duplicate attribute name found - %s\n", name);
1436 		/* kset_find_obj() returns a reference */
1437 		kobject_put(duplicate);
1438 		return -EBUSY;
1439 	}
1440 
1441 	return 0;
1442 }
1443 
tlmi_sysfs_init(void)1444 static int tlmi_sysfs_init(void)
1445 {
1446 	int i, ret;
1447 
1448 	tlmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0),
1449 			NULL, "%s", "thinklmi");
1450 	if (IS_ERR(tlmi_priv.class_dev)) {
1451 		ret = PTR_ERR(tlmi_priv.class_dev);
1452 		goto fail_class_created;
1453 	}
1454 
1455 	tlmi_priv.attribute_kset = kset_create_and_add("attributes", NULL,
1456 			&tlmi_priv.class_dev->kobj);
1457 	if (!tlmi_priv.attribute_kset) {
1458 		ret = -ENOMEM;
1459 		goto fail_device_created;
1460 	}
1461 
1462 	for (i = 0; i < TLMI_SETTINGS_COUNT; i++) {
1463 		/* Check if index is a valid setting - skip if it isn't */
1464 		if (!tlmi_priv.setting[i])
1465 			continue;
1466 
1467 		/* check for duplicate or reserved values */
1468 		if (tlmi_validate_setting_name(tlmi_priv.attribute_kset,
1469 					       tlmi_priv.setting[i]->display_name) < 0) {
1470 			kfree(tlmi_priv.setting[i]->possible_values);
1471 			kfree(tlmi_priv.setting[i]);
1472 			tlmi_priv.setting[i] = NULL;
1473 			continue;
1474 		}
1475 
1476 		/* Build attribute */
1477 		tlmi_priv.setting[i]->kobj.kset = tlmi_priv.attribute_kset;
1478 		ret = kobject_add(&tlmi_priv.setting[i]->kobj, NULL,
1479 				  "%s", tlmi_priv.setting[i]->display_name);
1480 		if (ret)
1481 			goto fail_create_attr;
1482 
1483 		ret = sysfs_create_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group);
1484 		if (ret)
1485 			goto fail_create_attr;
1486 	}
1487 
1488 	ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr);
1489 	if (ret)
1490 		goto fail_create_attr;
1491 
1492 	ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &save_settings.attr);
1493 	if (ret)
1494 		goto fail_create_attr;
1495 
1496 	if (tlmi_priv.can_debug_cmd && debug_support) {
1497 		ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr);
1498 		if (ret)
1499 			goto fail_create_attr;
1500 	}
1501 
1502 	/* Create authentication entries */
1503 	tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL,
1504 								&tlmi_priv.class_dev->kobj);
1505 	if (!tlmi_priv.authentication_kset) {
1506 		ret = -ENOMEM;
1507 		goto fail_create_attr;
1508 	}
1509 	tlmi_priv.pwd_admin->kobj.kset = tlmi_priv.authentication_kset;
1510 	ret = kobject_add(&tlmi_priv.pwd_admin->kobj, NULL, "%s", "Admin");
1511 	if (ret)
1512 		goto fail_create_attr;
1513 
1514 	ret = sysfs_create_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group);
1515 	if (ret)
1516 		goto fail_create_attr;
1517 
1518 	tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset;
1519 	ret = kobject_add(&tlmi_priv.pwd_power->kobj, NULL, "%s", "Power-on");
1520 	if (ret)
1521 		goto fail_create_attr;
1522 
1523 	ret = sysfs_create_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group);
1524 	if (ret)
1525 		goto fail_create_attr;
1526 
1527 	if (tlmi_priv.opcode_support) {
1528 		tlmi_priv.pwd_system->kobj.kset = tlmi_priv.authentication_kset;
1529 		ret = kobject_add(&tlmi_priv.pwd_system->kobj, NULL, "%s", "System");
1530 		if (ret)
1531 			goto fail_create_attr;
1532 
1533 		ret = sysfs_create_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group);
1534 		if (ret)
1535 			goto fail_create_attr;
1536 
1537 		tlmi_priv.pwd_hdd->kobj.kset = tlmi_priv.authentication_kset;
1538 		ret = kobject_add(&tlmi_priv.pwd_hdd->kobj, NULL, "%s", "HDD");
1539 		if (ret)
1540 			goto fail_create_attr;
1541 
1542 		ret = sysfs_create_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group);
1543 		if (ret)
1544 			goto fail_create_attr;
1545 
1546 		tlmi_priv.pwd_nvme->kobj.kset = tlmi_priv.authentication_kset;
1547 		ret = kobject_add(&tlmi_priv.pwd_nvme->kobj, NULL, "%s", "NVMe");
1548 		if (ret)
1549 			goto fail_create_attr;
1550 
1551 		ret = sysfs_create_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group);
1552 		if (ret)
1553 			goto fail_create_attr;
1554 	}
1555 
1556 	return ret;
1557 
1558 fail_create_attr:
1559 	tlmi_release_attr();
1560 fail_device_created:
1561 	device_destroy(&firmware_attributes_class, MKDEV(0, 0));
1562 fail_class_created:
1563 	return ret;
1564 }
1565 
1566 /* ---- Base Driver -------------------------------------------------------- */
tlmi_create_auth(const char * pwd_type,const char * pwd_role)1567 static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type,
1568 			    const char *pwd_role)
1569 {
1570 	struct tlmi_pwd_setting *new_pwd;
1571 
1572 	new_pwd = kzalloc(sizeof(struct tlmi_pwd_setting), GFP_KERNEL);
1573 	if (!new_pwd)
1574 		return NULL;
1575 
1576 	strscpy(new_pwd->kbdlang, "us");
1577 	new_pwd->encoding = TLMI_ENCODING_ASCII;
1578 	new_pwd->pwd_type = pwd_type;
1579 	new_pwd->role = pwd_role;
1580 	new_pwd->minlen = tlmi_priv.pwdcfg.core.min_length;
1581 	new_pwd->maxlen = tlmi_priv.pwdcfg.core.max_length;
1582 	new_pwd->index = 0;
1583 
1584 	kobject_init(&new_pwd->kobj, &tlmi_pwd_setting_ktype);
1585 
1586 	return new_pwd;
1587 }
1588 
tlmi_analyze(void)1589 static int tlmi_analyze(void)
1590 {
1591 	int i, ret;
1592 
1593 	if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) &&
1594 	    wmi_has_guid(LENOVO_SAVE_BIOS_SETTINGS_GUID))
1595 		tlmi_priv.can_set_bios_settings = true;
1596 
1597 	if (wmi_has_guid(LENOVO_GET_BIOS_SELECTIONS_GUID))
1598 		tlmi_priv.can_get_bios_selections = true;
1599 
1600 	if (wmi_has_guid(LENOVO_SET_BIOS_PASSWORD_GUID))
1601 		tlmi_priv.can_set_bios_password = true;
1602 
1603 	if (wmi_has_guid(LENOVO_BIOS_PASSWORD_SETTINGS_GUID))
1604 		tlmi_priv.can_get_password_settings = true;
1605 
1606 	if (wmi_has_guid(LENOVO_DEBUG_CMD_GUID))
1607 		tlmi_priv.can_debug_cmd = true;
1608 
1609 	if (wmi_has_guid(LENOVO_OPCODE_IF_GUID))
1610 		tlmi_priv.opcode_support = true;
1611 
1612 	if (wmi_has_guid(LENOVO_SET_BIOS_CERT_GUID) &&
1613 		wmi_has_guid(LENOVO_SET_BIOS_SETTING_CERT_GUID) &&
1614 		wmi_has_guid(LENOVO_SAVE_BIOS_SETTING_CERT_GUID))
1615 		tlmi_priv.certificate_support = true;
1616 
1617 	/*
1618 	 * Try to find the number of valid settings of this machine
1619 	 * and use it to create sysfs attributes.
1620 	 */
1621 	for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) {
1622 		struct tlmi_attr_setting *setting;
1623 		char *item = NULL;
1624 
1625 		tlmi_priv.setting[i] = NULL;
1626 		ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID);
1627 		if (ret)
1628 			break;
1629 		if (!item)
1630 			break;
1631 		if (!*item) {
1632 			kfree(item);
1633 			continue;
1634 		}
1635 
1636 		/* It is not allowed to have '/' for file name. Convert it into '\'. */
1637 		strreplace(item, '/', '\\');
1638 
1639 		/* Remove the value part */
1640 		strreplace(item, ',', '\0');
1641 
1642 		/* Create a setting entry */
1643 		setting = kzalloc(sizeof(*setting), GFP_KERNEL);
1644 		if (!setting) {
1645 			ret = -ENOMEM;
1646 			kfree(item);
1647 			goto fail_clear_attr;
1648 		}
1649 		setting->index = i;
1650 		strscpy(setting->display_name, item);
1651 		/* If BIOS selections supported, load those */
1652 		if (tlmi_priv.can_get_bios_selections) {
1653 			ret = tlmi_get_bios_selections(setting->display_name,
1654 					&setting->possible_values);
1655 			if (ret || !setting->possible_values)
1656 				pr_info("Error retrieving possible values for %d : %s\n",
1657 						i, setting->display_name);
1658 		} else {
1659 			/*
1660 			 * Older Thinkstations don't support the bios_selections API.
1661 			 * Instead they store this as a [Optional:Option1,Option2] section of the
1662 			 * name string.
1663 			 * Try and pull that out if it's available.
1664 			 */
1665 			char *optitem, *optstart, *optend;
1666 
1667 			if (!tlmi_setting(setting->index, &optitem, LENOVO_BIOS_SETTING_GUID)) {
1668 				optstart = strstr(optitem, "[Optional:");
1669 				if (optstart) {
1670 					optstart += strlen("[Optional:");
1671 					optend = strstr(optstart, "]");
1672 					if (optend)
1673 						setting->possible_values =
1674 							kstrndup(optstart, optend - optstart,
1675 									GFP_KERNEL);
1676 				}
1677 				kfree(optitem);
1678 			}
1679 		}
1680 		/*
1681 		 * firmware-attributes requires that possible_values are separated by ';' but
1682 		 * Lenovo FW uses ','. Replace appropriately.
1683 		 */
1684 		if (setting->possible_values)
1685 			strreplace(setting->possible_values, ',', ';');
1686 
1687 		kobject_init(&setting->kobj, &tlmi_attr_setting_ktype);
1688 		tlmi_priv.setting[i] = setting;
1689 		kfree(item);
1690 	}
1691 
1692 	/* Create password setting structure */
1693 	ret = tlmi_get_pwd_settings(&tlmi_priv.pwdcfg);
1694 	if (ret)
1695 		goto fail_clear_attr;
1696 
1697 	/* All failures below boil down to kmalloc failures */
1698 	ret = -ENOMEM;
1699 
1700 	tlmi_priv.pwd_admin = tlmi_create_auth("pap", "bios-admin");
1701 	if (!tlmi_priv.pwd_admin)
1702 		goto fail_clear_attr;
1703 
1704 	if (tlmi_priv.pwdcfg.core.password_state & TLMI_PAP_PWD)
1705 		tlmi_priv.pwd_admin->pwd_enabled = true;
1706 
1707 	tlmi_priv.pwd_power = tlmi_create_auth("pop", "power-on");
1708 	if (!tlmi_priv.pwd_power)
1709 		goto fail_clear_attr;
1710 
1711 	if (tlmi_priv.pwdcfg.core.password_state & TLMI_POP_PWD)
1712 		tlmi_priv.pwd_power->pwd_enabled = true;
1713 
1714 	if (tlmi_priv.opcode_support) {
1715 		tlmi_priv.pwd_system = tlmi_create_auth("smp", "system");
1716 		if (!tlmi_priv.pwd_system)
1717 			goto fail_clear_attr;
1718 
1719 		if (tlmi_priv.pwdcfg.core.password_state & TLMI_SMP_PWD)
1720 			tlmi_priv.pwd_system->pwd_enabled = true;
1721 
1722 		tlmi_priv.pwd_hdd = tlmi_create_auth("hdd", "hdd");
1723 		if (!tlmi_priv.pwd_hdd)
1724 			goto fail_clear_attr;
1725 
1726 		tlmi_priv.pwd_nvme = tlmi_create_auth("nvm", "nvme");
1727 		if (!tlmi_priv.pwd_nvme)
1728 			goto fail_clear_attr;
1729 
1730 		/* Set default hdd/nvme index to 1 as there is no device 0 */
1731 		tlmi_priv.pwd_hdd->index = 1;
1732 		tlmi_priv.pwd_nvme->index = 1;
1733 
1734 		if (tlmi_priv.pwdcfg.core.password_state & TLMI_HDD_PWD) {
1735 			/* Check if PWD is configured and set index to first drive found */
1736 			if (tlmi_priv.pwdcfg.ext.hdd_user_password ||
1737 					tlmi_priv.pwdcfg.ext.hdd_master_password) {
1738 				tlmi_priv.pwd_hdd->pwd_enabled = true;
1739 				if (tlmi_priv.pwdcfg.ext.hdd_master_password)
1740 					tlmi_priv.pwd_hdd->index =
1741 						ffs(tlmi_priv.pwdcfg.ext.hdd_master_password) - 1;
1742 				else
1743 					tlmi_priv.pwd_hdd->index =
1744 						ffs(tlmi_priv.pwdcfg.ext.hdd_user_password) - 1;
1745 			}
1746 			if (tlmi_priv.pwdcfg.ext.nvme_user_password ||
1747 					tlmi_priv.pwdcfg.ext.nvme_master_password) {
1748 				tlmi_priv.pwd_nvme->pwd_enabled = true;
1749 				if (tlmi_priv.pwdcfg.ext.nvme_master_password)
1750 					tlmi_priv.pwd_nvme->index =
1751 						ffs(tlmi_priv.pwdcfg.ext.nvme_master_password) - 1;
1752 				else
1753 					tlmi_priv.pwd_nvme->index =
1754 						ffs(tlmi_priv.pwdcfg.ext.nvme_user_password) - 1;
1755 			}
1756 		}
1757 	}
1758 
1759 	if (tlmi_priv.certificate_support) {
1760 		tlmi_priv.pwd_admin->cert_installed =
1761 			tlmi_priv.pwdcfg.core.password_state & TLMI_CERT_SVC;
1762 		tlmi_priv.pwd_system->cert_installed =
1763 			tlmi_priv.pwdcfg.core.password_state & TLMI_CERT_SMC;
1764 	}
1765 	return 0;
1766 
1767 fail_clear_attr:
1768 	for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) {
1769 		if (tlmi_priv.setting[i]) {
1770 			kfree(tlmi_priv.setting[i]->possible_values);
1771 			kfree(tlmi_priv.setting[i]);
1772 		}
1773 	}
1774 	kfree(tlmi_priv.pwd_admin);
1775 	kfree(tlmi_priv.pwd_power);
1776 	kfree(tlmi_priv.pwd_system);
1777 	kfree(tlmi_priv.pwd_hdd);
1778 	kfree(tlmi_priv.pwd_nvme);
1779 	return ret;
1780 }
1781 
tlmi_remove(struct wmi_device * wdev)1782 static void tlmi_remove(struct wmi_device *wdev)
1783 {
1784 	tlmi_release_attr();
1785 	device_destroy(&firmware_attributes_class, MKDEV(0, 0));
1786 }
1787 
tlmi_probe(struct wmi_device * wdev,const void * context)1788 static int tlmi_probe(struct wmi_device *wdev, const void *context)
1789 {
1790 	int ret;
1791 
1792 	ret = tlmi_analyze();
1793 	if (ret)
1794 		return ret;
1795 
1796 	return tlmi_sysfs_init();
1797 }
1798 
1799 static const struct wmi_device_id tlmi_id_table[] = {
1800 	{ .guid_string = LENOVO_BIOS_SETTING_GUID },
1801 	{ }
1802 };
1803 MODULE_DEVICE_TABLE(wmi, tlmi_id_table);
1804 
1805 static struct wmi_driver tlmi_driver = {
1806 	.driver = {
1807 		.name = "think-lmi",
1808 	},
1809 	.id_table = tlmi_id_table,
1810 	.probe = tlmi_probe,
1811 	.remove = tlmi_remove,
1812 };
1813 
1814 MODULE_AUTHOR("Sugumaran L <[email protected]>");
1815 MODULE_AUTHOR("Mark Pearson <[email protected]>");
1816 MODULE_AUTHOR("Corentin Chary <[email protected]>");
1817 MODULE_DESCRIPTION("ThinkLMI Driver");
1818 MODULE_LICENSE("GPL");
1819 
1820 module_wmi_driver(tlmi_driver);
1821