vboot_api_kernel_tests.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
  2. * Use of this source code is governed by a BSD-style license that can be
  3. * found in the LICENSE file.
  4. *
  5. * Tests for VbTryLoadKernel()
  6. */
  7. #include <stddef.h>
  8. #include <stdint.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include "2sysincludes.h"
  12. #include "2api.h"
  13. #include "2nvstorage.h"
  14. #include "gbb_header.h"
  15. #include "load_kernel_fw.h"
  16. #include "rollback_index.h"
  17. #include "test_common.h"
  18. #include "utility.h"
  19. #include "vboot_api.h"
  20. #include "vboot_kernel.h"
  21. struct LoadKernelParams *VbApiKernelGetParams(void);
  22. #define MAX_TEST_DISKS 10
  23. #define DEFAULT_COUNT -1
  24. typedef struct {
  25. uint64_t bytes_per_lba;
  26. uint64_t lba_count;
  27. uint32_t flags;
  28. const char *diskname;
  29. } disk_desc_t;
  30. typedef struct {
  31. char *name;
  32. /* inputs for test case */
  33. uint32_t want_flags;
  34. VbError_t diskgetinfo_return_val;
  35. disk_desc_t disks_to_provide[MAX_TEST_DISKS];
  36. int disk_count_to_return;
  37. VbError_t loadkernel_return_val[MAX_TEST_DISKS];
  38. uint8_t external_expected[MAX_TEST_DISKS];
  39. /* outputs from test */
  40. uint32_t expected_recovery_request_val;
  41. const char *expected_to_find_disk;
  42. const char *expected_to_load_disk;
  43. uint32_t expected_return_val;
  44. } test_case_t;
  45. /****************************************************************************/
  46. /* Test cases */
  47. static const char pickme[] = "correct choice";
  48. #define DONT_CARE ((const char *)42)
  49. test_case_t test[] = {
  50. {
  51. .name = "first removable drive",
  52. .want_flags = VB_DISK_FLAG_REMOVABLE,
  53. .disks_to_provide = {
  54. /* too small */
  55. {512, 10, VB_DISK_FLAG_REMOVABLE, 0},
  56. /* wrong LBA */
  57. {2048, 100, VB_DISK_FLAG_REMOVABLE, 0},
  58. /* wrong type */
  59. {512, 100, VB_DISK_FLAG_FIXED, 0},
  60. /* wrong flags */
  61. {512, 100, 0, 0},
  62. /* still wrong flags */
  63. {512, 100, -1, 0},
  64. {512, 100,
  65. VB_DISK_FLAG_REMOVABLE | VB_DISK_FLAG_EXTERNAL_GPT,
  66. pickme},
  67. /* already got one */
  68. {512, 100, VB_DISK_FLAG_REMOVABLE, "holygrail"},
  69. },
  70. .disk_count_to_return = DEFAULT_COUNT,
  71. .diskgetinfo_return_val = VBERROR_SUCCESS,
  72. .loadkernel_return_val = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
  73. .external_expected = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
  74. .expected_recovery_request_val = VBNV_RECOVERY_NOT_REQUESTED,
  75. .expected_to_find_disk = pickme,
  76. .expected_to_load_disk = pickme,
  77. .expected_return_val = VBERROR_SUCCESS
  78. },
  79. {
  80. .name = "second removable drive",
  81. .want_flags = VB_DISK_FLAG_REMOVABLE,
  82. .disks_to_provide = {
  83. /* wrong flags */
  84. {512, 100, 0, 0},
  85. {512, 100, VB_DISK_FLAG_REMOVABLE, "not yet"},
  86. {512, 100, VB_DISK_FLAG_REMOVABLE, pickme},
  87. },
  88. .disk_count_to_return = DEFAULT_COUNT,
  89. .diskgetinfo_return_val = VBERROR_SUCCESS,
  90. .loadkernel_return_val = {1, 0, 1, 1, 1, 1, 1, 1, 1, 1,},
  91. .expected_recovery_request_val = VBNV_RECOVERY_NOT_REQUESTED,
  92. .expected_to_find_disk = pickme,
  93. .expected_to_load_disk = pickme,
  94. .expected_return_val = VBERROR_SUCCESS
  95. },
  96. {
  97. .name = "first fixed drive",
  98. .want_flags = VB_DISK_FLAG_FIXED,
  99. .disks_to_provide = {
  100. /* too small */
  101. {512, 10, VB_DISK_FLAG_FIXED, 0},
  102. /* wrong LBA */
  103. {2048, 100, VB_DISK_FLAG_FIXED, 0},
  104. /* wrong type */
  105. {512, 100, VB_DISK_FLAG_REMOVABLE, 0},
  106. /* wrong flags */
  107. {512, 100, 0, 0},
  108. /* still wrong flags */
  109. {512, 100, -1, 0},
  110. /* flags */
  111. {512, 100, VB_DISK_FLAG_REMOVABLE|VB_DISK_FLAG_FIXED,
  112. 0},
  113. {512, 100, VB_DISK_FLAG_FIXED, pickme},
  114. /* already got one */
  115. {512, 100, VB_DISK_FLAG_FIXED, "holygrail"},
  116. },
  117. .disk_count_to_return = DEFAULT_COUNT,
  118. .diskgetinfo_return_val = VBERROR_SUCCESS,
  119. .loadkernel_return_val = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
  120. .expected_recovery_request_val = VBNV_RECOVERY_NOT_REQUESTED,
  121. .expected_to_find_disk = pickme,
  122. .expected_to_load_disk = pickme,
  123. .expected_return_val = VBERROR_SUCCESS
  124. },
  125. {
  126. .name = "no drives at all",
  127. .want_flags = VB_DISK_FLAG_FIXED,
  128. .disks_to_provide = {},
  129. .disk_count_to_return = DEFAULT_COUNT,
  130. .diskgetinfo_return_val = VBERROR_SUCCESS,
  131. .loadkernel_return_val = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
  132. .expected_recovery_request_val = VBNV_RECOVERY_RW_NO_DISK,
  133. .expected_to_find_disk = 0,
  134. .expected_to_load_disk = 0,
  135. .expected_return_val = VBERROR_NO_DISK_FOUND
  136. },
  137. {
  138. .name = "no valid drives",
  139. .want_flags = VB_DISK_FLAG_FIXED,
  140. .disks_to_provide = {
  141. /* too small */
  142. {512, 10, VB_DISK_FLAG_FIXED, 0},
  143. /* wrong LBA */
  144. {2048, 100, VB_DISK_FLAG_FIXED, 0},
  145. /* wrong type */
  146. {512, 100, VB_DISK_FLAG_REMOVABLE, 0},
  147. /* wrong flags */
  148. {512, 100, 0, 0},
  149. /* still wrong flags */
  150. {512, 100, -1, 0},
  151. /* doesn't load */
  152. {512, 100, VB_DISK_FLAG_FIXED, "bad1"},
  153. /* doesn't load */
  154. {512, 100, VB_DISK_FLAG_FIXED, "bad2"},
  155. },
  156. .disk_count_to_return = DEFAULT_COUNT,
  157. .diskgetinfo_return_val = VBERROR_SUCCESS,
  158. .loadkernel_return_val = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
  159. .expected_recovery_request_val = VBNV_RECOVERY_RW_NO_KERNEL,
  160. .expected_to_find_disk = DONT_CARE,
  161. .expected_to_load_disk = 0,
  162. .expected_return_val = 1
  163. },
  164. };
  165. /****************************************************************************/
  166. /* Mock data */
  167. static VbDiskInfo mock_disks[MAX_TEST_DISKS];
  168. static test_case_t *t;
  169. static int load_kernel_calls;
  170. static uint32_t got_recovery_request_val;
  171. static const char *got_find_disk;
  172. static const char *got_load_disk;
  173. static uint32_t got_return_val;
  174. static uint32_t got_external_mismatch;
  175. static struct vb2_context ctx;
  176. /**
  177. * Reset mock data (for use before each test)
  178. */
  179. static void ResetMocks(int i)
  180. {
  181. memset(&ctx, 0, sizeof(ctx));
  182. memset(VbApiKernelGetParams(), 0, sizeof(LoadKernelParams));
  183. memset(&mock_disks, 0, sizeof(mock_disks));
  184. load_kernel_calls = 0;
  185. got_recovery_request_val = VBNV_RECOVERY_NOT_REQUESTED;
  186. got_find_disk = 0;
  187. got_load_disk = 0;
  188. got_return_val = 0xdeadbeef;
  189. t = test + i;
  190. }
  191. int is_nonzero(const void *vptr, size_t count)
  192. {
  193. const char *p = (const char *)vptr;
  194. while (count--)
  195. if (*p++)
  196. return 1;
  197. return 0;
  198. }
  199. /****************************************************************************/
  200. /* Mocked verification functions */
  201. VbError_t VbExDiskGetInfo(VbDiskInfo **infos_ptr, uint32_t *count,
  202. uint32_t disk_flags)
  203. {
  204. int i;
  205. int num_disks = 0;
  206. VB2_DEBUG("My %s\n", __FUNCTION__);
  207. *infos_ptr = mock_disks;
  208. for(i = 0; i < MAX_TEST_DISKS; i++) {
  209. if (is_nonzero(&t->disks_to_provide[i],
  210. sizeof(t->disks_to_provide[i]))) {
  211. mock_disks[num_disks].bytes_per_lba =
  212. t->disks_to_provide[i].bytes_per_lba;
  213. mock_disks[num_disks].lba_count =
  214. mock_disks[num_disks].streaming_lba_count =
  215. t->disks_to_provide[i].lba_count;
  216. mock_disks[num_disks].flags =
  217. t->disks_to_provide[i].flags;
  218. mock_disks[num_disks].handle = (VbExDiskHandle_t)
  219. t->disks_to_provide[i].diskname;
  220. VB2_DEBUG(" mock_disk[%d] %" PRIu64 " %" PRIu64
  221. " 0x%x %s\n", i,
  222. mock_disks[num_disks].bytes_per_lba,
  223. mock_disks[num_disks].lba_count,
  224. mock_disks[num_disks].flags,
  225. (mock_disks[num_disks].handle
  226. ? (char *)mock_disks[num_disks].handle
  227. : "0"));
  228. num_disks++;
  229. } else {
  230. mock_disks[num_disks].handle =
  231. (VbExDiskHandle_t)"INVALID";
  232. }
  233. }
  234. if (t->disk_count_to_return >= 0)
  235. *count = t->disk_count_to_return;
  236. else
  237. *count = num_disks;
  238. VB2_DEBUG(" *count=%" PRIu32 "\n", *count);
  239. VB2_DEBUG(" return 0x%x\n", t->diskgetinfo_return_val);
  240. return t->diskgetinfo_return_val;
  241. }
  242. VbError_t VbExDiskFreeInfo(VbDiskInfo *infos,
  243. VbExDiskHandle_t preserve_handle)
  244. {
  245. got_load_disk = (const char *)preserve_handle;
  246. VB2_DEBUG("%s(): got_load_disk = %s\n", __FUNCTION__,
  247. got_load_disk ? got_load_disk : "0");
  248. return VBERROR_SUCCESS;
  249. }
  250. VbError_t LoadKernel(struct vb2_context *ctx, LoadKernelParams *params,
  251. VbCommonParams *cparams)
  252. {
  253. got_find_disk = (const char *)params->disk_handle;
  254. VB2_DEBUG("%s(%d): got_find_disk = %s\n", __FUNCTION__,
  255. load_kernel_calls,
  256. got_find_disk ? got_find_disk : "0");
  257. if (t->external_expected[load_kernel_calls] !=
  258. !!(params->boot_flags & BOOT_FLAG_EXTERNAL_GPT))
  259. got_external_mismatch++;
  260. return t->loadkernel_return_val[load_kernel_calls++];
  261. }
  262. void vb2_nv_set(struct vb2_context *ctx,
  263. enum vb2_nv_param param,
  264. uint32_t value)
  265. {
  266. VB2_DEBUG("%s(): got_recovery_request_val = %d (0x%x)\n", __FUNCTION__,
  267. value, value);
  268. got_recovery_request_val = value;
  269. }
  270. /****************************************************************************/
  271. static void VbTryLoadKernelTest(void)
  272. {
  273. int i;
  274. int num_tests = sizeof(test) / sizeof(test[0]);
  275. for (i = 0; i < num_tests; i++) {
  276. printf("Test case: %s ...\n", test[i].name);
  277. ResetMocks(i);
  278. TEST_EQ(VbTryLoadKernel(&ctx, 0, test[i].want_flags),
  279. t->expected_return_val, " return value");
  280. TEST_EQ(got_recovery_request_val,
  281. t->expected_recovery_request_val, " recovery_request");
  282. if (t->expected_to_find_disk != DONT_CARE) {
  283. TEST_PTR_EQ(got_find_disk, t->expected_to_find_disk,
  284. " find disk");
  285. TEST_PTR_EQ(got_load_disk, t->expected_to_load_disk,
  286. " load disk");
  287. }
  288. TEST_EQ(got_external_mismatch, 0, " external GPT errors");
  289. }
  290. }
  291. int main(void)
  292. {
  293. VbTryLoadKernelTest();
  294. return gTestSuccess ? 0 : 255;
  295. }