think-lmi.c 47 KB

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