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