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