think-lmi.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641
  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 <[email protected]>
  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.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 (1 << 0)
  155. #define TLMI_PAP_PWD (1 << 1)
  156. #define TLMI_HDD_PWD (1 << 2)
  157. #define TLMI_SMP_PWD (1 << 6) /* System Management */
  158. #define TLMI_CERT (1 << 7)
  159. #define to_tlmi_pwd_setting(kobj) container_of(kobj, struct tlmi_pwd_setting, kobj)
  160. #define to_tlmi_attr_setting(kobj) container_of(kobj, struct tlmi_attr_setting, kobj)
  161. static const struct tlmi_err_codes tlmi_errs[] = {
  162. {"Success", 0},
  163. {"Not Supported", -EOPNOTSUPP},
  164. {"Invalid Parameter", -EINVAL},
  165. {"Access Denied", -EACCES},
  166. {"System Busy", -EBUSY},
  167. };
  168. static const char * const encoding_options[] = {
  169. [TLMI_ENCODING_ASCII] = "ascii",
  170. [TLMI_ENCODING_SCANCODE] = "scancode",
  171. };
  172. static const char * const level_options[] = {
  173. [TLMI_LEVEL_USER] = "user",
  174. [TLMI_LEVEL_MASTER] = "master",
  175. };
  176. static struct think_lmi tlmi_priv;
  177. static struct class *fw_attr_class;
  178. static DEFINE_MUTEX(tlmi_mutex);
  179. /* ------ Utility functions ------------*/
  180. /* Strip out CR if one is present */
  181. static void strip_cr(char *str)
  182. {
  183. char *p = strchrnul(str, '\n');
  184. *p = '\0';
  185. }
  186. /* Convert BIOS WMI error string to suitable error code */
  187. static int tlmi_errstr_to_err(const char *errstr)
  188. {
  189. int i;
  190. for (i = 0; i < sizeof(tlmi_errs)/sizeof(struct tlmi_err_codes); i++) {
  191. if (!strcmp(tlmi_errs[i].err_str, errstr))
  192. return tlmi_errs[i].err_code;
  193. }
  194. return -EPERM;
  195. }
  196. /* Extract error string from WMI return buffer */
  197. static int tlmi_extract_error(const struct acpi_buffer *output)
  198. {
  199. const union acpi_object *obj;
  200. obj = output->pointer;
  201. if (!obj)
  202. return -ENOMEM;
  203. if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer)
  204. return -EIO;
  205. return tlmi_errstr_to_err(obj->string.pointer);
  206. }
  207. /* Utility function to execute WMI call to BIOS */
  208. static int tlmi_simple_call(const char *guid, const char *arg)
  209. {
  210. const struct acpi_buffer input = { strlen(arg), (char *)arg };
  211. struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
  212. acpi_status status;
  213. int i, err;
  214. /*
  215. * Duplicated call required to match BIOS workaround for behavior
  216. * seen when WMI accessed via scripting on other OS.
  217. */
  218. for (i = 0; i < 2; i++) {
  219. /* (re)initialize output buffer to default state */
  220. output.length = ACPI_ALLOCATE_BUFFER;
  221. output.pointer = NULL;
  222. status = wmi_evaluate_method(guid, 0, 0, &input, &output);
  223. if (ACPI_FAILURE(status)) {
  224. kfree(output.pointer);
  225. return -EIO;
  226. }
  227. err = tlmi_extract_error(&output);
  228. kfree(output.pointer);
  229. if (err)
  230. return err;
  231. }
  232. return 0;
  233. }
  234. /* Extract output string from WMI return buffer */
  235. static int tlmi_extract_output_string(const struct acpi_buffer *output,
  236. char **string)
  237. {
  238. const union acpi_object *obj;
  239. char *s;
  240. obj = output->pointer;
  241. if (!obj)
  242. return -ENOMEM;
  243. if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer)
  244. return -EIO;
  245. s = kstrdup(obj->string.pointer, GFP_KERNEL);
  246. if (!s)
  247. return -ENOMEM;
  248. *string = s;
  249. return 0;
  250. }
  251. /* ------ Core interface functions ------------*/
  252. /* Get password settings from BIOS */
  253. static int tlmi_get_pwd_settings(struct tlmi_pwdcfg *pwdcfg)
  254. {
  255. struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
  256. const union acpi_object *obj;
  257. acpi_status status;
  258. int copy_size;
  259. if (!tlmi_priv.can_get_password_settings)
  260. return -EOPNOTSUPP;
  261. status = wmi_query_block(LENOVO_BIOS_PASSWORD_SETTINGS_GUID, 0,
  262. &output);
  263. if (ACPI_FAILURE(status))
  264. return -EIO;
  265. obj = output.pointer;
  266. if (!obj)
  267. return -ENOMEM;
  268. if (obj->type != ACPI_TYPE_BUFFER || !obj->buffer.pointer) {
  269. kfree(obj);
  270. return -EIO;
  271. }
  272. /*
  273. * The size of thinkpad_wmi_pcfg on ThinkStation is larger than ThinkPad.
  274. * To make the driver compatible on different brands, we permit it to get
  275. * the data in below case.
  276. * Settings must have at minimum the core fields available
  277. */
  278. if (obj->buffer.length < sizeof(struct tlmi_pwdcfg_core)) {
  279. pr_warn("Unknown pwdcfg buffer length %d\n", obj->buffer.length);
  280. kfree(obj);
  281. return -EIO;
  282. }
  283. copy_size = obj->buffer.length < sizeof(struct tlmi_pwdcfg) ?
  284. obj->buffer.length : sizeof(struct tlmi_pwdcfg);
  285. memcpy(pwdcfg, obj->buffer.pointer, copy_size);
  286. kfree(obj);
  287. if (WARN_ON(pwdcfg->core.max_length >= TLMI_PWD_BUFSIZE))
  288. pwdcfg->core.max_length = TLMI_PWD_BUFSIZE - 1;
  289. return 0;
  290. }
  291. static int tlmi_save_bios_settings(const char *password)
  292. {
  293. return tlmi_simple_call(LENOVO_SAVE_BIOS_SETTINGS_GUID,
  294. password);
  295. }
  296. static int tlmi_opcode_setting(char *setting, const char *value)
  297. {
  298. char *opcode_str;
  299. int ret;
  300. opcode_str = kasprintf(GFP_KERNEL, "%s:%s;", setting, value);
  301. if (!opcode_str)
  302. return -ENOMEM;
  303. ret = tlmi_simple_call(LENOVO_OPCODE_IF_GUID, opcode_str);
  304. kfree(opcode_str);
  305. return ret;
  306. }
  307. static int tlmi_setting(int item, char **value, const char *guid_string)
  308. {
  309. struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
  310. acpi_status status;
  311. int ret;
  312. status = wmi_query_block(guid_string, item, &output);
  313. if (ACPI_FAILURE(status)) {
  314. kfree(output.pointer);
  315. return -EIO;
  316. }
  317. ret = tlmi_extract_output_string(&output, value);
  318. kfree(output.pointer);
  319. return ret;
  320. }
  321. static int tlmi_get_bios_selections(const char *item, char **value)
  322. {
  323. const struct acpi_buffer input = { strlen(item), (char *)item };
  324. struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
  325. acpi_status status;
  326. int ret;
  327. status = wmi_evaluate_method(LENOVO_GET_BIOS_SELECTIONS_GUID,
  328. 0, 0, &input, &output);
  329. if (ACPI_FAILURE(status)) {
  330. kfree(output.pointer);
  331. return -EIO;
  332. }
  333. ret = tlmi_extract_output_string(&output, value);
  334. kfree(output.pointer);
  335. return ret;
  336. }
  337. /* ---- Authentication sysfs --------------------------------------------------------- */
  338. static ssize_t is_enabled_show(struct kobject *kobj, struct kobj_attribute *attr,
  339. char *buf)
  340. {
  341. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  342. return sysfs_emit(buf, "%d\n", setting->valid);
  343. }
  344. static struct kobj_attribute auth_is_pass_set = __ATTR_RO(is_enabled);
  345. static ssize_t current_password_store(struct kobject *kobj,
  346. struct kobj_attribute *attr,
  347. const char *buf, size_t count)
  348. {
  349. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  350. size_t pwdlen;
  351. pwdlen = strlen(buf);
  352. /* pwdlen == 0 is allowed to clear the password */
  353. if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen)))
  354. return -EINVAL;
  355. strscpy(setting->password, buf, setting->maxlen);
  356. /* Strip out CR if one is present, setting password won't work if it is present */
  357. strip_cr(setting->password);
  358. return count;
  359. }
  360. static struct kobj_attribute auth_current_password = __ATTR_WO(current_password);
  361. static ssize_t new_password_store(struct kobject *kobj,
  362. struct kobj_attribute *attr,
  363. const char *buf, size_t count)
  364. {
  365. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  366. char *auth_str, *new_pwd;
  367. size_t pwdlen;
  368. int ret;
  369. if (!capable(CAP_SYS_ADMIN))
  370. return -EPERM;
  371. if (!tlmi_priv.can_set_bios_password)
  372. return -EOPNOTSUPP;
  373. new_pwd = kstrdup(buf, GFP_KERNEL);
  374. if (!new_pwd)
  375. return -ENOMEM;
  376. /* Strip out CR if one is present, setting password won't work if it is present */
  377. strip_cr(new_pwd);
  378. /* Use lock in case multiple WMI operations needed */
  379. mutex_lock(&tlmi_mutex);
  380. pwdlen = strlen(new_pwd);
  381. /* pwdlen == 0 is allowed to clear the password */
  382. if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen))) {
  383. ret = -EINVAL;
  384. goto out;
  385. }
  386. /* If opcode support is present use that interface */
  387. if (tlmi_priv.opcode_support) {
  388. char pwd_type[8];
  389. /* Special handling required for HDD and NVMe passwords */
  390. if (setting == tlmi_priv.pwd_hdd) {
  391. if (setting->level == TLMI_LEVEL_USER)
  392. sprintf(pwd_type, "uhdp%d", setting->index);
  393. else
  394. sprintf(pwd_type, "mhdp%d", setting->index);
  395. } else if (setting == tlmi_priv.pwd_nvme) {
  396. if (setting->level == TLMI_LEVEL_USER)
  397. sprintf(pwd_type, "udrp%d", setting->index);
  398. else
  399. sprintf(pwd_type, "adrp%d", setting->index);
  400. } else {
  401. sprintf(pwd_type, "%s", setting->pwd_type);
  402. }
  403. ret = tlmi_opcode_setting("WmiOpcodePasswordType", pwd_type);
  404. if (ret)
  405. goto out;
  406. if (tlmi_priv.pwd_admin->valid) {
  407. ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
  408. tlmi_priv.pwd_admin->password);
  409. if (ret)
  410. goto out;
  411. }
  412. ret = tlmi_opcode_setting("WmiOpcodePasswordCurrent01", setting->password);
  413. if (ret)
  414. goto out;
  415. ret = tlmi_opcode_setting("WmiOpcodePasswordNew01", new_pwd);
  416. if (ret)
  417. goto out;
  418. ret = tlmi_simple_call(LENOVO_OPCODE_IF_GUID, "WmiOpcodePasswordSetUpdate;");
  419. } else {
  420. /* Format: 'PasswordType,CurrentPw,NewPw,Encoding,KbdLang;' */
  421. auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s,%s,%s;",
  422. setting->pwd_type, setting->password, new_pwd,
  423. encoding_options[setting->encoding], setting->kbdlang);
  424. if (!auth_str) {
  425. ret = -ENOMEM;
  426. goto out;
  427. }
  428. ret = tlmi_simple_call(LENOVO_SET_BIOS_PASSWORD_GUID, auth_str);
  429. kfree(auth_str);
  430. }
  431. out:
  432. mutex_unlock(&tlmi_mutex);
  433. kfree(new_pwd);
  434. return ret ?: count;
  435. }
  436. static struct kobj_attribute auth_new_password = __ATTR_WO(new_password);
  437. static ssize_t min_password_length_show(struct kobject *kobj, struct kobj_attribute *attr,
  438. char *buf)
  439. {
  440. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  441. return sysfs_emit(buf, "%d\n", setting->minlen);
  442. }
  443. static struct kobj_attribute auth_min_pass_length = __ATTR_RO(min_password_length);
  444. static ssize_t max_password_length_show(struct kobject *kobj, struct kobj_attribute *attr,
  445. char *buf)
  446. {
  447. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  448. return sysfs_emit(buf, "%d\n", setting->maxlen);
  449. }
  450. static struct kobj_attribute auth_max_pass_length = __ATTR_RO(max_password_length);
  451. static ssize_t mechanism_show(struct kobject *kobj, struct kobj_attribute *attr,
  452. char *buf)
  453. {
  454. return sysfs_emit(buf, "password\n");
  455. }
  456. static struct kobj_attribute auth_mechanism = __ATTR_RO(mechanism);
  457. static ssize_t encoding_show(struct kobject *kobj, struct kobj_attribute *attr,
  458. char *buf)
  459. {
  460. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  461. return sysfs_emit(buf, "%s\n", encoding_options[setting->encoding]);
  462. }
  463. static ssize_t encoding_store(struct kobject *kobj,
  464. struct kobj_attribute *attr,
  465. const char *buf, size_t count)
  466. {
  467. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  468. int i;
  469. /* Scan for a matching profile */
  470. i = sysfs_match_string(encoding_options, buf);
  471. if (i < 0)
  472. return -EINVAL;
  473. setting->encoding = i;
  474. return count;
  475. }
  476. static struct kobj_attribute auth_encoding = __ATTR_RW(encoding);
  477. static ssize_t kbdlang_show(struct kobject *kobj, struct kobj_attribute *attr,
  478. char *buf)
  479. {
  480. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  481. return sysfs_emit(buf, "%s\n", setting->kbdlang);
  482. }
  483. static ssize_t kbdlang_store(struct kobject *kobj,
  484. struct kobj_attribute *attr,
  485. const char *buf, size_t count)
  486. {
  487. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  488. int length;
  489. /* Calculate length till '\n' or terminating 0 */
  490. length = strchrnul(buf, '\n') - buf;
  491. if (!length || length >= TLMI_LANG_MAXLEN)
  492. return -EINVAL;
  493. memcpy(setting->kbdlang, buf, length);
  494. setting->kbdlang[length] = '\0';
  495. return count;
  496. }
  497. static struct kobj_attribute auth_kbdlang = __ATTR_RW(kbdlang);
  498. static ssize_t role_show(struct kobject *kobj, struct kobj_attribute *attr,
  499. char *buf)
  500. {
  501. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  502. return sysfs_emit(buf, "%s\n", setting->role);
  503. }
  504. static struct kobj_attribute auth_role = __ATTR_RO(role);
  505. static ssize_t index_show(struct kobject *kobj, struct kobj_attribute *attr,
  506. char *buf)
  507. {
  508. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  509. return sysfs_emit(buf, "%d\n", setting->index);
  510. }
  511. static ssize_t index_store(struct kobject *kobj,
  512. struct kobj_attribute *attr,
  513. const char *buf, size_t count)
  514. {
  515. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  516. int err, val;
  517. err = kstrtoint(buf, 10, &val);
  518. if (err < 0)
  519. return err;
  520. if (val < 0 || val > TLMI_INDEX_MAX)
  521. return -EINVAL;
  522. setting->index = val;
  523. return count;
  524. }
  525. static struct kobj_attribute auth_index = __ATTR_RW(index);
  526. static ssize_t level_show(struct kobject *kobj, struct kobj_attribute *attr,
  527. char *buf)
  528. {
  529. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  530. return sysfs_emit(buf, "%s\n", level_options[setting->level]);
  531. }
  532. static ssize_t level_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. /* Scan for a matching profile */
  539. i = sysfs_match_string(level_options, buf);
  540. if (i < 0)
  541. return -EINVAL;
  542. setting->level = i;
  543. return count;
  544. }
  545. static struct kobj_attribute auth_level = __ATTR_RW(level);
  546. static ssize_t cert_thumbprint(char *buf, const char *arg, int count)
  547. {
  548. const struct acpi_buffer input = { strlen(arg), (char *)arg };
  549. struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
  550. const union acpi_object *obj;
  551. acpi_status status;
  552. status = wmi_evaluate_method(LENOVO_CERT_THUMBPRINT_GUID, 0, 0, &input, &output);
  553. if (ACPI_FAILURE(status)) {
  554. kfree(output.pointer);
  555. return -EIO;
  556. }
  557. obj = output.pointer;
  558. if (!obj)
  559. return -ENOMEM;
  560. if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer) {
  561. kfree(output.pointer);
  562. return -EIO;
  563. }
  564. count += sysfs_emit_at(buf, count, "%s : %s\n", arg, (char *)obj->string.pointer);
  565. kfree(output.pointer);
  566. return count;
  567. }
  568. static ssize_t certificate_thumbprint_show(struct kobject *kobj, struct kobj_attribute *attr,
  569. char *buf)
  570. {
  571. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  572. int count = 0;
  573. if (!tlmi_priv.certificate_support || !setting->cert_installed)
  574. return -EOPNOTSUPP;
  575. count += cert_thumbprint(buf, "Md5", count);
  576. count += cert_thumbprint(buf, "Sha1", count);
  577. count += cert_thumbprint(buf, "Sha256", count);
  578. return count;
  579. }
  580. static struct kobj_attribute auth_cert_thumb = __ATTR_RO(certificate_thumbprint);
  581. static ssize_t cert_to_password_store(struct kobject *kobj,
  582. struct kobj_attribute *attr,
  583. const char *buf, size_t count)
  584. {
  585. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  586. char *auth_str, *passwd;
  587. int ret;
  588. if (!capable(CAP_SYS_ADMIN))
  589. return -EPERM;
  590. if (!tlmi_priv.certificate_support)
  591. return -EOPNOTSUPP;
  592. if (!setting->cert_installed)
  593. return -EINVAL;
  594. if (!setting->signature || !setting->signature[0])
  595. return -EACCES;
  596. passwd = kstrdup(buf, GFP_KERNEL);
  597. if (!passwd)
  598. return -ENOMEM;
  599. /* Strip out CR if one is present */
  600. strip_cr(passwd);
  601. /* Format: 'Password,Signature' */
  602. auth_str = kasprintf(GFP_KERNEL, "%s,%s", passwd, setting->signature);
  603. if (!auth_str) {
  604. kfree_sensitive(passwd);
  605. return -ENOMEM;
  606. }
  607. ret = tlmi_simple_call(LENOVO_CERT_TO_PASSWORD_GUID, auth_str);
  608. kfree(auth_str);
  609. kfree_sensitive(passwd);
  610. return ret ?: count;
  611. }
  612. static struct kobj_attribute auth_cert_to_password = __ATTR_WO(cert_to_password);
  613. static ssize_t certificate_store(struct kobject *kobj,
  614. struct kobj_attribute *attr,
  615. const char *buf, size_t count)
  616. {
  617. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  618. char *auth_str, *new_cert;
  619. char *guid;
  620. int ret;
  621. if (!capable(CAP_SYS_ADMIN))
  622. return -EPERM;
  623. if (!tlmi_priv.certificate_support)
  624. return -EOPNOTSUPP;
  625. /* If empty then clear installed certificate */
  626. if ((buf[0] == '\0') || (buf[0] == '\n')) { /* Clear installed certificate */
  627. /* Check that signature is set */
  628. if (!setting->signature || !setting->signature[0])
  629. return -EACCES;
  630. /* Format: 'serial#, signature' */
  631. auth_str = kasprintf(GFP_KERNEL, "%s,%s",
  632. dmi_get_system_info(DMI_PRODUCT_SERIAL),
  633. setting->signature);
  634. if (!auth_str)
  635. return -ENOMEM;
  636. ret = tlmi_simple_call(LENOVO_CLEAR_BIOS_CERT_GUID, auth_str);
  637. kfree(auth_str);
  638. return ret ?: count;
  639. }
  640. new_cert = kstrdup(buf, GFP_KERNEL);
  641. if (!new_cert)
  642. return -ENOMEM;
  643. /* Strip out CR if one is present */
  644. strip_cr(new_cert);
  645. if (setting->cert_installed) {
  646. /* Certificate is installed so this is an update */
  647. if (!setting->signature || !setting->signature[0]) {
  648. kfree(new_cert);
  649. return -EACCES;
  650. }
  651. guid = LENOVO_UPDATE_BIOS_CERT_GUID;
  652. /* Format: 'Certificate,Signature' */
  653. auth_str = kasprintf(GFP_KERNEL, "%s,%s",
  654. new_cert, setting->signature);
  655. } else {
  656. /* This is a fresh install */
  657. if (!setting->valid || !setting->password[0]) {
  658. kfree(new_cert);
  659. return -EACCES;
  660. }
  661. guid = LENOVO_SET_BIOS_CERT_GUID;
  662. /* Format: 'Certificate,Admin-password' */
  663. auth_str = kasprintf(GFP_KERNEL, "%s,%s",
  664. new_cert, setting->password);
  665. }
  666. kfree(new_cert);
  667. if (!auth_str)
  668. return -ENOMEM;
  669. ret = tlmi_simple_call(guid, auth_str);
  670. kfree(auth_str);
  671. return ret ?: count;
  672. }
  673. static struct kobj_attribute auth_certificate = __ATTR_WO(certificate);
  674. static ssize_t signature_store(struct kobject *kobj,
  675. struct kobj_attribute *attr,
  676. const char *buf, size_t count)
  677. {
  678. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  679. char *new_signature;
  680. if (!capable(CAP_SYS_ADMIN))
  681. return -EPERM;
  682. if (!tlmi_priv.certificate_support)
  683. return -EOPNOTSUPP;
  684. new_signature = kstrdup(buf, GFP_KERNEL);
  685. if (!new_signature)
  686. return -ENOMEM;
  687. /* Strip out CR if one is present */
  688. strip_cr(new_signature);
  689. /* Free any previous signature */
  690. kfree(setting->signature);
  691. setting->signature = new_signature;
  692. return count;
  693. }
  694. static struct kobj_attribute auth_signature = __ATTR_WO(signature);
  695. static ssize_t save_signature_store(struct kobject *kobj,
  696. struct kobj_attribute *attr,
  697. const char *buf, size_t count)
  698. {
  699. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  700. char *new_signature;
  701. if (!capable(CAP_SYS_ADMIN))
  702. return -EPERM;
  703. if (!tlmi_priv.certificate_support)
  704. return -EOPNOTSUPP;
  705. new_signature = kstrdup(buf, GFP_KERNEL);
  706. if (!new_signature)
  707. return -ENOMEM;
  708. /* Strip out CR if one is present */
  709. strip_cr(new_signature);
  710. /* Free any previous signature */
  711. kfree(setting->save_signature);
  712. setting->save_signature = new_signature;
  713. return count;
  714. }
  715. static struct kobj_attribute auth_save_signature = __ATTR_WO(save_signature);
  716. static umode_t auth_attr_is_visible(struct kobject *kobj,
  717. struct attribute *attr, int n)
  718. {
  719. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  720. /* We only want to display level and index settings on HDD/NVMe */
  721. if ((attr == (struct attribute *)&auth_index) ||
  722. (attr == (struct attribute *)&auth_level)) {
  723. if ((setting == tlmi_priv.pwd_hdd) || (setting == tlmi_priv.pwd_nvme))
  724. return attr->mode;
  725. return 0;
  726. }
  727. /* We only display certificates on Admin account, if supported */
  728. if ((attr == (struct attribute *)&auth_certificate) ||
  729. (attr == (struct attribute *)&auth_signature) ||
  730. (attr == (struct attribute *)&auth_save_signature) ||
  731. (attr == (struct attribute *)&auth_cert_thumb) ||
  732. (attr == (struct attribute *)&auth_cert_to_password)) {
  733. if ((setting == tlmi_priv.pwd_admin) && tlmi_priv.certificate_support)
  734. return attr->mode;
  735. return 0;
  736. }
  737. return attr->mode;
  738. }
  739. static struct attribute *auth_attrs[] = {
  740. &auth_is_pass_set.attr,
  741. &auth_min_pass_length.attr,
  742. &auth_max_pass_length.attr,
  743. &auth_current_password.attr,
  744. &auth_new_password.attr,
  745. &auth_role.attr,
  746. &auth_mechanism.attr,
  747. &auth_encoding.attr,
  748. &auth_kbdlang.attr,
  749. &auth_index.attr,
  750. &auth_level.attr,
  751. &auth_certificate.attr,
  752. &auth_signature.attr,
  753. &auth_save_signature.attr,
  754. &auth_cert_thumb.attr,
  755. &auth_cert_to_password.attr,
  756. NULL
  757. };
  758. static const struct attribute_group auth_attr_group = {
  759. .is_visible = auth_attr_is_visible,
  760. .attrs = auth_attrs,
  761. };
  762. /* ---- Attributes sysfs --------------------------------------------------------- */
  763. static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *attr,
  764. char *buf)
  765. {
  766. struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
  767. return sysfs_emit(buf, "%s\n", setting->display_name);
  768. }
  769. static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  770. {
  771. struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
  772. char *item, *value, *p;
  773. int ret;
  774. ret = tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID);
  775. if (ret)
  776. return ret;
  777. /* validate and split from `item,value` -> `value` */
  778. value = strpbrk(item, ",");
  779. if (!value || value == item || !strlen(value + 1))
  780. ret = -EINVAL;
  781. else {
  782. /* On Workstations remove the Options part after the value */
  783. p = strchrnul(value, ';');
  784. *p = '\0';
  785. ret = sysfs_emit(buf, "%s\n", value + 1);
  786. }
  787. kfree(item);
  788. return ret;
  789. }
  790. static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  791. {
  792. struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
  793. return sysfs_emit(buf, "%s\n", setting->possible_values);
  794. }
  795. static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr,
  796. char *buf)
  797. {
  798. struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
  799. if (setting->possible_values) {
  800. /* Figure out what setting type is as BIOS does not return this */
  801. if (strchr(setting->possible_values, ';'))
  802. return sysfs_emit(buf, "enumeration\n");
  803. }
  804. /* Anything else is going to be a string */
  805. return sysfs_emit(buf, "string\n");
  806. }
  807. static ssize_t current_value_store(struct kobject *kobj,
  808. struct kobj_attribute *attr,
  809. const char *buf, size_t count)
  810. {
  811. struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
  812. char *set_str = NULL, *new_setting = NULL;
  813. char *auth_str = NULL;
  814. int ret;
  815. if (!tlmi_priv.can_set_bios_settings)
  816. return -EOPNOTSUPP;
  817. new_setting = kstrdup(buf, GFP_KERNEL);
  818. if (!new_setting)
  819. return -ENOMEM;
  820. /* Strip out CR if one is present */
  821. strip_cr(new_setting);
  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->display_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. ret = tlmi_simple_call(LENOVO_SAVE_BIOS_SETTING_CERT_GUID,
  840. tlmi_priv.pwd_admin->save_signature);
  841. if (ret)
  842. goto out;
  843. } else { /* Non certiifcate based authentication */
  844. if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
  845. auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
  846. tlmi_priv.pwd_admin->password,
  847. encoding_options[tlmi_priv.pwd_admin->encoding],
  848. tlmi_priv.pwd_admin->kbdlang);
  849. if (!auth_str) {
  850. ret = -ENOMEM;
  851. goto out;
  852. }
  853. }
  854. if (auth_str)
  855. set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->display_name,
  856. new_setting, auth_str);
  857. else
  858. set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->display_name,
  859. new_setting);
  860. if (!set_str) {
  861. ret = -ENOMEM;
  862. goto out;
  863. }
  864. ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTINGS_GUID, set_str);
  865. if (ret)
  866. goto out;
  867. if (auth_str)
  868. ret = tlmi_save_bios_settings(auth_str);
  869. else
  870. ret = tlmi_save_bios_settings("");
  871. }
  872. if (!ret && !tlmi_priv.pending_changes) {
  873. tlmi_priv.pending_changes = true;
  874. /* let userland know it may need to check reboot pending again */
  875. kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
  876. }
  877. out:
  878. mutex_unlock(&tlmi_mutex);
  879. kfree(auth_str);
  880. kfree(set_str);
  881. kfree(new_setting);
  882. return ret ?: count;
  883. }
  884. static struct kobj_attribute attr_displ_name = __ATTR_RO(display_name);
  885. static struct kobj_attribute attr_possible_values = __ATTR_RO(possible_values);
  886. static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 0600);
  887. static struct kobj_attribute attr_type = __ATTR_RO(type);
  888. static umode_t attr_is_visible(struct kobject *kobj,
  889. struct attribute *attr, int n)
  890. {
  891. struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
  892. /* We don't want to display possible_values attributes if not available */
  893. if ((attr == &attr_possible_values.attr) && (!setting->possible_values))
  894. return 0;
  895. return attr->mode;
  896. }
  897. static struct attribute *tlmi_attrs[] = {
  898. &attr_displ_name.attr,
  899. &attr_current_val.attr,
  900. &attr_possible_values.attr,
  901. &attr_type.attr,
  902. NULL
  903. };
  904. static const struct attribute_group tlmi_attr_group = {
  905. .is_visible = attr_is_visible,
  906. .attrs = tlmi_attrs,
  907. };
  908. static ssize_t tlmi_attr_show(struct kobject *kobj, struct attribute *attr,
  909. char *buf)
  910. {
  911. struct kobj_attribute *kattr;
  912. kattr = container_of(attr, struct kobj_attribute, attr);
  913. if (kattr->show)
  914. return kattr->show(kobj, kattr, buf);
  915. return -EIO;
  916. }
  917. static ssize_t tlmi_attr_store(struct kobject *kobj, struct attribute *attr,
  918. const char *buf, size_t count)
  919. {
  920. struct kobj_attribute *kattr;
  921. kattr = container_of(attr, struct kobj_attribute, attr);
  922. if (kattr->store)
  923. return kattr->store(kobj, kattr, buf, count);
  924. return -EIO;
  925. }
  926. static const struct sysfs_ops tlmi_kobj_sysfs_ops = {
  927. .show = tlmi_attr_show,
  928. .store = tlmi_attr_store,
  929. };
  930. static void tlmi_attr_setting_release(struct kobject *kobj)
  931. {
  932. struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
  933. kfree(setting->possible_values);
  934. kfree(setting);
  935. }
  936. static void tlmi_pwd_setting_release(struct kobject *kobj)
  937. {
  938. struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
  939. kfree(setting);
  940. }
  941. static struct kobj_type tlmi_attr_setting_ktype = {
  942. .release = &tlmi_attr_setting_release,
  943. .sysfs_ops = &tlmi_kobj_sysfs_ops,
  944. };
  945. static struct kobj_type tlmi_pwd_setting_ktype = {
  946. .release = &tlmi_pwd_setting_release,
  947. .sysfs_ops = &tlmi_kobj_sysfs_ops,
  948. };
  949. static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr,
  950. char *buf)
  951. {
  952. return sprintf(buf, "%d\n", tlmi_priv.pending_changes);
  953. }
  954. static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
  955. /* ---- Debug interface--------------------------------------------------------- */
  956. static ssize_t debug_cmd_store(struct kobject *kobj, struct kobj_attribute *attr,
  957. const char *buf, size_t count)
  958. {
  959. char *set_str = NULL, *new_setting = NULL;
  960. char *auth_str = NULL;
  961. int ret;
  962. if (!tlmi_priv.can_debug_cmd)
  963. return -EOPNOTSUPP;
  964. new_setting = kstrdup(buf, GFP_KERNEL);
  965. if (!new_setting)
  966. return -ENOMEM;
  967. /* Strip out CR if one is present */
  968. strip_cr(new_setting);
  969. if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
  970. auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
  971. tlmi_priv.pwd_admin->password,
  972. encoding_options[tlmi_priv.pwd_admin->encoding],
  973. tlmi_priv.pwd_admin->kbdlang);
  974. if (!auth_str) {
  975. ret = -ENOMEM;
  976. goto out;
  977. }
  978. }
  979. if (auth_str)
  980. set_str = kasprintf(GFP_KERNEL, "%s,%s", new_setting, auth_str);
  981. else
  982. set_str = kasprintf(GFP_KERNEL, "%s;", new_setting);
  983. if (!set_str) {
  984. ret = -ENOMEM;
  985. goto out;
  986. }
  987. ret = tlmi_simple_call(LENOVO_DEBUG_CMD_GUID, set_str);
  988. if (ret)
  989. goto out;
  990. if (!ret && !tlmi_priv.pending_changes) {
  991. tlmi_priv.pending_changes = true;
  992. /* let userland know it may need to check reboot pending again */
  993. kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
  994. }
  995. out:
  996. kfree(auth_str);
  997. kfree(set_str);
  998. kfree(new_setting);
  999. return ret ?: count;
  1000. }
  1001. static struct kobj_attribute debug_cmd = __ATTR_WO(debug_cmd);
  1002. /* ---- Initialisation --------------------------------------------------------- */
  1003. static void tlmi_release_attr(void)
  1004. {
  1005. int i;
  1006. /* Attribute structures */
  1007. for (i = 0; i < TLMI_SETTINGS_COUNT; i++) {
  1008. if (tlmi_priv.setting[i]) {
  1009. sysfs_remove_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group);
  1010. kobject_put(&tlmi_priv.setting[i]->kobj);
  1011. }
  1012. }
  1013. sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr);
  1014. if (tlmi_priv.can_debug_cmd && debug_support)
  1015. sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr);
  1016. kset_unregister(tlmi_priv.attribute_kset);
  1017. /* Free up any saved signatures */
  1018. kfree(tlmi_priv.pwd_admin->signature);
  1019. kfree(tlmi_priv.pwd_admin->save_signature);
  1020. /* Authentication structures */
  1021. sysfs_remove_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group);
  1022. kobject_put(&tlmi_priv.pwd_admin->kobj);
  1023. sysfs_remove_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group);
  1024. kobject_put(&tlmi_priv.pwd_power->kobj);
  1025. if (tlmi_priv.opcode_support) {
  1026. sysfs_remove_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group);
  1027. kobject_put(&tlmi_priv.pwd_system->kobj);
  1028. sysfs_remove_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group);
  1029. kobject_put(&tlmi_priv.pwd_hdd->kobj);
  1030. sysfs_remove_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group);
  1031. kobject_put(&tlmi_priv.pwd_nvme->kobj);
  1032. }
  1033. kset_unregister(tlmi_priv.authentication_kset);
  1034. }
  1035. static int tlmi_validate_setting_name(struct kset *attribute_kset, char *name)
  1036. {
  1037. struct kobject *duplicate;
  1038. if (!strcmp(name, "Reserved"))
  1039. return -EINVAL;
  1040. duplicate = kset_find_obj(attribute_kset, name);
  1041. if (duplicate) {
  1042. pr_debug("Duplicate attribute name found - %s\n", name);
  1043. /* kset_find_obj() returns a reference */
  1044. kobject_put(duplicate);
  1045. return -EBUSY;
  1046. }
  1047. return 0;
  1048. }
  1049. static int tlmi_sysfs_init(void)
  1050. {
  1051. int i, ret;
  1052. ret = fw_attributes_class_get(&fw_attr_class);
  1053. if (ret)
  1054. return ret;
  1055. tlmi_priv.class_dev = device_create(fw_attr_class, NULL, MKDEV(0, 0),
  1056. NULL, "%s", "thinklmi");
  1057. if (IS_ERR(tlmi_priv.class_dev)) {
  1058. ret = PTR_ERR(tlmi_priv.class_dev);
  1059. goto fail_class_created;
  1060. }
  1061. tlmi_priv.attribute_kset = kset_create_and_add("attributes", NULL,
  1062. &tlmi_priv.class_dev->kobj);
  1063. if (!tlmi_priv.attribute_kset) {
  1064. ret = -ENOMEM;
  1065. goto fail_device_created;
  1066. }
  1067. for (i = 0; i < TLMI_SETTINGS_COUNT; i++) {
  1068. /* Check if index is a valid setting - skip if it isn't */
  1069. if (!tlmi_priv.setting[i])
  1070. continue;
  1071. /* check for duplicate or reserved values */
  1072. if (tlmi_validate_setting_name(tlmi_priv.attribute_kset,
  1073. tlmi_priv.setting[i]->display_name) < 0) {
  1074. kfree(tlmi_priv.setting[i]->possible_values);
  1075. kfree(tlmi_priv.setting[i]);
  1076. tlmi_priv.setting[i] = NULL;
  1077. continue;
  1078. }
  1079. /* Build attribute */
  1080. tlmi_priv.setting[i]->kobj.kset = tlmi_priv.attribute_kset;
  1081. ret = kobject_add(&tlmi_priv.setting[i]->kobj, NULL,
  1082. "%s", tlmi_priv.setting[i]->display_name);
  1083. if (ret)
  1084. goto fail_create_attr;
  1085. ret = sysfs_create_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group);
  1086. if (ret)
  1087. goto fail_create_attr;
  1088. }
  1089. ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr);
  1090. if (ret)
  1091. goto fail_create_attr;
  1092. if (tlmi_priv.can_debug_cmd && debug_support) {
  1093. ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr);
  1094. if (ret)
  1095. goto fail_create_attr;
  1096. }
  1097. /* Create authentication entries */
  1098. tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL,
  1099. &tlmi_priv.class_dev->kobj);
  1100. if (!tlmi_priv.authentication_kset) {
  1101. ret = -ENOMEM;
  1102. goto fail_create_attr;
  1103. }
  1104. tlmi_priv.pwd_admin->kobj.kset = tlmi_priv.authentication_kset;
  1105. ret = kobject_add(&tlmi_priv.pwd_admin->kobj, NULL, "%s", "Admin");
  1106. if (ret)
  1107. goto fail_create_attr;
  1108. ret = sysfs_create_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group);
  1109. if (ret)
  1110. goto fail_create_attr;
  1111. tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset;
  1112. ret = kobject_add(&tlmi_priv.pwd_power->kobj, NULL, "%s", "Power-on");
  1113. if (ret)
  1114. goto fail_create_attr;
  1115. ret = sysfs_create_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group);
  1116. if (ret)
  1117. goto fail_create_attr;
  1118. if (tlmi_priv.opcode_support) {
  1119. tlmi_priv.pwd_system->kobj.kset = tlmi_priv.authentication_kset;
  1120. ret = kobject_add(&tlmi_priv.pwd_system->kobj, NULL, "%s", "System");
  1121. if (ret)
  1122. goto fail_create_attr;
  1123. ret = sysfs_create_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group);
  1124. if (ret)
  1125. goto fail_create_attr;
  1126. tlmi_priv.pwd_hdd->kobj.kset = tlmi_priv.authentication_kset;
  1127. ret = kobject_add(&tlmi_priv.pwd_hdd->kobj, NULL, "%s", "HDD");
  1128. if (ret)
  1129. goto fail_create_attr;
  1130. ret = sysfs_create_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group);
  1131. if (ret)
  1132. goto fail_create_attr;
  1133. tlmi_priv.pwd_nvme->kobj.kset = tlmi_priv.authentication_kset;
  1134. ret = kobject_add(&tlmi_priv.pwd_nvme->kobj, NULL, "%s", "NVMe");
  1135. if (ret)
  1136. goto fail_create_attr;
  1137. ret = sysfs_create_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group);
  1138. if (ret)
  1139. goto fail_create_attr;
  1140. }
  1141. return ret;
  1142. fail_create_attr:
  1143. tlmi_release_attr();
  1144. fail_device_created:
  1145. device_destroy(fw_attr_class, MKDEV(0, 0));
  1146. fail_class_created:
  1147. fw_attributes_class_put();
  1148. return ret;
  1149. }
  1150. /* ---- Base Driver -------------------------------------------------------- */
  1151. static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type,
  1152. const char *pwd_role)
  1153. {
  1154. struct tlmi_pwd_setting *new_pwd;
  1155. new_pwd = kzalloc(sizeof(struct tlmi_pwd_setting), GFP_KERNEL);
  1156. if (!new_pwd)
  1157. return NULL;
  1158. strscpy(new_pwd->kbdlang, "us", TLMI_LANG_MAXLEN);
  1159. new_pwd->encoding = TLMI_ENCODING_ASCII;
  1160. new_pwd->pwd_type = pwd_type;
  1161. new_pwd->role = pwd_role;
  1162. new_pwd->minlen = tlmi_priv.pwdcfg.core.min_length;
  1163. new_pwd->maxlen = tlmi_priv.pwdcfg.core.max_length;
  1164. new_pwd->index = 0;
  1165. kobject_init(&new_pwd->kobj, &tlmi_pwd_setting_ktype);
  1166. return new_pwd;
  1167. }
  1168. static int tlmi_analyze(void)
  1169. {
  1170. acpi_status status;
  1171. int i, ret;
  1172. if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) &&
  1173. wmi_has_guid(LENOVO_SAVE_BIOS_SETTINGS_GUID))
  1174. tlmi_priv.can_set_bios_settings = true;
  1175. if (wmi_has_guid(LENOVO_GET_BIOS_SELECTIONS_GUID))
  1176. tlmi_priv.can_get_bios_selections = true;
  1177. if (wmi_has_guid(LENOVO_SET_BIOS_PASSWORD_GUID))
  1178. tlmi_priv.can_set_bios_password = true;
  1179. if (wmi_has_guid(LENOVO_BIOS_PASSWORD_SETTINGS_GUID))
  1180. tlmi_priv.can_get_password_settings = true;
  1181. if (wmi_has_guid(LENOVO_DEBUG_CMD_GUID))
  1182. tlmi_priv.can_debug_cmd = true;
  1183. if (wmi_has_guid(LENOVO_OPCODE_IF_GUID))
  1184. tlmi_priv.opcode_support = true;
  1185. if (wmi_has_guid(LENOVO_SET_BIOS_CERT_GUID) &&
  1186. wmi_has_guid(LENOVO_SET_BIOS_SETTING_CERT_GUID) &&
  1187. wmi_has_guid(LENOVO_SAVE_BIOS_SETTING_CERT_GUID))
  1188. tlmi_priv.certificate_support = true;
  1189. /*
  1190. * Try to find the number of valid settings of this machine
  1191. * and use it to create sysfs attributes.
  1192. */
  1193. for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) {
  1194. struct tlmi_attr_setting *setting;
  1195. char *item = NULL;
  1196. char *p;
  1197. tlmi_priv.setting[i] = NULL;
  1198. status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID);
  1199. if (ACPI_FAILURE(status))
  1200. break;
  1201. if (!item)
  1202. break;
  1203. if (!*item) {
  1204. kfree(item);
  1205. continue;
  1206. }
  1207. /* It is not allowed to have '/' for file name. Convert it into '\'. */
  1208. strreplace(item, '/', '\\');
  1209. /* Remove the value part */
  1210. p = strchrnul(item, ',');
  1211. *p = '\0';
  1212. /* Create a setting entry */
  1213. setting = kzalloc(sizeof(*setting), GFP_KERNEL);
  1214. if (!setting) {
  1215. ret = -ENOMEM;
  1216. kfree(item);
  1217. goto fail_clear_attr;
  1218. }
  1219. setting->index = i;
  1220. strscpy(setting->display_name, item, TLMI_SETTINGS_MAXLEN);
  1221. /* If BIOS selections supported, load those */
  1222. if (tlmi_priv.can_get_bios_selections) {
  1223. ret = tlmi_get_bios_selections(setting->display_name,
  1224. &setting->possible_values);
  1225. if (ret || !setting->possible_values)
  1226. pr_info("Error retrieving possible values for %d : %s\n",
  1227. i, setting->display_name);
  1228. } else {
  1229. /*
  1230. * Older Thinkstations don't support the bios_selections API.
  1231. * Instead they store this as a [Optional:Option1,Option2] section of the
  1232. * name string.
  1233. * Try and pull that out if it's available.
  1234. */
  1235. char *optitem, *optstart, *optend;
  1236. if (!tlmi_setting(setting->index, &optitem, LENOVO_BIOS_SETTING_GUID)) {
  1237. optstart = strstr(optitem, "[Optional:");
  1238. if (optstart) {
  1239. optstart += strlen("[Optional:");
  1240. optend = strstr(optstart, "]");
  1241. if (optend)
  1242. setting->possible_values =
  1243. kstrndup(optstart, optend - optstart,
  1244. GFP_KERNEL);
  1245. }
  1246. kfree(optitem);
  1247. }
  1248. }
  1249. /*
  1250. * firmware-attributes requires that possible_values are separated by ';' but
  1251. * Lenovo FW uses ','. Replace appropriately.
  1252. */
  1253. if (setting->possible_values)
  1254. strreplace(setting->possible_values, ',', ';');
  1255. kobject_init(&setting->kobj, &tlmi_attr_setting_ktype);
  1256. tlmi_priv.setting[i] = setting;
  1257. kfree(item);
  1258. }
  1259. /* Create password setting structure */
  1260. ret = tlmi_get_pwd_settings(&tlmi_priv.pwdcfg);
  1261. if (ret)
  1262. goto fail_clear_attr;
  1263. /* All failures below boil down to kmalloc failures */
  1264. ret = -ENOMEM;
  1265. tlmi_priv.pwd_admin = tlmi_create_auth("pap", "bios-admin");
  1266. if (!tlmi_priv.pwd_admin)
  1267. goto fail_clear_attr;
  1268. if (tlmi_priv.pwdcfg.core.password_state & TLMI_PAP_PWD)
  1269. tlmi_priv.pwd_admin->valid = true;
  1270. tlmi_priv.pwd_power = tlmi_create_auth("pop", "power-on");
  1271. if (!tlmi_priv.pwd_power)
  1272. goto fail_clear_attr;
  1273. if (tlmi_priv.pwdcfg.core.password_state & TLMI_POP_PWD)
  1274. tlmi_priv.pwd_power->valid = true;
  1275. if (tlmi_priv.opcode_support) {
  1276. tlmi_priv.pwd_system = tlmi_create_auth("smp", "system");
  1277. if (!tlmi_priv.pwd_system)
  1278. goto fail_clear_attr;
  1279. if (tlmi_priv.pwdcfg.core.password_state & TLMI_SMP_PWD)
  1280. tlmi_priv.pwd_system->valid = true;
  1281. tlmi_priv.pwd_hdd = tlmi_create_auth("hdd", "hdd");
  1282. if (!tlmi_priv.pwd_hdd)
  1283. goto fail_clear_attr;
  1284. tlmi_priv.pwd_nvme = tlmi_create_auth("nvm", "nvme");
  1285. if (!tlmi_priv.pwd_nvme)
  1286. goto fail_clear_attr;
  1287. if (tlmi_priv.pwdcfg.core.password_state & TLMI_HDD_PWD) {
  1288. /* Check if PWD is configured and set index to first drive found */
  1289. if (tlmi_priv.pwdcfg.ext.hdd_user_password ||
  1290. tlmi_priv.pwdcfg.ext.hdd_master_password) {
  1291. tlmi_priv.pwd_hdd->valid = true;
  1292. if (tlmi_priv.pwdcfg.ext.hdd_master_password)
  1293. tlmi_priv.pwd_hdd->index =
  1294. ffs(tlmi_priv.pwdcfg.ext.hdd_master_password) - 1;
  1295. else
  1296. tlmi_priv.pwd_hdd->index =
  1297. ffs(tlmi_priv.pwdcfg.ext.hdd_user_password) - 1;
  1298. }
  1299. if (tlmi_priv.pwdcfg.ext.nvme_user_password ||
  1300. tlmi_priv.pwdcfg.ext.nvme_master_password) {
  1301. tlmi_priv.pwd_nvme->valid = true;
  1302. if (tlmi_priv.pwdcfg.ext.nvme_master_password)
  1303. tlmi_priv.pwd_nvme->index =
  1304. ffs(tlmi_priv.pwdcfg.ext.nvme_master_password) - 1;
  1305. else
  1306. tlmi_priv.pwd_nvme->index =
  1307. ffs(tlmi_priv.pwdcfg.ext.nvme_user_password) - 1;
  1308. }
  1309. }
  1310. }
  1311. if (tlmi_priv.certificate_support &&
  1312. (tlmi_priv.pwdcfg.core.password_state & TLMI_CERT))
  1313. tlmi_priv.pwd_admin->cert_installed = true;
  1314. return 0;
  1315. fail_clear_attr:
  1316. for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) {
  1317. if (tlmi_priv.setting[i]) {
  1318. kfree(tlmi_priv.setting[i]->possible_values);
  1319. kfree(tlmi_priv.setting[i]);
  1320. }
  1321. }
  1322. kfree(tlmi_priv.pwd_admin);
  1323. kfree(tlmi_priv.pwd_power);
  1324. kfree(tlmi_priv.pwd_system);
  1325. kfree(tlmi_priv.pwd_hdd);
  1326. kfree(tlmi_priv.pwd_nvme);
  1327. return ret;
  1328. }
  1329. static void tlmi_remove(struct wmi_device *wdev)
  1330. {
  1331. tlmi_release_attr();
  1332. device_destroy(fw_attr_class, MKDEV(0, 0));
  1333. fw_attributes_class_put();
  1334. }
  1335. static int tlmi_probe(struct wmi_device *wdev, const void *context)
  1336. {
  1337. int ret;
  1338. ret = tlmi_analyze();
  1339. if (ret)
  1340. return ret;
  1341. return tlmi_sysfs_init();
  1342. }
  1343. static const struct wmi_device_id tlmi_id_table[] = {
  1344. { .guid_string = LENOVO_BIOS_SETTING_GUID },
  1345. { }
  1346. };
  1347. MODULE_DEVICE_TABLE(wmi, tlmi_id_table);
  1348. static struct wmi_driver tlmi_driver = {
  1349. .driver = {
  1350. .name = "think-lmi",
  1351. },
  1352. .id_table = tlmi_id_table,
  1353. .probe = tlmi_probe,
  1354. .remove = tlmi_remove,
  1355. };
  1356. MODULE_AUTHOR("Sugumaran L <[email protected]>");
  1357. MODULE_AUTHOR("Mark Pearson <[email protected]>");
  1358. MODULE_AUTHOR("Corentin Chary <[email protected]>");
  1359. MODULE_DESCRIPTION("ThinkLMI Driver");
  1360. MODULE_LICENSE("GPL");
  1361. module_wmi_driver(tlmi_driver);