efi_selftest_variables.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * efi_selftest_variables
  4. *
  5. * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  6. *
  7. * This unit test checks the following protocol services:
  8. * ConnectController, DisconnectController,
  9. * InstallProtocol, ReinstallProtocol, UninstallProtocol,
  10. * OpenProtocol, CloseProtcol, OpenProtocolInformation
  11. */
  12. #include <efi_selftest.h>
  13. #define EFI_ST_MAX_DATA_SIZE 16
  14. #define EFI_ST_MAX_VARNAME_SIZE 40
  15. static struct efi_boot_services *boottime;
  16. static struct efi_runtime_services *runtime;
  17. static efi_guid_t guid_vendor0 =
  18. EFI_GUID(0x67029eb5, 0x0af2, 0xf6b1,
  19. 0xda, 0x53, 0xfc, 0xb5, 0x66, 0xdd, 0x1c, 0xe6);
  20. static efi_guid_t guid_vendor1 =
  21. EFI_GUID(0xff629290, 0x1fc1, 0xd73f,
  22. 0x8f, 0xb1, 0x32, 0xf9, 0x0c, 0xa0, 0x42, 0xea);
  23. /*
  24. * Setup unit test.
  25. *
  26. * @handle handle of the loaded image
  27. * @systable system table
  28. */
  29. static int setup(const efi_handle_t img_handle,
  30. const struct efi_system_table *systable)
  31. {
  32. boottime = systable->boottime;
  33. runtime = systable->runtime;
  34. return EFI_ST_SUCCESS;
  35. }
  36. /*
  37. * Execute unit test.
  38. */
  39. static int execute(void)
  40. {
  41. efi_status_t ret;
  42. efi_uintn_t len;
  43. u32 attr;
  44. u8 v[16] = {0x5d, 0xd1, 0x5e, 0x51, 0x5a, 0x05, 0xc7, 0x0c,
  45. 0x35, 0x4a, 0xae, 0x87, 0xa5, 0xdf, 0x0f, 0x65,};
  46. u8 data[EFI_ST_MAX_DATA_SIZE];
  47. u16 varname[EFI_ST_MAX_VARNAME_SIZE];
  48. int flag;
  49. efi_guid_t guid;
  50. u64 max_storage, rem_storage, max_size;
  51. ret = runtime->query_variable_info(EFI_VARIABLE_BOOTSERVICE_ACCESS,
  52. &max_storage, &rem_storage,
  53. &max_size);
  54. if (ret != EFI_SUCCESS) {
  55. efi_st_todo("QueryVariableInfo failed\n");
  56. } else if (!max_storage || !rem_storage || !max_size) {
  57. efi_st_error("QueryVariableInfo: wrong info\n");
  58. return EFI_ST_FAILURE;
  59. }
  60. /* Set variable 0 */
  61. ret = runtime->set_variable(L"efi_st_var0", &guid_vendor0,
  62. EFI_VARIABLE_BOOTSERVICE_ACCESS,
  63. 3, v + 4);
  64. if (ret != EFI_SUCCESS) {
  65. efi_st_error("SetVariable failed\n");
  66. return EFI_ST_FAILURE;
  67. }
  68. data[3] = 0xff;
  69. len = 3;
  70. ret = runtime->get_variable(L"efi_st_var0", &guid_vendor0,
  71. &attr, &len, data);
  72. if (ret != EFI_SUCCESS) {
  73. efi_st_error("GetVariable failed\n");
  74. return EFI_ST_FAILURE;
  75. }
  76. if (efi_st_memcmp(data, v + 4, 3)) {
  77. efi_st_error("GetVariable returned wrong value\n");
  78. return EFI_ST_FAILURE;
  79. }
  80. if (data[3] != 0xff) {
  81. efi_st_error("GetVariable wrote past the end of the buffer\n");
  82. return EFI_ST_FAILURE;
  83. }
  84. /* Set variable 1 */
  85. ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1,
  86. EFI_VARIABLE_BOOTSERVICE_ACCESS,
  87. 8, v);
  88. if (ret != EFI_SUCCESS) {
  89. efi_st_error("SetVariable failed\n");
  90. return EFI_ST_FAILURE;
  91. }
  92. len = EFI_ST_MAX_DATA_SIZE;
  93. ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1,
  94. &attr, &len, data);
  95. if (ret != EFI_SUCCESS) {
  96. efi_st_error("GetVariable failed\n");
  97. return EFI_ST_FAILURE;
  98. }
  99. if (len != 8) {
  100. efi_st_error("GetVariable returned wrong length %u\n",
  101. (unsigned int)len);
  102. return EFI_ST_FAILURE;
  103. }
  104. if (efi_st_memcmp(data, v, 8)) {
  105. efi_st_error("GetVariable returned wrong value\n");
  106. return EFI_ST_FAILURE;
  107. }
  108. /* Append variable 1 */
  109. ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1,
  110. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  111. EFI_VARIABLE_APPEND_WRITE,
  112. 7, v + 8);
  113. if (ret != EFI_SUCCESS) {
  114. efi_st_error("SetVariable failed\n");
  115. return EFI_ST_FAILURE;
  116. }
  117. len = EFI_ST_MAX_DATA_SIZE;
  118. ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1,
  119. &attr, &len, data);
  120. if (ret != EFI_SUCCESS) {
  121. efi_st_error("GetVariable failed\n");
  122. return EFI_ST_FAILURE;
  123. }
  124. if (len != 15)
  125. efi_st_todo("GetVariable returned wrong length %u\n",
  126. (unsigned int)len);
  127. if (efi_st_memcmp(data, v, len))
  128. efi_st_todo("GetVariable returned wrong value\n");
  129. /* Enumerate variables */
  130. boottime->set_mem(&guid, 16, 0);
  131. *varname = 0;
  132. flag = 0;
  133. for (;;) {
  134. len = EFI_ST_MAX_VARNAME_SIZE;
  135. ret = runtime->get_next_variable_name(&len, varname, &guid);
  136. if (ret == EFI_NOT_FOUND)
  137. break;
  138. if (ret != EFI_SUCCESS) {
  139. efi_st_todo("GetNextVariableName failed\n");
  140. break;
  141. }
  142. if (!efi_st_memcmp(&guid, &guid_vendor0, sizeof(efi_guid_t)) &&
  143. !efi_st_strcmp_16_8(varname, "efi_st_var0"))
  144. flag |= 2;
  145. if (!efi_st_memcmp(&guid, &guid_vendor1, sizeof(efi_guid_t)) &&
  146. !efi_st_strcmp_16_8(varname, "efi_st_var1"))
  147. flag |= 2;
  148. }
  149. if (flag != 3)
  150. efi_st_todo(
  151. "GetNextVariableName did not return all variables\n");
  152. /* Delete variable 1 */
  153. ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1,
  154. 0, 0, NULL);
  155. if (ret != EFI_SUCCESS) {
  156. efi_st_error("SetVariable failed\n");
  157. return EFI_ST_FAILURE;
  158. }
  159. len = EFI_ST_MAX_DATA_SIZE;
  160. ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1,
  161. &attr, &len, data);
  162. if (ret != EFI_NOT_FOUND) {
  163. efi_st_error("Variable was not deleted\n");
  164. return EFI_ST_FAILURE;
  165. }
  166. /* Delete variable 0 */
  167. ret = runtime->set_variable(L"efi_st_var0", &guid_vendor0,
  168. 0, 0, NULL);
  169. if (ret != EFI_SUCCESS) {
  170. efi_st_error("SetVariable failed\n");
  171. return EFI_ST_FAILURE;
  172. }
  173. len = EFI_ST_MAX_DATA_SIZE;
  174. ret = runtime->get_variable(L"efi_st_var0", &guid_vendor0,
  175. &attr, &len, data);
  176. if (ret != EFI_NOT_FOUND) {
  177. efi_st_error("Variable was not deleted\n");
  178. return EFI_ST_FAILURE;
  179. }
  180. return EFI_ST_SUCCESS;
  181. }
  182. EFI_UNIT_TEST(variables) = {
  183. .name = "variables",
  184. .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
  185. .setup = setup,
  186. .execute = execute,
  187. };