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 = min_t(size_t, obj->buffer.length, sizeof(struct tlmi_pwdcfg)); 321 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 /* If empty then clear installed certificate */ 744 if ((buf[0] == '\0') || (buf[0] == '\n')) { /* Clear installed certificate */ 745 /* Check that signature is set */ 746 if (!setting->signature || !setting->signature[0]) 747 return -EACCES; 748 749 /* Format: 'serial#, signature' */ 750 auth_str = kasprintf(GFP_KERNEL, "%s,%s", 751 dmi_get_system_info(DMI_PRODUCT_SERIAL), 752 setting->signature); 753 if (!auth_str) 754 return -ENOMEM; 755 756 ret = tlmi_simple_call(LENOVO_CLEAR_BIOS_CERT_GUID, auth_str); 757 kfree(auth_str); 758 759 return ret ?: count; 760 } 761 762 new_cert = kstrdup(buf, GFP_KERNEL); 763 if (!new_cert) 764 return -ENOMEM; 765 /* Strip out CR if one is present */ 766 strip_cr(new_cert); 767 768 if (setting->cert_installed) { 769 /* Certificate is installed so this is an update */ 770 if (!setting->signature || !setting->signature[0]) { 771 kfree(new_cert); 772 return -EACCES; 773 } 774 guid = LENOVO_UPDATE_BIOS_CERT_GUID; 775 /* Format: 'Certificate,Signature' */ 776 auth_str = kasprintf(GFP_KERNEL, "%s,%s", 777 new_cert, setting->signature); 778 } else { 779 /* This is a fresh install */ 780 if (!setting->valid || !setting->password[0]) { 781 kfree(new_cert); 782 return -EACCES; 783 } 784 guid = LENOVO_SET_BIOS_CERT_GUID; 785 /* Format: 'Certificate,Admin-password' */ 786 auth_str = kasprintf(GFP_KERNEL, "%s,%s", 787 new_cert, setting->password); 788 } 789 kfree(new_cert); 790 if (!auth_str) 791 return -ENOMEM; 792 793 ret = tlmi_simple_call(guid, auth_str); 794 kfree(auth_str); 795 796 return ret ?: count; 797 } 798 799 static struct kobj_attribute auth_certificate = __ATTR_WO(certificate); 800 801 static ssize_t signature_store(struct kobject *kobj, 802 struct kobj_attribute *attr, 803 const char *buf, size_t count) 804 { 805 struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj); 806 char *new_signature; 807 808 if (!capable(CAP_SYS_ADMIN)) 809 return -EPERM; 810 811 if (!tlmi_priv.certificate_support) 812 return -EOPNOTSUPP; 813 814 new_signature = kstrdup(buf, GFP_KERNEL); 815 if (!new_signature) 816 return -ENOMEM; 817 818 /* Strip out CR if one is present */ 819 strip_cr(new_signature); 820 821 /* Free any previous signature */ 822 kfree(setting->signature); 823 setting->signature = new_signature; 824 825 return count; 826 } 827 828 static struct kobj_attribute auth_signature = __ATTR_WO(signature); 829 830 static ssize_t save_signature_store(struct kobject *kobj, 831 struct kobj_attribute *attr, 832 const char *buf, size_t count) 833 { 834 struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj); 835 char *new_signature; 836 837 if (!capable(CAP_SYS_ADMIN)) 838 return -EPERM; 839 840 if (!tlmi_priv.certificate_support) 841 return -EOPNOTSUPP; 842 843 new_signature = kstrdup(buf, GFP_KERNEL); 844 if (!new_signature) 845 return -ENOMEM; 846 847 /* Strip out CR if one is present */ 848 strip_cr(new_signature); 849 850 /* Free any previous signature */ 851 kfree(setting->save_signature); 852 setting->save_signature = new_signature; 853 854 return count; 855 } 856 857 static struct kobj_attribute auth_save_signature = __ATTR_WO(save_signature); 858 859 static umode_t auth_attr_is_visible(struct kobject *kobj, 860 struct attribute *attr, int n) 861 { 862 struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj); 863 864 /* We only want to display level and index settings on HDD/NVMe */ 865 if (attr == &auth_index.attr || attr == &auth_level.attr) { 866 if ((setting == tlmi_priv.pwd_hdd) || (setting == tlmi_priv.pwd_nvme)) 867 return attr->mode; 868 return 0; 869 } 870 871 /* We only display certificates on Admin account, if supported */ 872 if (attr == &auth_certificate.attr || 873 attr == &auth_signature.attr || 874 attr == &auth_save_signature.attr || 875 attr == &auth_cert_thumb.attr || 876 attr == &auth_cert_to_password.attr) { 877 if ((setting == tlmi_priv.pwd_admin) && tlmi_priv.certificate_support) 878 return attr->mode; 879 return 0; 880 } 881 882 return attr->mode; 883 } 884 885 static struct attribute *auth_attrs[] = { 886 &auth_is_pass_set.attr, 887 &auth_min_pass_length.attr, 888 &auth_max_pass_length.attr, 889 &auth_current_password.attr, 890 &auth_new_password.attr, 891 &auth_role.attr, 892 &auth_mechanism.attr, 893 &auth_encoding.attr, 894 &auth_kbdlang.attr, 895 &auth_index.attr, 896 &auth_level.attr, 897 &auth_certificate.attr, 898 &auth_signature.attr, 899 &auth_save_signature.attr, 900 &auth_cert_thumb.attr, 901 &auth_cert_to_password.attr, 902 NULL 903 }; 904 905 static const struct attribute_group auth_attr_group = { 906 .is_visible = auth_attr_is_visible, 907 .attrs = auth_attrs, 908 }; 909 910 /* ---- Attributes sysfs --------------------------------------------------------- */ 911 static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *attr, 912 char *buf) 913 { 914 struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); 915 916 return sysfs_emit(buf, "%s\n", setting->display_name); 917 } 918 919 static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 920 { 921 struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); 922 char *item, *value, *p; 923 int ret; 924 925 ret = tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID); 926 if (ret) 927 return ret; 928 929 /* validate and split from `item,value` -> `value` */ 930 value = strpbrk(item, ","); 931 if (!value || value == item || !strlen(value + 1)) 932 ret = -EINVAL; 933 else { 934 /* On Workstations remove the Options part after the value */ 935 p = strchrnul(value, ';'); 936 *p = '\0'; 937 ret = sysfs_emit(buf, "%s\n", value + 1); 938 } 939 kfree(item); 940 941 return ret; 942 } 943 944 static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 945 { 946 struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); 947 948 return sysfs_emit(buf, "%s\n", setting->possible_values); 949 } 950 951 static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, 952 char *buf) 953 { 954 struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); 955 956 if (setting->possible_values) { 957 /* Figure out what setting type is as BIOS does not return this */ 958 if (strchr(setting->possible_values, ';')) 959 return sysfs_emit(buf, "enumeration\n"); 960 } 961 /* Anything else is going to be a string */ 962 return sysfs_emit(buf, "string\n"); 963 } 964 965 static ssize_t current_value_store(struct kobject *kobj, 966 struct kobj_attribute *attr, 967 const char *buf, size_t count) 968 { 969 struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); 970 char *set_str = NULL, *new_setting = NULL; 971 char *auth_str = NULL; 972 int ret; 973 974 if (!tlmi_priv.can_set_bios_settings) 975 return -EOPNOTSUPP; 976 977 new_setting = kstrdup(buf, GFP_KERNEL); 978 if (!new_setting) 979 return -ENOMEM; 980 981 /* Strip out CR if one is present */ 982 strip_cr(new_setting); 983 984 /* Check if certificate authentication is enabled and active */ 985 if (tlmi_priv.certificate_support && tlmi_priv.pwd_admin->cert_installed) { 986 if (!tlmi_priv.pwd_admin->signature || !tlmi_priv.pwd_admin->save_signature) { 987 ret = -EINVAL; 988 goto out; 989 } 990 set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->display_name, 991 new_setting, tlmi_priv.pwd_admin->signature); 992 if (!set_str) { 993 ret = -ENOMEM; 994 goto out; 995 } 996 997 ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTING_CERT_GUID, set_str); 998 if (ret) 999 goto out; 1000 ret = tlmi_simple_call(LENOVO_SAVE_BIOS_SETTING_CERT_GUID, 1001 tlmi_priv.pwd_admin->save_signature); 1002 if (ret) 1003 goto out; 1004 } else { /* Non certiifcate based authentication */ 1005 if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) { 1006 auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;", 1007 tlmi_priv.pwd_admin->password, 1008 encoding_options[tlmi_priv.pwd_admin->encoding], 1009 tlmi_priv.pwd_admin->kbdlang); 1010 if (!auth_str) { 1011 ret = -ENOMEM; 1012 goto out; 1013 } 1014 } 1015 1016 if (auth_str) 1017 set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->display_name, 1018 new_setting, auth_str); 1019 else 1020 set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->display_name, 1021 new_setting); 1022 if (!set_str) { 1023 ret = -ENOMEM; 1024 goto out; 1025 } 1026 1027 ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTINGS_GUID, set_str); 1028 if (ret) 1029 goto out; 1030 1031 if (auth_str) 1032 ret = tlmi_save_bios_settings(auth_str); 1033 else 1034 ret = tlmi_save_bios_settings(""); 1035 } 1036 if (!ret && !tlmi_priv.pending_changes) { 1037 tlmi_priv.pending_changes = true; 1038 /* let userland know it may need to check reboot pending again */ 1039 kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE); 1040 } 1041 out: 1042 kfree(auth_str); 1043 kfree(set_str); 1044 kfree(new_setting); 1045 return ret ?: count; 1046 } 1047 1048 static struct kobj_attribute attr_displ_name = __ATTR_RO(display_name); 1049 1050 static struct kobj_attribute attr_possible_values = __ATTR_RO(possible_values); 1051 1052 static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 0600); 1053 1054 static struct kobj_attribute attr_type = __ATTR_RO(type); 1055 1056 static umode_t attr_is_visible(struct kobject *kobj, 1057 struct attribute *attr, int n) 1058 { 1059 struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); 1060 1061 /* We don't want to display possible_values attributes if not available */ 1062 if ((attr == &attr_possible_values.attr) && (!setting->possible_values)) 1063 return 0; 1064 1065 return attr->mode; 1066 } 1067 1068 static struct attribute *tlmi_attrs[] = { 1069 &attr_displ_name.attr, 1070 &attr_current_val.attr, 1071 &attr_possible_values.attr, 1072 &attr_type.attr, 1073 NULL 1074 }; 1075 1076 static const struct attribute_group tlmi_attr_group = { 1077 .is_visible = attr_is_visible, 1078 .attrs = tlmi_attrs, 1079 }; 1080 1081 static void tlmi_attr_setting_release(struct kobject *kobj) 1082 { 1083 struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); 1084 1085 kfree(setting->possible_values); 1086 kfree(setting); 1087 } 1088 1089 static void tlmi_pwd_setting_release(struct kobject *kobj) 1090 { 1091 struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj); 1092 1093 kfree(setting); 1094 } 1095 1096 static const struct kobj_type tlmi_attr_setting_ktype = { 1097 .release = &tlmi_attr_setting_release, 1098 .sysfs_ops = &kobj_sysfs_ops, 1099 }; 1100 1101 static const struct kobj_type tlmi_pwd_setting_ktype = { 1102 .release = &tlmi_pwd_setting_release, 1103 .sysfs_ops = &kobj_sysfs_ops, 1104 }; 1105 1106 static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr, 1107 char *buf) 1108 { 1109 return sprintf(buf, "%d\n", tlmi_priv.pending_changes); 1110 } 1111 1112 static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot); 1113 1114 /* ---- Debug interface--------------------------------------------------------- */ 1115 static ssize_t debug_cmd_store(struct kobject *kobj, struct kobj_attribute *attr, 1116 const char *buf, size_t count) 1117 { 1118 char *set_str = NULL, *new_setting = NULL; 1119 char *auth_str = NULL; 1120 int ret; 1121 1122 if (!tlmi_priv.can_debug_cmd) 1123 return -EOPNOTSUPP; 1124 1125 new_setting = kstrdup(buf, GFP_KERNEL); 1126 if (!new_setting) 1127 return -ENOMEM; 1128 1129 /* Strip out CR if one is present */ 1130 strip_cr(new_setting); 1131 1132 if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) { 1133 auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;", 1134 tlmi_priv.pwd_admin->password, 1135 encoding_options[tlmi_priv.pwd_admin->encoding], 1136 tlmi_priv.pwd_admin->kbdlang); 1137 if (!auth_str) { 1138 ret = -ENOMEM; 1139 goto out; 1140 } 1141 } 1142 1143 if (auth_str) 1144 set_str = kasprintf(GFP_KERNEL, "%s,%s", new_setting, auth_str); 1145 else 1146 set_str = kasprintf(GFP_KERNEL, "%s;", new_setting); 1147 if (!set_str) { 1148 ret = -ENOMEM; 1149 goto out; 1150 } 1151 1152 ret = tlmi_simple_call(LENOVO_DEBUG_CMD_GUID, set_str); 1153 if (ret) 1154 goto out; 1155 1156 if (!ret && !tlmi_priv.pending_changes) { 1157 tlmi_priv.pending_changes = true; 1158 /* let userland know it may need to check reboot pending again */ 1159 kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE); 1160 } 1161 out: 1162 kfree(auth_str); 1163 kfree(set_str); 1164 kfree(new_setting); 1165 return ret ?: count; 1166 } 1167 1168 static struct kobj_attribute debug_cmd = __ATTR_WO(debug_cmd); 1169 1170 /* ---- Initialisation --------------------------------------------------------- */ 1171 static void tlmi_release_attr(void) 1172 { 1173 int i; 1174 1175 /* Attribute structures */ 1176 for (i = 0; i < TLMI_SETTINGS_COUNT; i++) { 1177 if (tlmi_priv.setting[i]) { 1178 sysfs_remove_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group); 1179 kobject_put(&tlmi_priv.setting[i]->kobj); 1180 } 1181 } 1182 sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); 1183 if (tlmi_priv.can_debug_cmd && debug_support) 1184 sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr); 1185 1186 kset_unregister(tlmi_priv.attribute_kset); 1187 1188 /* Free up any saved signatures */ 1189 kfree(tlmi_priv.pwd_admin->signature); 1190 kfree(tlmi_priv.pwd_admin->save_signature); 1191 1192 /* Authentication structures */ 1193 sysfs_remove_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group); 1194 kobject_put(&tlmi_priv.pwd_admin->kobj); 1195 sysfs_remove_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group); 1196 kobject_put(&tlmi_priv.pwd_power->kobj); 1197 1198 if (tlmi_priv.opcode_support) { 1199 sysfs_remove_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group); 1200 kobject_put(&tlmi_priv.pwd_system->kobj); 1201 sysfs_remove_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group); 1202 kobject_put(&tlmi_priv.pwd_hdd->kobj); 1203 sysfs_remove_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group); 1204 kobject_put(&tlmi_priv.pwd_nvme->kobj); 1205 } 1206 1207 kset_unregister(tlmi_priv.authentication_kset); 1208 } 1209 1210 static int tlmi_sysfs_init(void) 1211 { 1212 int i, ret; 1213 1214 ret = fw_attributes_class_get(&fw_attr_class); 1215 if (ret) 1216 return ret; 1217 1218 tlmi_priv.class_dev = device_create(fw_attr_class, NULL, MKDEV(0, 0), 1219 NULL, "%s", "thinklmi"); 1220 if (IS_ERR(tlmi_priv.class_dev)) { 1221 ret = PTR_ERR(tlmi_priv.class_dev); 1222 goto fail_class_created; 1223 } 1224 1225 tlmi_priv.attribute_kset = kset_create_and_add("attributes", NULL, 1226 &tlmi_priv.class_dev->kobj); 1227 if (!tlmi_priv.attribute_kset) { 1228 ret = -ENOMEM; 1229 goto fail_device_created; 1230 } 1231 1232 for (i = 0; i < TLMI_SETTINGS_COUNT; i++) { 1233 /* Check if index is a valid setting - skip if it isn't */ 1234 if (!tlmi_priv.setting[i]) 1235 continue; 1236 1237 /* check for duplicate or reserved values */ 1238 if (kset_find_obj(tlmi_priv.attribute_kset, tlmi_priv.setting[i]->display_name) || 1239 !strcmp(tlmi_priv.setting[i]->display_name, "Reserved")) { 1240 pr_debug("duplicate or reserved attribute name found - %s\n", 1241 tlmi_priv.setting[i]->display_name); 1242 kfree(tlmi_priv.setting[i]->possible_values); 1243 kfree(tlmi_priv.setting[i]); 1244 tlmi_priv.setting[i] = NULL; 1245 continue; 1246 } 1247 1248 /* Build attribute */ 1249 tlmi_priv.setting[i]->kobj.kset = tlmi_priv.attribute_kset; 1250 ret = kobject_add(&tlmi_priv.setting[i]->kobj, NULL, 1251 "%s", tlmi_priv.setting[i]->display_name); 1252 if (ret) 1253 goto fail_create_attr; 1254 1255 ret = sysfs_create_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group); 1256 if (ret) 1257 goto fail_create_attr; 1258 } 1259 1260 ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); 1261 if (ret) 1262 goto fail_create_attr; 1263 1264 if (tlmi_priv.can_debug_cmd && debug_support) { 1265 ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr); 1266 if (ret) 1267 goto fail_create_attr; 1268 } 1269 1270 /* Create authentication entries */ 1271 tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL, 1272 &tlmi_priv.class_dev->kobj); 1273 if (!tlmi_priv.authentication_kset) { 1274 ret = -ENOMEM; 1275 goto fail_create_attr; 1276 } 1277 tlmi_priv.pwd_admin->kobj.kset = tlmi_priv.authentication_kset; 1278 ret = kobject_add(&tlmi_priv.pwd_admin->kobj, NULL, "%s", "Admin"); 1279 if (ret) 1280 goto fail_create_attr; 1281 1282 ret = sysfs_create_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group); 1283 if (ret) 1284 goto fail_create_attr; 1285 1286 tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset; 1287 ret = kobject_add(&tlmi_priv.pwd_power->kobj, NULL, "%s", "Power-on"); 1288 if (ret) 1289 goto fail_create_attr; 1290 1291 ret = sysfs_create_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group); 1292 if (ret) 1293 goto fail_create_attr; 1294 1295 if (tlmi_priv.opcode_support) { 1296 tlmi_priv.pwd_system->kobj.kset = tlmi_priv.authentication_kset; 1297 ret = kobject_add(&tlmi_priv.pwd_system->kobj, NULL, "%s", "System"); 1298 if (ret) 1299 goto fail_create_attr; 1300 1301 ret = sysfs_create_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group); 1302 if (ret) 1303 goto fail_create_attr; 1304 1305 tlmi_priv.pwd_hdd->kobj.kset = tlmi_priv.authentication_kset; 1306 ret = kobject_add(&tlmi_priv.pwd_hdd->kobj, NULL, "%s", "HDD"); 1307 if (ret) 1308 goto fail_create_attr; 1309 1310 ret = sysfs_create_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group); 1311 if (ret) 1312 goto fail_create_attr; 1313 1314 tlmi_priv.pwd_nvme->kobj.kset = tlmi_priv.authentication_kset; 1315 ret = kobject_add(&tlmi_priv.pwd_nvme->kobj, NULL, "%s", "NVMe"); 1316 if (ret) 1317 goto fail_create_attr; 1318 1319 ret = sysfs_create_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group); 1320 if (ret) 1321 goto fail_create_attr; 1322 } 1323 1324 return ret; 1325 1326 fail_create_attr: 1327 tlmi_release_attr(); 1328 fail_device_created: 1329 device_destroy(fw_attr_class, MKDEV(0, 0)); 1330 fail_class_created: 1331 fw_attributes_class_put(); 1332 return ret; 1333 } 1334 1335 /* ---- Base Driver -------------------------------------------------------- */ 1336 static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, 1337 const char *pwd_role) 1338 { 1339 struct tlmi_pwd_setting *new_pwd; 1340 1341 new_pwd = kzalloc(sizeof(struct tlmi_pwd_setting), GFP_KERNEL); 1342 if (!new_pwd) 1343 return NULL; 1344 1345 strscpy(new_pwd->kbdlang, "us", TLMI_LANG_MAXLEN); 1346 new_pwd->encoding = TLMI_ENCODING_ASCII; 1347 new_pwd->pwd_type = pwd_type; 1348 new_pwd->role = pwd_role; 1349 new_pwd->minlen = tlmi_priv.pwdcfg.core.min_length; 1350 new_pwd->maxlen = tlmi_priv.pwdcfg.core.max_length; 1351 new_pwd->index = 0; 1352 1353 kobject_init(&new_pwd->kobj, &tlmi_pwd_setting_ktype); 1354 1355 return new_pwd; 1356 } 1357 1358 static int tlmi_analyze(void) 1359 { 1360 int i, ret; 1361 1362 if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && 1363 wmi_has_guid(LENOVO_SAVE_BIOS_SETTINGS_GUID)) 1364 tlmi_priv.can_set_bios_settings = true; 1365 1366 if (wmi_has_guid(LENOVO_GET_BIOS_SELECTIONS_GUID)) 1367 tlmi_priv.can_get_bios_selections = true; 1368 1369 if (wmi_has_guid(LENOVO_SET_BIOS_PASSWORD_GUID)) 1370 tlmi_priv.can_set_bios_password = true; 1371 1372 if (wmi_has_guid(LENOVO_BIOS_PASSWORD_SETTINGS_GUID)) 1373 tlmi_priv.can_get_password_settings = true; 1374 1375 if (wmi_has_guid(LENOVO_DEBUG_CMD_GUID)) 1376 tlmi_priv.can_debug_cmd = true; 1377 1378 if (wmi_has_guid(LENOVO_OPCODE_IF_GUID)) 1379 tlmi_priv.opcode_support = true; 1380 1381 if (wmi_has_guid(LENOVO_SET_BIOS_CERT_GUID) && 1382 wmi_has_guid(LENOVO_SET_BIOS_SETTING_CERT_GUID) && 1383 wmi_has_guid(LENOVO_SAVE_BIOS_SETTING_CERT_GUID)) 1384 tlmi_priv.certificate_support = true; 1385 1386 /* 1387 * Try to find the number of valid settings of this machine 1388 * and use it to create sysfs attributes. 1389 */ 1390 for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) { 1391 struct tlmi_attr_setting *setting; 1392 char *item = NULL; 1393 char *p; 1394 1395 tlmi_priv.setting[i] = NULL; 1396 ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID); 1397 if (ret) 1398 break; 1399 if (!item) 1400 break; 1401 if (!*item) { 1402 kfree(item); 1403 continue; 1404 } 1405 1406 /* It is not allowed to have '/' for file name. Convert it into '\'. */ 1407 strreplace(item, '/', '\\'); 1408 1409 /* Remove the value part */ 1410 p = strchrnul(item, ','); 1411 *p = '\0'; 1412 1413 /* Create a setting entry */ 1414 setting = kzalloc(sizeof(*setting), GFP_KERNEL); 1415 if (!setting) { 1416 ret = -ENOMEM; 1417 kfree(item); 1418 goto fail_clear_attr; 1419 } 1420 setting->index = i; 1421 strscpy(setting->display_name, item, TLMI_SETTINGS_MAXLEN); 1422 /* If BIOS selections supported, load those */ 1423 if (tlmi_priv.can_get_bios_selections) { 1424 ret = tlmi_get_bios_selections(setting->display_name, 1425 &setting->possible_values); 1426 if (ret || !setting->possible_values) 1427 pr_info("Error retrieving possible values for %d : %s\n", 1428 i, setting->display_name); 1429 } else { 1430 /* 1431 * Older Thinkstations don't support the bios_selections API. 1432 * Instead they store this as a [Optional:Option1,Option2] section of the 1433 * name string. 1434 * Try and pull that out if it's available. 1435 */ 1436 char *optitem, *optstart, *optend; 1437 1438 if (!tlmi_setting(setting->index, &optitem, LENOVO_BIOS_SETTING_GUID)) { 1439 optstart = strstr(optitem, "[Optional:"); 1440 if (optstart) { 1441 optstart += strlen("[Optional:"); 1442 optend = strstr(optstart, "]"); 1443 if (optend) 1444 setting->possible_values = 1445 kstrndup(optstart, optend - optstart, 1446 GFP_KERNEL); 1447 } 1448 kfree(optitem); 1449 } 1450 } 1451 /* 1452 * firmware-attributes requires that possible_values are separated by ';' but 1453 * Lenovo FW uses ','. Replace appropriately. 1454 */ 1455 if (setting->possible_values) 1456 strreplace(setting->possible_values, ',', ';'); 1457 1458 kobject_init(&setting->kobj, &tlmi_attr_setting_ktype); 1459 tlmi_priv.setting[i] = setting; 1460 kfree(item); 1461 } 1462 1463 /* Create password setting structure */ 1464 ret = tlmi_get_pwd_settings(&tlmi_priv.pwdcfg); 1465 if (ret) 1466 goto fail_clear_attr; 1467 1468 /* All failures below boil down to kmalloc failures */ 1469 ret = -ENOMEM; 1470 1471 tlmi_priv.pwd_admin = tlmi_create_auth("pap", "bios-admin"); 1472 if (!tlmi_priv.pwd_admin) 1473 goto fail_clear_attr; 1474 1475 if (tlmi_priv.pwdcfg.core.password_state & TLMI_PAP_PWD) 1476 tlmi_priv.pwd_admin->valid = true; 1477 1478 tlmi_priv.pwd_power = tlmi_create_auth("pop", "power-on"); 1479 if (!tlmi_priv.pwd_power) 1480 goto fail_clear_attr; 1481 1482 if (tlmi_priv.pwdcfg.core.password_state & TLMI_POP_PWD) 1483 tlmi_priv.pwd_power->valid = true; 1484 1485 if (tlmi_priv.opcode_support) { 1486 tlmi_priv.pwd_system = tlmi_create_auth("sys", "system"); 1487 if (!tlmi_priv.pwd_system) 1488 goto fail_clear_attr; 1489 1490 if (tlmi_priv.pwdcfg.core.password_state & TLMI_SYS_PWD) 1491 tlmi_priv.pwd_system->valid = true; 1492 1493 tlmi_priv.pwd_hdd = tlmi_create_auth("hdd", "hdd"); 1494 if (!tlmi_priv.pwd_hdd) 1495 goto fail_clear_attr; 1496 1497 tlmi_priv.pwd_nvme = tlmi_create_auth("nvm", "nvme"); 1498 if (!tlmi_priv.pwd_nvme) 1499 goto fail_clear_attr; 1500 1501 if (tlmi_priv.pwdcfg.core.password_state & TLMI_HDD_PWD) { 1502 /* Check if PWD is configured and set index to first drive found */ 1503 if (tlmi_priv.pwdcfg.ext.hdd_user_password || 1504 tlmi_priv.pwdcfg.ext.hdd_master_password) { 1505 tlmi_priv.pwd_hdd->valid = true; 1506 if (tlmi_priv.pwdcfg.ext.hdd_master_password) 1507 tlmi_priv.pwd_hdd->index = 1508 ffs(tlmi_priv.pwdcfg.ext.hdd_master_password) - 1; 1509 else 1510 tlmi_priv.pwd_hdd->index = 1511 ffs(tlmi_priv.pwdcfg.ext.hdd_user_password) - 1; 1512 } 1513 if (tlmi_priv.pwdcfg.ext.nvme_user_password || 1514 tlmi_priv.pwdcfg.ext.nvme_master_password) { 1515 tlmi_priv.pwd_nvme->valid = true; 1516 if (tlmi_priv.pwdcfg.ext.nvme_master_password) 1517 tlmi_priv.pwd_nvme->index = 1518 ffs(tlmi_priv.pwdcfg.ext.nvme_master_password) - 1; 1519 else 1520 tlmi_priv.pwd_nvme->index = 1521 ffs(tlmi_priv.pwdcfg.ext.nvme_user_password) - 1; 1522 } 1523 } 1524 } 1525 1526 if (tlmi_priv.certificate_support && 1527 (tlmi_priv.pwdcfg.core.password_state & TLMI_CERT)) 1528 tlmi_priv.pwd_admin->cert_installed = true; 1529 1530 return 0; 1531 1532 fail_clear_attr: 1533 for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) { 1534 if (tlmi_priv.setting[i]) { 1535 kfree(tlmi_priv.setting[i]->possible_values); 1536 kfree(tlmi_priv.setting[i]); 1537 } 1538 } 1539 kfree(tlmi_priv.pwd_admin); 1540 kfree(tlmi_priv.pwd_power); 1541 kfree(tlmi_priv.pwd_system); 1542 kfree(tlmi_priv.pwd_hdd); 1543 kfree(tlmi_priv.pwd_nvme); 1544 return ret; 1545 } 1546 1547 static void tlmi_remove(struct wmi_device *wdev) 1548 { 1549 tlmi_release_attr(); 1550 device_destroy(fw_attr_class, MKDEV(0, 0)); 1551 fw_attributes_class_put(); 1552 } 1553 1554 static int tlmi_probe(struct wmi_device *wdev, const void *context) 1555 { 1556 int ret; 1557 1558 ret = tlmi_analyze(); 1559 if (ret) 1560 return ret; 1561 1562 return tlmi_sysfs_init(); 1563 } 1564 1565 static const struct wmi_device_id tlmi_id_table[] = { 1566 { .guid_string = LENOVO_BIOS_SETTING_GUID }, 1567 { } 1568 }; 1569 MODULE_DEVICE_TABLE(wmi, tlmi_id_table); 1570 1571 static struct wmi_driver tlmi_driver = { 1572 .driver = { 1573 .name = "think-lmi", 1574 }, 1575 .id_table = tlmi_id_table, 1576 .probe = tlmi_probe, 1577 .remove = tlmi_remove, 1578 }; 1579 1580 MODULE_AUTHOR("Sugumaran L <slacshiminar@lenovo.com>"); 1581 MODULE_AUTHOR("Mark Pearson <markpearson@lenovo.com>"); 1582 MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>"); 1583 MODULE_DESCRIPTION("ThinkLMI Driver"); 1584 MODULE_LICENSE("GPL"); 1585 1586 module_wmi_driver(tlmi_driver); 1587