1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #if defined(HAS_GTEST)
18 #include <gtest/gtest.h>
19 #else
20 #include "gtest_stubs.h"
21 #endif
22
23 #include <string.h>
24
25 #include <nvram/core/nvram_manager.h>
26 #include <nvram/core/persistence.h>
27
28 #include "fake_storage.h"
29
30 namespace nvram {
31 namespace {
32
33 class NvramManagerTest : public testing::Test {
34 protected:
NvramManagerTest()35 NvramManagerTest() {
36 storage::Clear();
37 }
38
SetupHeader(uint32_t header_version,uint32_t index)39 static void SetupHeader(uint32_t header_version, uint32_t index) {
40 NvramHeader header;
41 header.version = header_version;
42 ASSERT_TRUE(header.allocated_indices.Resize(1));
43 header.allocated_indices[0] = index;
44 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreHeader(header));
45 }
46
ReadAndCompareSpaceData(NvramManager * nvram,uint32_t index,const void * expected_contents,size_t expected_size)47 static void ReadAndCompareSpaceData(NvramManager* nvram,
48 uint32_t index,
49 const void* expected_contents,
50 size_t expected_size) {
51 ReadSpaceRequest read_space_request;
52 read_space_request.index = index;
53 ReadSpaceResponse read_space_response;
54 EXPECT_EQ(NV_RESULT_SUCCESS,
55 nvram->ReadSpace(read_space_request, &read_space_response));
56 ASSERT_EQ(expected_size, read_space_response.buffer.size());
57 EXPECT_EQ(0, memcmp(read_space_response.buffer.data(), expected_contents,
58 expected_size));
59 }
60
GetControlsMask(const Vector<nvram_control_t> & controls)61 static uint32_t GetControlsMask(const Vector<nvram_control_t>& controls) {
62 uint32_t mask = 0;
63 for (nvram_control_t control : controls) {
64 mask |= (1 << control);
65 }
66 return mask;
67 }
68 };
69
TEST_F(NvramManagerTest,Init_FromScratch)70 TEST_F(NvramManagerTest, Init_FromScratch) {
71 NvramManager nvram;
72
73 GetSpaceInfoRequest get_space_info_request;
74 get_space_info_request.index = 1;
75 GetSpaceInfoResponse get_space_info_response;
76 EXPECT_EQ(
77 NV_RESULT_SPACE_DOES_NOT_EXIST,
78 nvram.GetSpaceInfo(get_space_info_request, &get_space_info_response));
79 }
80
TEST_F(NvramManagerTest,Init_TrailingStorageBytes)81 TEST_F(NvramManagerTest, Init_TrailingStorageBytes) {
82 // Set up a pre-existing space and add some trailing bytes.
83 NvramSpace space;
84 ASSERT_TRUE(space.contents.Resize(10));
85 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(1, space));
86 Blob space_blob;
87 ASSERT_EQ(storage::Status::kSuccess, storage::LoadSpace(1, &space_blob));
88 ASSERT_TRUE(space_blob.Resize(space_blob.size() + 10));
89 ASSERT_EQ(storage::Status::kSuccess, storage::StoreSpace(1, space_blob));
90
91 // Produce a matching header and append some trailing bytes.
92 NvramHeader header;
93 header.version = NvramHeader::kVersion;
94 ASSERT_TRUE(header.allocated_indices.Resize(1));
95 header.allocated_indices[0] = 1;
96 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreHeader(header));
97 Blob header_blob;
98 ASSERT_EQ(storage::Status::kSuccess, storage::LoadHeader(&header_blob));
99 ASSERT_TRUE(header_blob.Resize(header_blob.size() + 10));
100 ASSERT_EQ(storage::Status::kSuccess, storage::StoreHeader(header_blob));
101
102 // Initialize the |NvramManager| and check that the header and space blobs get
103 // loaded successfully.
104 NvramManager nvram;
105
106 GetInfoRequest get_info_request;
107 GetInfoResponse get_info_response;
108 EXPECT_EQ(NV_RESULT_SUCCESS,
109 nvram.GetInfo(get_info_request, &get_info_response));
110 ASSERT_EQ(1U, get_info_response.space_list.size());
111 EXPECT_EQ(1U, get_info_response.space_list[0]);
112
113 GetSpaceInfoRequest get_space_info_request;
114 get_space_info_request.index = 1;
115 GetSpaceInfoResponse get_space_info_response;
116 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
117 &get_space_info_response));
118 EXPECT_EQ(10U, get_space_info_response.size);
119 }
120
TEST_F(NvramManagerTest,Init_SpacesPresent)121 TEST_F(NvramManagerTest, Init_SpacesPresent) {
122 // Set up two pre-existing spaces.
123 NvramSpace space;
124 ASSERT_TRUE(space.contents.Resize(10));
125 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(1, space));
126 ASSERT_TRUE(space.contents.Resize(20));
127 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(2, space));
128
129 // Indicate 3 present spaces in the header, including one that doesn't have
130 // space data in storage.
131 NvramHeader header;
132 header.version = NvramHeader::kVersion;
133 ASSERT_TRUE(header.allocated_indices.Resize(3));
134 header.allocated_indices[0] = 1;
135 header.allocated_indices[1] = 2;
136 header.allocated_indices[2] = 3;
137 header.provisional_index.Activate() = 4;
138 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreHeader(header));
139
140 NvramManager nvram;
141
142 // Check that the spaces are correctly recovered.
143 GetSpaceInfoRequest get_space_info_request;
144 get_space_info_request.index = 1;
145 GetSpaceInfoResponse get_space_info_response;
146 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
147 &get_space_info_response));
148 EXPECT_EQ(10u, get_space_info_response.size);
149
150 get_space_info_request.index = 2;
151 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
152 &get_space_info_response));
153 EXPECT_EQ(20u, get_space_info_response.size);
154
155 get_space_info_request.index = 3;
156 EXPECT_EQ(
157 NV_RESULT_INTERNAL_ERROR,
158 nvram.GetSpaceInfo(get_space_info_request, &get_space_info_response));
159
160 get_space_info_request.index = 4;
161 EXPECT_EQ(
162 NV_RESULT_SPACE_DOES_NOT_EXIST,
163 nvram.GetSpaceInfo(get_space_info_request, &get_space_info_response));
164 }
165
TEST_F(NvramManagerTest,Init_BadSpacePresent)166 TEST_F(NvramManagerTest, Init_BadSpacePresent) {
167 // Set up a good and a bad NVRAM space.
168 NvramSpace space;
169 ASSERT_TRUE(space.contents.Resize(10));
170 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(1, space));
171 const uint8_t kBadSpaceData[] = {0xba, 0xad};
172 Blob bad_space_blob;
173 ASSERT_TRUE(bad_space_blob.Assign(kBadSpaceData, sizeof(kBadSpaceData)));
174 ASSERT_EQ(storage::Status::kSuccess,
175 storage::StoreSpace(2, bad_space_blob));
176
177 NvramHeader header;
178 header.version = NvramHeader::kVersion;
179 ASSERT_TRUE(header.allocated_indices.Resize(2));
180 header.allocated_indices[0] = 1;
181 header.allocated_indices[1] = 2;
182 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreHeader(header));
183
184 NvramManager nvram;
185
186 // The bad index will fail requests.
187 GetSpaceInfoRequest get_space_info_request;
188 get_space_info_request.index = 2;
189 GetSpaceInfoResponse get_space_info_response;
190 nvram_result_t result =
191 nvram.GetSpaceInfo(get_space_info_request, &get_space_info_response);
192 EXPECT_NE(NV_RESULT_SUCCESS, result);
193 EXPECT_NE(NV_RESULT_SPACE_DOES_NOT_EXIST, result);
194
195 // A request to get info for the good index should succeed.
196 get_space_info_request.index = 1;
197 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
198 &get_space_info_response));
199 EXPECT_EQ(10u, get_space_info_response.size);
200 }
201
TEST_F(NvramManagerTest,Init_NewerStorageVersion)202 TEST_F(NvramManagerTest, Init_NewerStorageVersion) {
203 // Set up an NVRAM space.
204 NvramSpace space;
205 ASSERT_TRUE(space.contents.Resize(10));
206 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(1, space));
207
208 SetupHeader(NvramHeader::kVersion + 1, 1);
209
210 NvramManager nvram;
211
212 // Requests should fail due to version mismatch.
213 GetSpaceInfoRequest get_space_info_request;
214 get_space_info_request.index = 1;
215 GetSpaceInfoResponse get_space_info_response;
216 EXPECT_EQ(
217 NV_RESULT_INTERNAL_ERROR,
218 nvram.GetSpaceInfo(get_space_info_request, &get_space_info_response));
219 }
220
TEST_F(NvramManagerTest,Init_StorageObjectTypeMismatch)221 TEST_F(NvramManagerTest, Init_StorageObjectTypeMismatch) {
222 // Set up an NVRAM space.
223 NvramSpace space;
224 ASSERT_TRUE(space.contents.Resize(10));
225 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(1, space));
226
227 // Copy the space blob to the header storage.
228 Blob space_blob;
229 ASSERT_EQ(storage::Status::kSuccess, storage::LoadSpace(1, &space_blob));
230 ASSERT_EQ(storage::Status::kSuccess, storage::StoreHeader(space_blob));
231
232 NvramManager nvram;
233
234 // Initialization should detect that the header storage object doesn't look
235 // like a header, so initialization should fail.
236 GetInfoRequest get_info_request;
237 GetInfoResponse get_info_response;
238 EXPECT_EQ(NV_RESULT_INTERNAL_ERROR,
239 nvram.GetInfo(get_info_request, &get_info_response));
240 }
241
TEST_F(NvramManagerTest,CreateSpace_Success)242 TEST_F(NvramManagerTest, CreateSpace_Success) {
243 NvramManager nvram;
244
245 // Make a call to CreateSpace, which should succeed.
246 CreateSpaceRequest create_space_request;
247 create_space_request.index = 1;
248 create_space_request.size = 32;
249 ASSERT_TRUE(create_space_request.controls.Resize(5));
250 create_space_request.controls[0] = NV_CONTROL_BOOT_WRITE_LOCK;
251 create_space_request.controls[1] = NV_CONTROL_BOOT_READ_LOCK;
252 create_space_request.controls[2] = NV_CONTROL_WRITE_AUTHORIZATION;
253 create_space_request.controls[3] = NV_CONTROL_READ_AUTHORIZATION;
254 create_space_request.controls[4] = NV_CONTROL_WRITE_EXTEND;
255
256 CreateSpaceResponse create_space_response;
257 EXPECT_EQ(NV_RESULT_SUCCESS,
258 nvram.CreateSpace(create_space_request, &create_space_response));
259
260 // GetSpaceInfo should reflect the space parameters set during creation.
261 GetSpaceInfoRequest get_space_info_request;
262 get_space_info_request.index = 1;
263 GetSpaceInfoResponse get_space_info_response;
264 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
265 &get_space_info_response));
266
267 EXPECT_EQ(32u, get_space_info_response.size);
268 EXPECT_EQ(GetControlsMask(create_space_request.controls),
269 GetControlsMask(get_space_info_response.controls));
270 EXPECT_EQ(false, get_space_info_response.read_locked);
271 EXPECT_EQ(false, get_space_info_response.write_locked);
272 }
273
TEST_F(NvramManagerTest,CreateSpace_Existing)274 TEST_F(NvramManagerTest, CreateSpace_Existing) {
275 // Set up an NVRAM space.
276 NvramSpace space;
277 ASSERT_TRUE(space.contents.Resize(10));
278 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(1, space));
279
280 SetupHeader(NvramHeader::kVersion, 1);
281
282 NvramManager nvram;
283
284 // A request to create another space with the same index should fail.
285 CreateSpaceRequest create_space_request;
286 create_space_request.index = 1;
287 create_space_request.size = 16;
288
289 CreateSpaceResponse create_space_response;
290 EXPECT_EQ(NV_RESULT_SPACE_ALREADY_EXISTS,
291 nvram.CreateSpace(create_space_request, &create_space_response));
292 }
293
TEST_F(NvramManagerTest,CreateSpace_TooLarge)294 TEST_F(NvramManagerTest, CreateSpace_TooLarge) {
295 NvramManager nvram;
296
297 // A request to create a space with a too large content size should fail.
298 CreateSpaceRequest create_space_request;
299 create_space_request.index = 1;
300 create_space_request.size = 16384;
301
302 CreateSpaceResponse create_space_response;
303 EXPECT_EQ(NV_RESULT_INVALID_PARAMETER,
304 nvram.CreateSpace(create_space_request, &create_space_response));
305 }
306
TEST_F(NvramManagerTest,CreateSpace_AuthTooLarge)307 TEST_F(NvramManagerTest, CreateSpace_AuthTooLarge) {
308 NvramManager nvram;
309
310 // A request to create a space with a too large authorization value size
311 // should fail.
312 CreateSpaceRequest create_space_request;
313 create_space_request.index = 1;
314 ASSERT_TRUE(create_space_request.authorization_value.Resize(256));
315
316 CreateSpaceResponse create_space_response;
317 EXPECT_EQ(NV_RESULT_INVALID_PARAMETER,
318 nvram.CreateSpace(create_space_request, &create_space_response));
319 }
320
TEST_F(NvramManagerTest,CreateSpace_BadControl)321 TEST_F(NvramManagerTest, CreateSpace_BadControl) {
322 NvramManager nvram;
323
324 // A request to create a space with an unknown control value should fail.
325 CreateSpaceRequest create_space_request;
326 create_space_request.index = 1;
327 create_space_request.size = 16;
328 ASSERT_TRUE(create_space_request.controls.Resize(2));
329 create_space_request.controls[0] = NV_CONTROL_BOOT_WRITE_LOCK;
330 create_space_request.controls[1] = 17;
331
332 CreateSpaceResponse create_space_response;
333 EXPECT_EQ(NV_RESULT_INVALID_PARAMETER,
334 nvram.CreateSpace(create_space_request, &create_space_response));
335 }
336
TEST_F(NvramManagerTest,CreateSpace_ControlWriteLockExclusive)337 TEST_F(NvramManagerTest, CreateSpace_ControlWriteLockExclusive) {
338 NvramManager nvram;
339
340 // Spaces may not be created with conflicting write lock modes.
341 CreateSpaceRequest create_space_request;
342 create_space_request.index = 1;
343 create_space_request.size = 16;
344 ASSERT_TRUE(create_space_request.controls.Resize(2));
345 create_space_request.controls[0] = NV_CONTROL_BOOT_WRITE_LOCK;
346 create_space_request.controls[1] = NV_CONTROL_PERSISTENT_WRITE_LOCK;
347
348 CreateSpaceResponse create_space_response;
349 EXPECT_EQ(NV_RESULT_INVALID_PARAMETER,
350 nvram.CreateSpace(create_space_request, &create_space_response));
351 }
352
TEST_F(NvramManagerTest,CreateSpace_WriteExtendSpaceSize)353 TEST_F(NvramManagerTest, CreateSpace_WriteExtendSpaceSize) {
354 NvramManager nvram;
355
356 // Write-extend spaces must match SHA256 hash size, i.e. 32 bytes.
357 CreateSpaceRequest create_space_request;
358 create_space_request.index = 1;
359 create_space_request.size = 16;
360 ASSERT_TRUE(create_space_request.controls.Resize(1));
361 create_space_request.controls[0] = NV_CONTROL_WRITE_EXTEND;
362
363 CreateSpaceResponse create_space_response;
364 EXPECT_EQ(NV_RESULT_INVALID_PARAMETER,
365 nvram.CreateSpace(create_space_request, &create_space_response));
366 }
367
TEST_F(NvramManagerTest,CreateSpace_HeaderWriteError)368 TEST_F(NvramManagerTest, CreateSpace_HeaderWriteError) {
369 // If the header fails to get written to storage, the creation request should
370 // fail.
371 storage::SetHeaderWriteError(true);
372
373 NvramManager nvram;
374
375 CreateSpaceRequest create_space_request;
376 create_space_request.index = 1;
377 create_space_request.size = 16;
378
379 CreateSpaceResponse create_space_response;
380 EXPECT_EQ(NV_RESULT_INTERNAL_ERROR,
381 nvram.CreateSpace(create_space_request, &create_space_response));
382
383 // The space shouldn't be present.
384 GetInfoRequest get_info_request;
385 GetInfoResponse get_info_response;
386 EXPECT_EQ(NV_RESULT_SUCCESS,
387 nvram.GetInfo(get_info_request, &get_info_response));
388 EXPECT_EQ(0U, get_info_response.space_list.size());
389
390 // Creation of the space after clearing the error should work.
391 storage::SetHeaderWriteError(false);
392 EXPECT_EQ(NV_RESULT_SUCCESS,
393 nvram.CreateSpace(create_space_request, &create_space_response));
394
395 // The space should be reported as allocated now.
396 EXPECT_EQ(NV_RESULT_SUCCESS,
397 nvram.GetInfo(get_info_request, &get_info_response));
398 ASSERT_EQ(1U, get_info_response.space_list.size());
399 EXPECT_EQ(1U, get_info_response.space_list[0]);
400 }
401
TEST_F(NvramManagerTest,CreateSpace_SpaceWriteError)402 TEST_F(NvramManagerTest, CreateSpace_SpaceWriteError) {
403 storage::SetSpaceWriteError(1, true);
404 NvramManager nvram;
405
406 // A request to create another space with the same index should fail.
407 CreateSpaceRequest create_space_request;
408 create_space_request.index = 1;
409 create_space_request.size = 16;
410
411 CreateSpaceResponse create_space_response;
412 EXPECT_EQ(NV_RESULT_INTERNAL_ERROR,
413 nvram.CreateSpace(create_space_request, &create_space_response));
414
415 // Reloading the state after a crash should not show any traces of the space.
416 storage::SetSpaceWriteError(1, false);
417 NvramManager nvram2;
418
419 // The space shouldn't exist in the space list.
420 GetInfoRequest get_info_request;
421 GetInfoResponse get_info_response;
422 EXPECT_EQ(NV_RESULT_SUCCESS,
423 nvram2.GetInfo(get_info_request, &get_info_response));
424
425 EXPECT_EQ(0U, get_info_response.space_list.size());
426
427 // The space info request should indicate the space doesn't exist.
428 GetSpaceInfoRequest get_space_info_request;
429 get_space_info_request.index = 1;
430 GetSpaceInfoResponse get_space_info_response;
431 EXPECT_EQ(
432 NV_RESULT_SPACE_DOES_NOT_EXIST,
433 nvram2.GetSpaceInfo(get_space_info_request, &get_space_info_response));
434 }
435
TEST_F(NvramManagerTest,DeleteSpace_SpaceAbsent)436 TEST_F(NvramManagerTest, DeleteSpace_SpaceAbsent) {
437 NvramManager nvram;
438
439 // Attempt to delete a non-existing space.
440 DeleteSpaceRequest delete_space_request;
441 delete_space_request.index = 42;
442 DeleteSpaceResponse delete_space_response;
443 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
444 nvram.DeleteSpace(delete_space_request, &delete_space_response));
445 }
446
TEST_F(NvramManagerTest,DeleteSpace_Success)447 TEST_F(NvramManagerTest, DeleteSpace_Success) {
448 // Set up an NVRAM space.
449 NvramSpace space;
450 ASSERT_TRUE(space.contents.Resize(10));
451 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(42, space));
452 SetupHeader(NvramHeader::kVersion, 42);
453
454 NvramManager nvram;
455
456 // Successful deletion.
457 DeleteSpaceRequest delete_space_request;
458 delete_space_request.index = 42;
459 DeleteSpaceResponse delete_space_response;
460 EXPECT_EQ(NV_RESULT_SUCCESS,
461 nvram.DeleteSpace(delete_space_request, &delete_space_response));
462 }
463
TEST_F(NvramManagerTest,DeleteSpace_AuthorizationFailure)464 TEST_F(NvramManagerTest, DeleteSpace_AuthorizationFailure) {
465 // Set up an NVRAM space.
466 NvramSpace space;
467 space.controls = (1 << NV_CONTROL_WRITE_AUTHORIZATION);
468 const char kAuthorizationValue[] = "secret";
469 ASSERT_TRUE(space.authorization_value.Assign(kAuthorizationValue,
470 sizeof(kAuthorizationValue)));
471 ASSERT_TRUE(space.contents.Resize(10));
472 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(42, space));
473 SetupHeader(NvramHeader::kVersion, 42);
474
475 NvramManager nvram;
476
477 // Deletion should fail if correct secret is not provided.
478 DeleteSpaceRequest delete_space_request;
479 delete_space_request.index = 42;
480 DeleteSpaceResponse delete_space_response;
481 EXPECT_EQ(NV_RESULT_ACCESS_DENIED,
482 nvram.DeleteSpace(delete_space_request, &delete_space_response));
483 }
484
TEST_F(NvramManagerTest,DeleteSpace_HalfDeleted)485 TEST_F(NvramManagerTest, DeleteSpace_HalfDeleted) {
486 // Set up an NVRAM space.
487 NvramSpace space;
488 ASSERT_TRUE(space.contents.Resize(10));
489 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(42, space));
490 SetupHeader(NvramHeader::kVersion, 42);
491
492 // Hold on to the space data.
493 Blob space_data;
494 ASSERT_EQ(storage::Status::kSuccess, storage::LoadSpace(42, &space_data));
495
496 NvramManager nvram;
497
498 // Delete the space.
499 DeleteSpaceRequest delete_space_request;
500 delete_space_request.index = 42;
501 DeleteSpaceResponse delete_space_response;
502 EXPECT_EQ(NV_RESULT_SUCCESS,
503 nvram.DeleteSpace(delete_space_request, &delete_space_response));
504
505 // Put the space data back into place to simulate a half-completed deletion.
506 ASSERT_EQ(storage::Status::kSuccess, storage::StoreSpace(42, space_data));
507
508 // The space should remain deleted after re-initialization.
509 NvramManager nvram2;
510
511 GetSpaceInfoRequest get_space_info_request;
512 get_space_info_request.index = 42;
513 GetSpaceInfoResponse get_space_info_response;
514 EXPECT_EQ(
515 NV_RESULT_SPACE_DOES_NOT_EXIST,
516 nvram2.GetSpaceInfo(get_space_info_request, &get_space_info_response));
517
518 // Re-creation of a space with the same index should work.
519 CreateSpaceRequest create_space_request;
520 create_space_request.index = 42;
521 create_space_request.size = 32;
522 ASSERT_TRUE(create_space_request.controls.Resize(1));
523 create_space_request.controls[0] = NV_CONTROL_BOOT_WRITE_LOCK;
524 CreateSpaceResponse create_space_response;
525 EXPECT_EQ(NV_RESULT_SUCCESS,
526 nvram2.CreateSpace(create_space_request, &create_space_response));
527 }
528
TEST_F(NvramManagerTest,DeleteSpace_SpaceDeleteError)529 TEST_F(NvramManagerTest, DeleteSpace_SpaceDeleteError) {
530 // Set up an NVRAM space.
531 NvramSpace space;
532 ASSERT_TRUE(space.contents.Resize(10));
533 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(42, space));
534 SetupHeader(NvramHeader::kVersion, 42);
535
536 // Make space deletion fail.
537 storage::SetSpaceWriteError(42, true);
538
539 NvramManager nvram;
540
541 // Attempt to delete the space.
542 DeleteSpaceRequest delete_space_request;
543 delete_space_request.index = 42;
544 DeleteSpaceResponse delete_space_response;
545 EXPECT_EQ(NV_RESULT_INTERNAL_ERROR,
546 nvram.DeleteSpace(delete_space_request, &delete_space_response));
547
548 // The space should remain present.
549 GetSpaceInfoRequest get_space_info_request;
550 get_space_info_request.index = 42;
551 GetSpaceInfoResponse get_space_info_response;
552 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
553 &get_space_info_response));
554 EXPECT_EQ(10U, get_space_info_response.size);
555
556 // Starting up from scratch shouldn't destroy the space either.
557 storage::SetSpaceWriteError(42, false);
558
559 NvramManager nvram2;
560
561 GetSpaceInfoResponse get_space_info_response_2;
562 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
563 &get_space_info_response_2));
564 EXPECT_EQ(10U, get_space_info_response_2.size);
565 }
566
TEST_F(NvramManagerTest,DeleteSpace_HeaderWriteError)567 TEST_F(NvramManagerTest, DeleteSpace_HeaderWriteError) {
568 // Set up an NVRAM space.
569 NvramSpace space;
570 ASSERT_TRUE(space.contents.Resize(10));
571 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(42, space));
572 SetupHeader(NvramHeader::kVersion, 42);
573
574 // Header write on deletion will fail.
575 storage::SetHeaderWriteError(true);
576
577 NvramManager nvram;
578
579 // Attempt to delete the space.
580 DeleteSpaceRequest delete_space_request;
581 delete_space_request.index = 42;
582 DeleteSpaceResponse delete_space_response;
583 EXPECT_EQ(NV_RESULT_INTERNAL_ERROR,
584 nvram.DeleteSpace(delete_space_request, &delete_space_response));
585
586 // The space should remain present.
587 GetSpaceInfoRequest get_space_info_request;
588 get_space_info_request.index = 42;
589 GetSpaceInfoResponse get_space_info_response;
590 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
591 &get_space_info_response));
592 EXPECT_EQ(10U, get_space_info_response.size);
593
594 // Starting up from scratch shouldn't destroy the space either.
595 storage::SetSpaceWriteError(42, false);
596
597 NvramManager nvram2;
598
599 GetSpaceInfoResponse get_space_info_response_2;
600 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
601 &get_space_info_response_2));
602 EXPECT_EQ(10U, get_space_info_response_2.size);
603 }
604
TEST_F(NvramManagerTest,DisableCreate_Success)605 TEST_F(NvramManagerTest, DisableCreate_Success) {
606 NvramManager nvram;
607
608 // Issue a successful disable create request.
609 DisableCreateRequest disable_create_request;
610 DisableCreateResponse disable_create_response;
611 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.DisableCreate(disable_create_request,
612 &disable_create_response));
613
614 // Make sure space creation request fail afterwards.
615 CreateSpaceRequest create_space_request;
616 create_space_request.index = 1;
617 create_space_request.size = 32;
618 ASSERT_TRUE(create_space_request.controls.Resize(1));
619 create_space_request.controls[0] = NV_CONTROL_BOOT_WRITE_LOCK;
620 CreateSpaceResponse create_space_response;
621 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED,
622 nvram.CreateSpace(create_space_request, &create_space_response));
623
624 // Redundant requests to disable creation are OK.
625 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.DisableCreate(disable_create_request,
626 &disable_create_response));
627
628 // Space creation should remain disabled even after a reboot.
629 NvramManager nvram2;
630 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED,
631 nvram2.CreateSpace(create_space_request, &create_space_response));
632 }
633
TEST_F(NvramManagerTest,DisableCreate_WriteError)634 TEST_F(NvramManagerTest, DisableCreate_WriteError) {
635 // Make header writes fail.
636 storage::SetHeaderWriteError(true);
637
638 NvramManager nvram;
639
640 // The disable request should fail.
641 DisableCreateRequest disable_create_request;
642 DisableCreateResponse disable_create_response;
643 EXPECT_EQ(
644 NV_RESULT_INTERNAL_ERROR,
645 nvram.DisableCreate(disable_create_request, &disable_create_response));
646
647 // We should still be able to create spaces after clearing the error.
648 storage::SetHeaderWriteError(false);
649
650 CreateSpaceRequest create_space_request;
651 create_space_request.index = 1;
652 create_space_request.size = 32;
653 ASSERT_TRUE(create_space_request.controls.Resize(1));
654 create_space_request.controls[0] = NV_CONTROL_BOOT_WRITE_LOCK;
655 CreateSpaceResponse create_space_response;
656 EXPECT_EQ(NV_RESULT_SUCCESS,
657 nvram.CreateSpace(create_space_request, &create_space_response));
658 }
659
TEST_F(NvramManagerTest,WriteSpace_SpaceAbsent)660 TEST_F(NvramManagerTest, WriteSpace_SpaceAbsent) {
661 NvramManager nvram;
662
663 // Attempt to write a non-existing space.
664 WriteSpaceRequest write_space_request;
665 write_space_request.index = 17;
666 ASSERT_TRUE(write_space_request.buffer.Assign("0123456789", 10));
667 WriteSpaceResponse write_space_response;
668 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
669 nvram.WriteSpace(write_space_request, &write_space_response));
670 }
671
TEST_F(NvramManagerTest,WriteSpace_Success)672 TEST_F(NvramManagerTest, WriteSpace_Success) {
673 // Set up an NVRAM space.
674 NvramSpace space;
675 ASSERT_TRUE(space.contents.Resize(10));
676 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
677 SetupHeader(NvramHeader::kVersion, 17);
678
679 NvramManager nvram;
680
681 // Write the space.
682 WriteSpaceRequest write_space_request;
683 write_space_request.index = 17;
684 ASSERT_TRUE(write_space_request.buffer.Assign("0123456789", 10));
685 WriteSpaceResponse write_space_response;
686 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.WriteSpace(write_space_request,
687 &write_space_response));
688
689 // Read back the space and compare contents.
690 ReadAndCompareSpaceData(&nvram, 17, "0123456789", 10);
691
692 // The data should persist even after a reboot.
693 NvramManager nvram2;
694
695 ReadAndCompareSpaceData(&nvram2, 17, "0123456789", 10);
696 }
697
TEST_F(NvramManagerTest,WriteSpace_ExcessData)698 TEST_F(NvramManagerTest, WriteSpace_ExcessData) {
699 // Set up an NVRAM space.
700 NvramSpace space;
701 ASSERT_TRUE(space.contents.Resize(10));
702 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
703 SetupHeader(NvramHeader::kVersion, 17);
704
705 NvramManager nvram;
706
707 // Write the space.
708 WriteSpaceRequest write_space_request;
709 write_space_request.index = 17;
710 ASSERT_TRUE(write_space_request.buffer.Assign("0123456789abcdef", 16));
711 WriteSpaceResponse write_space_response;
712 EXPECT_EQ(NV_RESULT_INVALID_PARAMETER,
713 nvram.WriteSpace(write_space_request, &write_space_response));
714 }
715
TEST_F(NvramManagerTest,WriteSpace_ShortData)716 TEST_F(NvramManagerTest, WriteSpace_ShortData) {
717 // Set up an NVRAM space.
718 NvramSpace space;
719 ASSERT_TRUE(space.contents.Resize(10));
720 memset(space.contents.data(), 'X', space.contents.size());
721 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
722 SetupHeader(NvramHeader::kVersion, 17);
723
724 NvramManager nvram;
725
726 // Write the space.
727 WriteSpaceRequest write_space_request;
728 write_space_request.index = 17;
729 ASSERT_TRUE(write_space_request.buffer.Assign("01234", 5));
730 WriteSpaceResponse write_space_response;
731 EXPECT_EQ(NV_RESULT_SUCCESS,
732 nvram.WriteSpace(write_space_request, &write_space_response));
733
734 // Read back the space data and verify that the missing content bytes have
735 // been set to 0.
736 const uint8_t kExpectedContents[] = {'0', '1', '2', '3', '4', 0, 0, 0, 0, 0};
737 ReadAndCompareSpaceData(&nvram, 17, kExpectedContents, 10);
738 }
739
TEST_F(NvramManagerTest,WriteSpace_WriteExtend)740 TEST_F(NvramManagerTest, WriteSpace_WriteExtend) {
741 // Set up an NVRAM space.
742 NvramSpace space;
743 space.controls = (1 << NV_CONTROL_WRITE_EXTEND);
744 ASSERT_TRUE(space.contents.Resize(32));
745 memset(space.contents.data(), 0, space.contents.size());
746 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
747 SetupHeader(NvramHeader::kVersion, 17);
748
749 NvramManager nvram;
750
751 // Write the space.
752 WriteSpaceRequest write_space_request;
753 write_space_request.index = 17;
754 ASSERT_TRUE(write_space_request.buffer.Assign("data", 4));
755 WriteSpaceResponse write_space_response;
756 EXPECT_EQ(NV_RESULT_SUCCESS,
757 nvram.WriteSpace(write_space_request, &write_space_response));
758
759 // Read back the space data and verify the hash.
760 const uint8_t kExpectedContents[] = {
761 0xee, 0x84, 0x52, 0x88, 0xbb, 0x60, 0x7e, 0x02, 0xfd, 0xfb, 0x31,
762 0x95, 0x3a, 0x77, 0x23, 0xcf, 0x67, 0xea, 0x6e, 0x2d, 0xd7, 0xdb,
763 0x8c, 0xb4, 0xe4, 0xd2, 0xfd, 0xb4, 0x76, 0x7a, 0x67, 0x89,
764 };
765 ReadAndCompareSpaceData(&nvram, 17, kExpectedContents, 32);
766 }
767
TEST_F(NvramManagerTest,WriteSpace_WriteExtendShortSpace)768 TEST_F(NvramManagerTest, WriteSpace_WriteExtendShortSpace) {
769 // Set up an NVRAM space.
770 NvramSpace space;
771 space.controls = (1 << NV_CONTROL_WRITE_EXTEND);
772 ASSERT_TRUE(space.contents.Resize(16));
773 memset(space.contents.data(), 0, space.contents.size());
774 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
775 SetupHeader(NvramHeader::kVersion, 17);
776
777 NvramManager nvram;
778
779 // Write the space.
780 WriteSpaceRequest write_space_request;
781 write_space_request.index = 17;
782 ASSERT_TRUE(write_space_request.buffer.Assign("data", 4));
783 WriteSpaceResponse write_space_response;
784 EXPECT_EQ(NV_RESULT_SUCCESS,
785 nvram.WriteSpace(write_space_request, &write_space_response));
786
787 // Read back the space data and verify the truncated hash.
788 const uint8_t kExpectedContents[] = {
789 0x24, 0x2a, 0xbb, 0x36, 0x10, 0x37, 0x92, 0x3f,
790 0x7d, 0x7d, 0x92, 0x3a, 0x16, 0x65, 0xd2, 0xa2,
791 };
792 ReadAndCompareSpaceData(&nvram, 17, kExpectedContents, 16);
793 }
794
TEST_F(NvramManagerTest,WriteSpace_WriteExtendLongSpace)795 TEST_F(NvramManagerTest, WriteSpace_WriteExtendLongSpace) {
796 // Set up an NVRAM space.
797 NvramSpace space;
798 space.controls = (1 << NV_CONTROL_WRITE_EXTEND);
799 ASSERT_TRUE(space.contents.Resize(33));
800 memset(space.contents.data(), 'X', space.contents.size());
801 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
802 SetupHeader(NvramHeader::kVersion, 17);
803
804 NvramManager nvram;
805
806 // Write the space.
807 WriteSpaceRequest write_space_request;
808 write_space_request.index = 17;
809 ASSERT_TRUE(write_space_request.buffer.Assign("data", 4));
810 WriteSpaceResponse write_space_response;
811 EXPECT_EQ(NV_RESULT_SUCCESS,
812 nvram.WriteSpace(write_space_request, &write_space_response));
813
814 // Read back the space data and verify the hash and trailing 0 bytes.
815 const uint8_t kExpectedContents[] = {
816 0x99, 0xb8, 0x5f, 0xd0, 0xf7, 0x9b, 0x17, 0x2e, 0x0e, 0x58, 0x3d,
817 0x3c, 0x9a, 0x29, 0xa3, 0xaf, 0x0a, 0x4c, 0x68, 0x97, 0x72, 0x8c,
818 0x0c, 0xa4, 0x37, 0xad, 0x39, 0xf3, 0x8c, 0x6e, 0x64, 0xd7, 0x00,
819 };
820 ReadAndCompareSpaceData(&nvram, 17, kExpectedContents, 33);
821 }
822
TEST_F(NvramManagerTest,WriteSpace_AuthorizationFailure)823 TEST_F(NvramManagerTest, WriteSpace_AuthorizationFailure) {
824 // Set up an NVRAM space.
825 NvramSpace space;
826 space.controls = (1 << NV_CONTROL_WRITE_AUTHORIZATION);
827 ASSERT_TRUE(space.contents.Resize(10));
828 const char kAuthorizationValue[] = "secret";
829 ASSERT_TRUE(space.authorization_value.Assign(kAuthorizationValue,
830 sizeof(kAuthorizationValue)));
831 ASSERT_TRUE(space.contents.Assign("0123456789", 10));
832 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
833 SetupHeader(NvramHeader::kVersion, 17);
834
835 NvramManager nvram;
836
837 // Attempt a write with the wrong authorization value.
838 WriteSpaceRequest write_space_request;
839 write_space_request.index = 17;
840 ASSERT_TRUE(write_space_request.buffer.Assign("data", 4));
841 WriteSpaceResponse write_space_response;
842 EXPECT_EQ(NV_RESULT_ACCESS_DENIED,
843 nvram.WriteSpace(write_space_request, &write_space_response));
844
845 // The previous data should remain effective.
846 ReadAndCompareSpaceData(&nvram, 17, "0123456789", 10);
847 }
848
TEST_F(NvramManagerTest,WriteSpace_WriteError)849 TEST_F(NvramManagerTest, WriteSpace_WriteError) {
850 // Set up an NVRAM space.
851 NvramSpace space;
852 ASSERT_TRUE(space.contents.Assign("0123456789", 10));
853 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
854 SetupHeader(NvramHeader::kVersion, 17);
855
856 NvramManager nvram;
857
858 storage::SetSpaceWriteError(17, true);
859
860 // Attempt a write, which should fail.
861 WriteSpaceRequest write_space_request;
862 write_space_request.index = 17;
863 ASSERT_TRUE(write_space_request.buffer.Assign("data", 4));
864 WriteSpaceResponse write_space_response;
865 EXPECT_EQ(NV_RESULT_INTERNAL_ERROR,
866 nvram.WriteSpace(write_space_request, &write_space_response));
867
868 // The previous data should remain effective.
869 ReadAndCompareSpaceData(&nvram, 17, "0123456789", 10);
870 }
871
TEST_F(NvramManagerTest,ReadSpace_SpaceAbsent)872 TEST_F(NvramManagerTest, ReadSpace_SpaceAbsent) {
873 NvramManager nvram;
874
875 // Attempt a read from a space that doesn't exist.
876 ReadSpaceRequest read_space_request;
877 read_space_request.index = 17;
878 ReadSpaceResponse read_space_response;
879 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
880 nvram.ReadSpace(read_space_request, &read_space_response));
881 }
882
TEST_F(NvramManagerTest,ReadSpace_AuthorizationFailure)883 TEST_F(NvramManagerTest, ReadSpace_AuthorizationFailure) {
884 // Set up an NVRAM space.
885 NvramSpace space;
886 space.controls = (1 << NV_CONTROL_READ_AUTHORIZATION);
887 ASSERT_TRUE(space.contents.Resize(10));
888 const char kAuthorizationValue[] = "secret";
889 ASSERT_TRUE(space.authorization_value.Assign(kAuthorizationValue,
890 sizeof(kAuthorizationValue)));
891 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
892 SetupHeader(NvramHeader::kVersion, 17);
893
894 NvramManager nvram;
895
896 // Attempt a read from the space.
897 ReadSpaceRequest read_space_request;
898 read_space_request.index = 17;
899 ReadSpaceResponse read_space_response;
900 EXPECT_EQ(NV_RESULT_ACCESS_DENIED,
901 nvram.ReadSpace(read_space_request, &read_space_response));
902 EXPECT_EQ(0U, read_space_response.buffer.size());
903 }
904
TEST_F(NvramManagerTest,LockSpaceWrite_SpaceAbsent)905 TEST_F(NvramManagerTest, LockSpaceWrite_SpaceAbsent) {
906 NvramManager nvram;
907
908 // Attempt to lock a space that doesn't exist.
909 LockSpaceWriteRequest lock_space_write_request;
910 lock_space_write_request.index = 17;
911 LockSpaceWriteResponse lock_space_write_response;
912 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
913 nvram.LockSpaceWrite(lock_space_write_request,
914 &lock_space_write_response));
915 }
916
TEST_F(NvramManagerTest,LockSpaceWrite_AuthorizationFailure)917 TEST_F(NvramManagerTest, LockSpaceWrite_AuthorizationFailure) {
918 // Set up an NVRAM space.
919 NvramSpace space;
920 space.controls = (1 << NV_CONTROL_PERSISTENT_WRITE_LOCK) |
921 (1 << NV_CONTROL_WRITE_AUTHORIZATION);
922 ASSERT_TRUE(space.contents.Resize(10));
923 const char kAuthorizationValue[] = "secret";
924 ASSERT_TRUE(space.authorization_value.Assign(kAuthorizationValue,
925 sizeof(kAuthorizationValue)));
926 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
927 SetupHeader(NvramHeader::kVersion, 17);
928
929 NvramManager nvram;
930
931 // Attempt to lock a space without valid authentication.
932 LockSpaceWriteRequest lock_space_write_request;
933 lock_space_write_request.index = 17;
934 LockSpaceWriteResponse lock_space_write_response;
935 EXPECT_EQ(NV_RESULT_ACCESS_DENIED,
936 nvram.LockSpaceWrite(lock_space_write_request,
937 &lock_space_write_response));
938 }
939
TEST_F(NvramManagerTest,LockSpaceWrite_SuccessPersistent)940 TEST_F(NvramManagerTest, LockSpaceWrite_SuccessPersistent) {
941 // Set up an NVRAM space.
942 NvramSpace space;
943 space.controls = (1 << NV_CONTROL_PERSISTENT_WRITE_LOCK);
944 ASSERT_TRUE(space.contents.Resize(10));
945 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
946 SetupHeader(NvramHeader::kVersion, 17);
947
948 NvramManager nvram;
949
950 // Lock the space.
951 LockSpaceWriteRequest lock_space_write_request;
952 lock_space_write_request.index = 17;
953 LockSpaceWriteResponse lock_space_write_response;
954 EXPECT_EQ(NV_RESULT_SUCCESS,
955 nvram.LockSpaceWrite(lock_space_write_request,
956 &lock_space_write_response));
957
958 // Writing should fail now.
959 WriteSpaceRequest write_space_request;
960 write_space_request.index = 17;
961 ASSERT_TRUE(write_space_request.buffer.Assign("data", 4));
962 WriteSpaceResponse write_space_response;
963 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED,
964 nvram.WriteSpace(write_space_request, &write_space_response));
965
966 // The lock should be persistent, so writing should fail after reboot.
967 NvramManager nvram2;
968
969 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED,
970 nvram2.WriteSpace(write_space_request, &write_space_response));
971 }
972
TEST_F(NvramManagerTest,LockSpaceWrite_SuccessBoot)973 TEST_F(NvramManagerTest, LockSpaceWrite_SuccessBoot) {
974 // Set up an NVRAM space.
975 NvramSpace space;
976 space.controls = (1 << NV_CONTROL_BOOT_WRITE_LOCK);
977 ASSERT_TRUE(space.contents.Assign("01234567890", 10));
978 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
979 SetupHeader(NvramHeader::kVersion, 17);
980
981 NvramManager nvram;
982
983 // Lock the space.
984 LockSpaceWriteRequest lock_space_write_request;
985 lock_space_write_request.index = 17;
986 LockSpaceWriteResponse lock_space_write_response;
987 EXPECT_EQ(NV_RESULT_SUCCESS,
988 nvram.LockSpaceWrite(lock_space_write_request,
989 &lock_space_write_response));
990
991 // Writing should fail now.
992 WriteSpaceRequest write_space_request;
993 write_space_request.index = 17;
994 ASSERT_TRUE(write_space_request.buffer.Assign("newcontent", 10));
995 WriteSpaceResponse write_space_response;
996 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED,
997 nvram.WriteSpace(write_space_request, &write_space_response));
998
999 // We configured a per-boot lock, so writing should succeed after reboot.
1000 NvramManager nvram2;
1001
1002 EXPECT_EQ(NV_RESULT_SUCCESS,
1003 nvram2.WriteSpace(write_space_request, &write_space_response));
1004 ReadAndCompareSpaceData(&nvram2, 17, "newcontent", 10);
1005 }
1006
TEST_F(NvramManagerTest,LockSpaceWrite_NotLockable)1007 TEST_F(NvramManagerTest, LockSpaceWrite_NotLockable) {
1008 // Set up an NVRAM space.
1009 NvramSpace space;
1010 ASSERT_TRUE(space.contents.Resize(10));
1011 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
1012 SetupHeader(NvramHeader::kVersion, 17);
1013
1014 NvramManager nvram;
1015
1016 // Attempt to lock a space without valid authentication.
1017 LockSpaceWriteRequest lock_space_write_request;
1018 lock_space_write_request.index = 17;
1019 LockSpaceWriteResponse lock_space_write_response;
1020 EXPECT_EQ(NV_RESULT_INVALID_PARAMETER,
1021 nvram.LockSpaceWrite(lock_space_write_request,
1022 &lock_space_write_response));
1023 }
1024
TEST_F(NvramManagerTest,LockSpaceRead_SpaceAbsent)1025 TEST_F(NvramManagerTest, LockSpaceRead_SpaceAbsent) {
1026 NvramManager nvram;
1027
1028 // Attempt to lock a non-existing space.
1029 LockSpaceReadRequest lock_space_read_request;
1030 lock_space_read_request.index = 17;
1031 LockSpaceReadResponse lock_space_read_response;
1032 EXPECT_EQ(
1033 NV_RESULT_SPACE_DOES_NOT_EXIST,
1034 nvram.LockSpaceRead(lock_space_read_request, &lock_space_read_response));
1035 }
1036
TEST_F(NvramManagerTest,LockSpaceRead_AuthorizationFailure)1037 TEST_F(NvramManagerTest, LockSpaceRead_AuthorizationFailure) {
1038 // Set up an NVRAM space.
1039 NvramSpace space;
1040 space.controls =
1041 (1 << NV_CONTROL_BOOT_READ_LOCK) | (1 << NV_CONTROL_READ_AUTHORIZATION);
1042 ASSERT_TRUE(space.contents.Resize(10));
1043 const char kAuthorizationValue[] = "secret";
1044 ASSERT_TRUE(space.authorization_value.Assign(kAuthorizationValue,
1045 sizeof(kAuthorizationValue)));
1046 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
1047 SetupHeader(NvramHeader::kVersion, 17);
1048
1049 NvramManager nvram;
1050
1051 // Attempt to lock a space without valid authorization.
1052 LockSpaceReadRequest lock_space_read_request;
1053 lock_space_read_request.index = 17;
1054 LockSpaceReadResponse lock_space_read_response;
1055 EXPECT_EQ(
1056 NV_RESULT_ACCESS_DENIED,
1057 nvram.LockSpaceRead(lock_space_read_request, &lock_space_read_response));
1058 }
1059
TEST_F(NvramManagerTest,LockSpaceRead_Success)1060 TEST_F(NvramManagerTest, LockSpaceRead_Success) {
1061 // Set up an NVRAM space.
1062 NvramSpace space;
1063 space.controls = (1 << NV_CONTROL_BOOT_READ_LOCK);
1064 ASSERT_TRUE(space.contents.Assign("0123456789", 10));
1065 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
1066 SetupHeader(NvramHeader::kVersion, 17);
1067
1068 NvramManager nvram;
1069
1070 // Lock the space.
1071 LockSpaceReadRequest lock_space_read_request;
1072 lock_space_read_request.index = 17;
1073 LockSpaceReadResponse lock_space_read_response;
1074 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.LockSpaceRead(lock_space_read_request,
1075 &lock_space_read_response));
1076
1077 // Read requests should fail now.
1078 ReadSpaceRequest read_space_request;
1079 read_space_request.index = 17;
1080 ReadSpaceResponse read_space_response;
1081 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED,
1082 nvram.ReadSpace(read_space_request, &read_space_response));
1083 EXPECT_EQ(0U, read_space_response.buffer.size());
1084
1085 // This is a non-persistent lock, so reads should work again after a reboot.
1086 NvramManager nvram2;
1087
1088 ReadAndCompareSpaceData(&nvram2, 17, "0123456789", 10);
1089 }
1090
TEST_F(NvramManagerTest,LockSpaceRead_NotLockable)1091 TEST_F(NvramManagerTest, LockSpaceRead_NotLockable) {
1092 // Set up an NVRAM space.
1093 NvramSpace space;
1094 ASSERT_TRUE(space.contents.Resize(10));
1095 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
1096 SetupHeader(NvramHeader::kVersion, 17);
1097
1098 NvramManager nvram;
1099
1100 // Attempt to lock a space without valid authorization.
1101 LockSpaceReadRequest lock_space_read_request;
1102 lock_space_read_request.index = 17;
1103 LockSpaceReadResponse lock_space_read_response;
1104 EXPECT_EQ(
1105 NV_RESULT_INVALID_PARAMETER,
1106 nvram.LockSpaceRead(lock_space_read_request, &lock_space_read_response));
1107 }
1108
TEST_F(NvramManagerTest,WipeStorage_Success)1109 TEST_F(NvramManagerTest, WipeStorage_Success) {
1110 // Set up an NVRAM space.
1111 NvramSpace space;
1112 ASSERT_TRUE(space.contents.Resize(10));
1113 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
1114 SetupHeader(NvramHeader::kVersion, 17);
1115
1116 // Check that the space is visible.
1117 NvramManager nvram;
1118 GetSpaceInfoRequest get_space_info_request;
1119 get_space_info_request.index = 17;
1120 GetSpaceInfoResponse get_space_info_response;
1121 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
1122 &get_space_info_response));
1123 EXPECT_EQ(10U, get_space_info_response.size);
1124
1125 // Request a wipe.
1126 WipeStorageRequest wipe_storage_request;
1127 WipeStorageResponse wipe_storage_response;
1128 EXPECT_EQ(NV_RESULT_SUCCESS,
1129 nvram.WipeStorage(wipe_storage_request, &wipe_storage_response));
1130
1131 // The space should no longer be declared.
1132 GetInfoRequest get_info_request;
1133 GetInfoResponse get_info_response;
1134 EXPECT_EQ(NV_RESULT_SUCCESS,
1135 nvram.GetInfo(get_info_request, &get_info_response));
1136 EXPECT_EQ(0U, get_info_response.space_list.size());
1137
1138 // Accessing the space should fail.
1139 EXPECT_EQ(
1140 NV_RESULT_SPACE_DOES_NOT_EXIST,
1141 nvram.GetSpaceInfo(get_space_info_request, &get_space_info_response));
1142 }
1143
TEST_F(NvramManagerTest,WipeStorage_Abort)1144 TEST_F(NvramManagerTest, WipeStorage_Abort) {
1145 // Set up two pre-existing spaces and a matching header.
1146 NvramSpace space;
1147 ASSERT_TRUE(space.contents.Resize(10));
1148 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(1, space));
1149 ASSERT_TRUE(space.contents.Resize(20));
1150 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(2, space));
1151 NvramHeader header;
1152 header.version = NvramHeader::kVersion;
1153 ASSERT_TRUE(header.allocated_indices.Resize(2));
1154 header.allocated_indices[0] = 1;
1155 header.allocated_indices[1] = 2;
1156 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreHeader(header));
1157
1158 // Check that the spaces are visible.
1159 NvramManager nvram;
1160 GetInfoRequest get_info_request;
1161 GetInfoResponse get_info_response;
1162 EXPECT_EQ(NV_RESULT_SUCCESS,
1163 nvram.GetInfo(get_info_request, &get_info_response));
1164 EXPECT_EQ(2U, get_info_response.space_list.size());
1165 int space_mask = 0;
1166 for (size_t i = 0; i < get_info_response.space_list.size(); ++i) {
1167 space_mask |= (1 << get_info_response.space_list[i]);
1168 }
1169 EXPECT_EQ(0x6, space_mask);
1170
1171 // Set things up so the deletion request for the second space fails.
1172 storage::SetSpaceWriteError(2, true);
1173
1174 // The wipe request should fail now.
1175 WipeStorageRequest wipe_storage_request;
1176 WipeStorageResponse wipe_storage_response;
1177 EXPECT_EQ(NV_RESULT_INTERNAL_ERROR,
1178 nvram.WipeStorage(wipe_storage_request, &wipe_storage_response));
1179
1180 // New wipe attempt with a fresh instance after clearing the error.
1181 storage::SetSpaceWriteError(2, false);
1182 NvramManager nvram2;
1183 EXPECT_EQ(NV_RESULT_SUCCESS,
1184 nvram2.WipeStorage(wipe_storage_request, &wipe_storage_response));
1185
1186 // No spaces should remain.
1187 EXPECT_EQ(NV_RESULT_SUCCESS,
1188 nvram2.GetInfo(get_info_request, &get_info_response));
1189 EXPECT_EQ(0U, get_info_response.space_list.size());
1190 }
1191
TEST_F(NvramManagerTest,WipeStorage_Disable)1192 TEST_F(NvramManagerTest, WipeStorage_Disable) {
1193 // Set up an NVRAM space.
1194 NvramSpace space;
1195 ASSERT_TRUE(space.contents.Resize(10));
1196 ASSERT_EQ(storage::Status::kSuccess, persistence::StoreSpace(17, space));
1197 SetupHeader(NvramHeader::kVersion, 17);
1198
1199 NvramManager nvram;
1200
1201 // Disable wiping.
1202 DisableWipeRequest disable_wipe_request;
1203 DisableWipeResponse disable_wipe_response;
1204 EXPECT_EQ(NV_RESULT_SUCCESS,
1205 nvram.DisableWipe(disable_wipe_request, &disable_wipe_response));
1206
1207 // A wipe request should fail.
1208 WipeStorageRequest wipe_storage_request;
1209 WipeStorageResponse wipe_storage_response;
1210 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED,
1211 nvram.WipeStorage(wipe_storage_request, &wipe_storage_response));
1212
1213 // The space should remain declared.
1214 GetInfoRequest get_info_request;
1215 GetInfoResponse get_info_response;
1216 EXPECT_EQ(NV_RESULT_SUCCESS,
1217 nvram.GetInfo(get_info_request, &get_info_response));
1218 ASSERT_EQ(1U, get_info_response.space_list.size());
1219 EXPECT_EQ(17U, get_info_response.space_list[0]);
1220
1221 // The space data should remain present.
1222 GetSpaceInfoRequest get_space_info_request;
1223 get_space_info_request.index = 17;
1224 GetSpaceInfoResponse get_space_info_response;
1225 EXPECT_EQ(NV_RESULT_SUCCESS, nvram.GetSpaceInfo(get_space_info_request,
1226 &get_space_info_response));
1227 EXPECT_EQ(10U, get_space_info_response.size);
1228 }
1229
1230 } // namespace
1231 } // namespace nvram
1232