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