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