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