blob: 27abca3bd571cf574d46fcdb164c4bb5d066b1c1 [file] [log] [blame]
Jakub Czapigab20aa092021-07-27 17:04:11 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <assert.h>
4#include <cbfs.h>
5#include <commonlib/bsd/cbfs_mdata.h>
6#include <commonlib/region.h>
7#include <string.h>
8#include <tests/lib/cbfs_util.h>
9#include <tests/test.h>
10
11
12static struct cbfs_boot_device cbd;
13
14static u8 aligned_cbfs_buffer[(sizeof(struct cbfs_test_file) + CBFS_ALIGNMENT) * 10]
15 __aligned(CBFS_ALIGNMENT);
16
17static u8 *unaligned_cbfs_buffer = &aligned_cbfs_buffer[3];
18static uintptr_t unaligned_cbfs_buffer_size = sizeof(aligned_cbfs_buffer) - 3;
19
20static u8 cbfs_mcache[TEST_MCACHE_SIZE] __aligned(CBFS_MCACHE_ALIGNMENT);
21
22/* Add files to CBFS buffer. NULL in files list equals to one CBFS_ALIGNMENT of spacing. */
23static int create_cbfs(const struct cbfs_test_file *files[], const size_t nfiles, u8 *buffer,
24 const size_t buffer_size)
25{
26 u8 *data_ptr = buffer;
27 size_t file_size = 0;
28 memset(buffer, 0, buffer_size);
29
30 for (size_t i = 0; i < nfiles; ++i) {
31 if (files[i] == NULL) {
32 file_size = CBFS_ALIGNMENT;
33 assert_true(&data_ptr[file_size] < &buffer[buffer_size]);
34 } else {
35 file_size = be32_to_cpu(files[i]->header.len)
36 + be32_to_cpu(files[i]->header.offset);
37 assert_true(&data_ptr[file_size] < &buffer[buffer_size]);
38 memcpy(data_ptr, files[i], file_size);
39 }
40
41 data_ptr = &data_ptr[file_size];
42 const uintptr_t offset = (uintptr_t)data_ptr - (uintptr_t)buffer;
43 data_ptr = &buffer[ALIGN_UP(offset, CBFS_ALIGNMENT)];
44 }
45
46 return 0;
47}
48
49/* Mocks */
50
51const struct cbfs_boot_device *cbfs_get_boot_device(bool force_ro)
52{
53 return &cbd;
54}
55
56size_t ulzman(const void *src, size_t srcn, void *dst, size_t dstn)
57{
58 check_expected(srcn);
59 check_expected(dstn);
60 memcpy(dst, src, dstn);
61 return dstn;
62}
63
64size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn)
65{
66 check_expected(srcn);
67 check_expected(dstn);
68 memcpy(dst, src, dstn);
69 return dstn;
70}
71
72extern cb_err_t __real_cbfs_lookup(cbfs_dev_t dev, const char *name,
73 union cbfs_mdata *mdata_out, size_t *data_offset_out,
74 struct vb2_hash *metadata_hash);
75
76cb_err_t cbfs_lookup(cbfs_dev_t dev, const char *name, union cbfs_mdata *mdata_out,
77 size_t *data_offset_out, struct vb2_hash *metadata_hash)
78{
79 const cb_err_t err =
80 __real_cbfs_lookup(dev, name, mdata_out, data_offset_out, metadata_hash);
81 assert_int_equal(err, mock_type(cb_err_t));
82 return err;
83}
84
85extern cb_err_t __real_cbfs_mcache_lookup(const void *mcache, size_t mcache_size,
86 const char *name, union cbfs_mdata *mdata_out,
87 size_t *data_offset_out);
88
89cb_err_t cbfs_mcache_lookup(const void *mcache, size_t mcache_size, const char *name,
90 union cbfs_mdata *mdata_out, size_t *data_offset_out)
91{
92 const cb_err_t err = __real_cbfs_mcache_lookup(mcache, mcache_size, name, mdata_out,
93 data_offset_out);
94 assert_int_equal(err, mock_type(cb_err_t));
95 return err;
96}
97
98extern void *__real_mem_pool_alloc(struct mem_pool *mp, size_t sz);
99
100void *mem_pool_alloc(struct mem_pool *mp, size_t sz)
101{
102 check_expected(sz);
103 assert_ptr_equal(mp, &cbfs_cache);
104 return __real_mem_pool_alloc(mp, sz);
105}
106
107extern void __real_mem_pool_free(struct mem_pool *mp, void *p);
108
109void mem_pool_free(struct mem_pool *mp, void *p)
110{
111 check_expected(p);
112 assert_ptr_equal(mp, &cbfs_cache);
113 return __real_mem_pool_free(mp, p);
114}
115
116static u8 cbmem_test_buf[2 * MiB];
117
118void *cbmem_add(u32 id, u64 size)
119{
120 check_expected(id);
121 check_expected(size);
122 return cbmem_test_buf;
123}
124
125/* Setup, teardown and utils */
126
127struct cbfs_test_state_ex {
128 u32 file_type;
129 u32 file_length;
130 cb_err_t lookup_result;
131};
132
133struct cbfs_test_state {
134 u8 *cbfs_buf;
135 size_t cbfs_size;
136
137 /* Optionals */
138 struct cbfs_test_state_ex ex;
139};
140
141static int setup_test_cbfs_aligned(void **state)
142{
143 struct cbfs_test_state *s = malloc(sizeof(struct cbfs_test_state));
144
145 if (!s)
146 return 1;
147 s->cbfs_buf = aligned_cbfs_buffer;
148 s->cbfs_size = sizeof(aligned_cbfs_buffer);
149 memset(&s->ex, 0, sizeof(s->ex));
150
151 /* Prestate */
152 if (*state != NULL)
153 s->ex = *((struct cbfs_test_state_ex *)*state);
154
155 *state = s;
156
157 rdev_chain_mem(&cbd.rdev, aligned_cbfs_buffer, sizeof(aligned_cbfs_buffer));
158 memset(aligned_cbfs_buffer, 0, sizeof(aligned_cbfs_buffer));
159
160 cbd.mcache = cbfs_mcache;
161 cbd.mcache_size = TEST_MCACHE_SIZE;
162
163 return 0;
164}
165
166static int setup_test_cbfs_unaligned(void **state)
167{
168 struct cbfs_test_state *s = malloc(sizeof(struct cbfs_test_state));
169
170 if (!s)
171 return 1;
172 s->cbfs_buf = unaligned_cbfs_buffer;
173 s->cbfs_size = unaligned_cbfs_buffer_size;
174 memset(&s->ex, 0, sizeof(s->ex));
175
176 /* Prestate */
177 if (*state != NULL)
178 s->ex = *((struct cbfs_test_state_ex *)*state);
179
180 *state = s;
181
182 rdev_chain_mem(&cbd.rdev, unaligned_cbfs_buffer, unaligned_cbfs_buffer_size);
183 memset(unaligned_cbfs_buffer, 0, unaligned_cbfs_buffer_size);
184
185 cbd.mcache = cbfs_mcache;
186 cbd.mcache_size = TEST_MCACHE_SIZE;
187
188 return 0;
189}
190
191static int teardown_test_cbfs(void **state)
192{
193 free(*state);
194 memset(&cbd, 0, sizeof(cbd));
195 return 0;
196}
197
198/* Utils */
199
200static void expect_lookup_result(cb_err_t res)
201{
202 if (CONFIG(NO_CBFS_MCACHE))
203 will_return(cbfs_lookup, (res));
204 else
205 will_return(cbfs_mcache_lookup, (res));
206}
207
208/* Tests */
209
210/* Test case for cbfs_map() function. Validate file searching in the correct CBFS */
211static void test_cbfs_map(void **state)
212{
213 void *mapping;
214 size_t size_out;
215 struct cbfs_test_state *s = *state;
216 const struct cbfs_test_file *cbfs_files[] = {
217 &test_file_int_1, &test_file_2, NULL, &test_file_int_2,
218 &test_file_1, NULL, NULL, &test_file_int_3,
219 };
220 assert_int_equal(
221 0, create_cbfs(cbfs_files, ARRAY_SIZE(cbfs_files), s->cbfs_buf, s->cbfs_size));
222 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
223
224 /* Existing files */
225 size_out = 0;
226 expect_lookup_result(CB_SUCCESS);
227 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
228 assert_non_null(mapping);
229 assert_int_equal(TEST_DATA_1_SIZE, size_out);
230 assert_memory_equal(mapping, test_data_1, TEST_DATA_1_SIZE);
231
232 expect_value(mem_pool_free, p, mapping);
233 cbfs_unmap(mapping);
234
235 size_out = 0;
236 expect_value(ulzman, srcn, TEST_DATA_2_SIZE);
237 expect_value(ulzman, dstn, TEST_DATA_2_SIZE);
238 expect_value(mem_pool_alloc, sz, TEST_DATA_2_SIZE);
239 expect_lookup_result(CB_SUCCESS);
240 mapping = cbfs_map(TEST_DATA_2_FILENAME, &size_out);
241 assert_non_null(mapping);
242 assert_int_equal(TEST_DATA_2_SIZE, size_out);
243 assert_memory_equal(mapping, test_data_2, TEST_DATA_2_SIZE);
244
245 expect_value(mem_pool_free, p, mapping);
246 cbfs_unmap(mapping);
247
248 size_out = 0;
249 expect_lookup_result(CB_SUCCESS);
250 mapping = cbfs_map(TEST_DATA_INT_1_FILENAME, &size_out);
251 assert_non_null(mapping);
252 assert_int_equal(TEST_DATA_INT_1_SIZE, size_out);
253 assert_memory_equal(mapping, test_data_int_1, TEST_DATA_INT_1_SIZE);
254
255 expect_value(mem_pool_free, p, mapping);
256 cbfs_unmap(mapping);
257
258 /* Do not pass output pointer to size. It should work correctly. */
259 expect_lookup_result(CB_SUCCESS);
260 mapping = cbfs_map(TEST_DATA_INT_2_FILENAME, NULL);
261 assert_non_null(mapping);
262 assert_memory_equal(mapping, test_data_int_2, TEST_DATA_INT_2_SIZE);
263
264 expect_value(mem_pool_free, p, mapping);
265 cbfs_unmap(mapping);
266
267 size_out = 0;
268 expect_value(ulz4fn, srcn, TEST_DATA_INT_3_SIZE);
269 expect_value(ulz4fn, dstn, TEST_DATA_INT_3_SIZE);
270 expect_value(mem_pool_alloc, sz, TEST_DATA_INT_3_SIZE);
271 expect_lookup_result(CB_SUCCESS);
272 mapping = cbfs_map(TEST_DATA_INT_3_FILENAME, &size_out);
273 assert_non_null(mapping);
274 assert_int_equal(TEST_DATA_INT_3_SIZE, size_out);
275 assert_memory_equal(mapping, test_data_int_3, TEST_DATA_INT_3_SIZE);
276
277 expect_value(mem_pool_free, p, mapping);
278 cbfs_unmap(mapping);
279
280 /* Nonexistent files */
281 size_out = 0;
282 expect_lookup_result(CB_CBFS_NOT_FOUND);
283 mapping = cbfs_map("unknown_fname", &size_out);
284 assert_ptr_equal(NULL, mapping);
285 assert_int_equal(0, size_out);
286
287 size_out = 0;
288 expect_lookup_result(CB_CBFS_NOT_FOUND);
289 mapping = cbfs_map("", &size_out);
290 assert_ptr_equal(NULL, mapping);
291 assert_int_equal(0, size_out);
292}
293
294static void test_cbfs_cbmem_alloc(void **state)
295{
296 void *mapping;
297 size_t size_out;
298 struct cbfs_test_state *s = *state;
299 const struct cbfs_test_file *cbfs_files[] = {
300 NULL, &test_file_1, &test_file_2, &test_file_int_1,
301 NULL, &test_file_int_2, &test_file_int_3, NULL,
302 };
303 assert_int_equal(
304 0, create_cbfs(cbfs_files, ARRAY_SIZE(cbfs_files), s->cbfs_buf, s->cbfs_size));
305 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
306
307 /* Existing files */
308 expect_lookup_result(CB_SUCCESS);
309 expect_value(cbmem_add, id, 0x0101);
310 expect_value(cbmem_add, size, TEST_DATA_1_SIZE);
311 mapping = cbfs_cbmem_alloc(TEST_DATA_1_FILENAME, 0x0101, &size_out);
312 assert_non_null(mapping);
313 assert_int_equal(TEST_DATA_1_SIZE, size_out);
314 assert_memory_equal(mapping, test_data_1, TEST_DATA_1_SIZE);
315
316 expect_value(mem_pool_free, p, mapping);
317 cbfs_unmap(mapping);
318
319 /* Do not pass output pointer to size. It should work correctly. */
320 expect_value(ulzman, srcn, TEST_DATA_2_SIZE);
321 expect_value(ulzman, dstn, TEST_DATA_2_SIZE);
322 expect_lookup_result(CB_SUCCESS);
323 expect_value(cbmem_add, id, 0x0102);
324 expect_value(cbmem_add, size, TEST_DATA_2_SIZE);
325 mapping = cbfs_cbmem_alloc(TEST_DATA_2_FILENAME, 0x0102, NULL);
326 assert_non_null(mapping);
327 assert_memory_equal(mapping, test_data_2, TEST_DATA_2_SIZE);
328
329 expect_value(mem_pool_free, p, mapping);
330 cbfs_unmap(mapping);
331
332 size_out = 0;
333 expect_lookup_result(CB_SUCCESS);
334 expect_value(cbmem_add, id, 0x0201);
335 expect_value(cbmem_add, size, TEST_DATA_INT_1_SIZE);
336 mapping = cbfs_cbmem_alloc(TEST_DATA_INT_1_FILENAME, 0x0201, &size_out);
337 assert_non_null(mapping);
338 assert_int_equal(TEST_DATA_INT_1_SIZE, size_out);
339 assert_memory_equal(mapping, test_data_int_1, TEST_DATA_INT_1_SIZE);
340
341 expect_value(mem_pool_free, p, mapping);
342 cbfs_unmap(mapping);
343
344 size_out = 0;
345 expect_lookup_result(CB_SUCCESS);
346 expect_value(cbmem_add, id, 0x0202);
347 expect_value(cbmem_add, size, TEST_DATA_INT_2_SIZE);
348 mapping = cbfs_cbmem_alloc(TEST_DATA_INT_2_FILENAME, 0x0202, &size_out);
349 assert_non_null(mapping);
350 assert_int_equal(TEST_DATA_INT_2_SIZE, size_out);
351 assert_memory_equal(mapping, test_data_int_2, TEST_DATA_INT_2_SIZE);
352
353 expect_value(mem_pool_free, p, mapping);
354 cbfs_unmap(mapping);
355
356 size_out = 0;
357 expect_value(ulz4fn, srcn, TEST_DATA_INT_3_SIZE);
358 expect_value(ulz4fn, dstn, TEST_DATA_INT_3_SIZE);
359 expect_lookup_result(CB_SUCCESS);
360 expect_value(cbmem_add, id, 0x0203);
361 expect_value(cbmem_add, size, TEST_DATA_INT_2_SIZE);
362 mapping = cbfs_cbmem_alloc(TEST_DATA_INT_3_FILENAME, 0x0203, &size_out);
363 assert_non_null(mapping);
364 assert_int_equal(TEST_DATA_INT_3_SIZE, size_out);
365 assert_memory_equal(mapping, test_data_int_3, TEST_DATA_INT_3_SIZE);
366
367 expect_value(mem_pool_free, p, mapping);
368 cbfs_unmap(mapping);
369
370 /* Nonexistent files */
371 size_out = 0;
372 expect_lookup_result(CB_CBFS_NOT_FOUND);
373 mapping = cbfs_cbmem_alloc("nothing-file", 0x0301, &size_out);
374 assert_null(mapping);
375
376 size_out = 0;
377 expect_lookup_result(CB_CBFS_NOT_FOUND);
378 mapping = cbfs_cbmem_alloc("", 0x0302, &size_out);
379 assert_null(mapping);
380}
381
382static void test_cbfs_image_not_aligned(void **state)
383{
384 void *mapping;
385 size_t size_out;
386 struct cbfs_test_state *s = *state;
387 const struct cbfs_test_file *cbfs_files[] = {
388 &test_file_int_1, &test_file_2,
389 };
390 assert_int_equal(0, create_cbfs(cbfs_files, ARRAY_SIZE(cbfs_files), &s->cbfs_buf[5],
391 s->cbfs_size - 5));
392 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
393
394 size_out = 0;
395 expect_lookup_result(CB_CBFS_NOT_FOUND);
396 mapping = cbfs_map(TEST_DATA_INT_1_FILENAME, &size_out);
397 assert_null(mapping);
398
399 size_out = 0;
400 expect_lookup_result(CB_CBFS_NOT_FOUND);
401 mapping = cbfs_map(TEST_DATA_2_FILENAME, &size_out);
402 assert_null(mapping);
403}
404
405static void test_cbfs_file_not_aligned(void **state)
406{
407 void *mapping;
408 size_t size_out;
409 struct cbfs_test_state *s = *state;
410
411 memcpy(s->cbfs_buf, &test_file_int_2, sizeof(test_file_int_2));
412 memcpy(&s->cbfs_buf[ALIGN_UP(sizeof(test_file_int_2), CBFS_ALIGNMENT) + 5],
413 &test_file_1, sizeof(test_file_1));
414 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
415
416 size_out = 0;
417 expect_lookup_result(CB_SUCCESS);
418 mapping = cbfs_map(TEST_DATA_INT_2_FILENAME, &size_out);
419 assert_ptr_equal(mapping,
420 &s->cbfs_buf[offsetof(struct cbfs_test_file, attrs_and_data)]);
421
422 size_out = 0;
423 expect_lookup_result(CB_CBFS_NOT_FOUND);
424 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
425 assert_null(mapping);
426}
427
428static void test_cbfs_garbage_data_before_aligned_file(void **state)
429{
430 void *mapping;
431 size_t size_out;
432 const char garbage[] =
433 "NOT so USEFUL DaTa BYTES that should have at least CBFS_ALIGNMENT bytes";
434 const size_t garbage_sz = CBFS_ALIGNMENT;
435 struct cbfs_test_state *s = *state;
436
437 /* Garbage data size has to be aligned to CBFS_ALIGNMENT */
438 memcpy(s->cbfs_buf, garbage, garbage_sz);
439 memcpy(&s->cbfs_buf[garbage_sz], &test_file_int_2, sizeof(test_file_int_2));
440 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
441
442 size_out = 0;
443 expect_lookup_result(CB_SUCCESS);
444 mapping = cbfs_map(TEST_DATA_INT_2_FILENAME, &size_out);
445 assert_ptr_equal(
446 mapping,
447 &s->cbfs_buf[garbage_sz + offsetof(struct cbfs_test_file, attrs_and_data)]);
448}
449
450static void test_cbfs_garbage_data_before_unaligned_file(void **state)
451{
452 void *mapping;
453 size_t size_out;
454 const char garbage[] =
455 "NOT so USEFUL DaTa BYTES that should have at least CBFS_ALIGNMENT + 3 bytes";
456 const size_t garbage_sz = CBFS_ALIGNMENT + 3;
457 struct cbfs_test_state *s = *state;
458
459 assert_true(garbage_sz == (CBFS_ALIGNMENT + 3));
460 memcpy(s->cbfs_buf, garbage, garbage_sz);
461 memcpy(&s->cbfs_buf[garbage_sz], &test_file_int_2, sizeof(test_file_int_2));
462 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
463
464 size_out = 0;
465 expect_lookup_result(CB_CBFS_NOT_FOUND);
466 mapping = cbfs_map(TEST_DATA_INT_2_FILENAME, &size_out);
467 assert_null(mapping);
468}
469
470static void test_cbfs_file_bigger_than_rdev(void **state)
471{
472 void *mapping;
473 size_t size_out;
474 struct cbfs_test_state *s = *state;
475 struct cbfs_test_file *f;
476 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
477 f = (struct cbfs_test_file *)s->cbfs_buf;
478 /* File with length equal to region_device size will go beyond it */
479 f->header.len = cpu_to_be32(s->cbfs_size);
480
481 /* Initialization and mcache building will succeed, because it only does access file
482 headers, and not actual data */
483 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
484
485 size_out = 0;
486 /* Lookup should not succeed, because data is too long, so reading it later would cause
487 memory access issues */
488 expect_lookup_result(CB_CBFS_NOT_FOUND);
489 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
490 assert_null(mapping);
491}
492
493static void test_cbfs_fail_beyond_rdev(void **state)
494{
495 void *mapping;
496 size_t size_out;
497 struct cbfs_test_state *s = *state;
498 size_t second_file_start = ALIGN_UP(sizeof(test_file_1), CBFS_ALIGNMENT);
499
500 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
501 memcpy(&s->cbfs_buf[second_file_start], &test_file_2, s->ex.file_length);
502 assert_true((second_file_start + s->ex.file_length) <= region_sz(&cbd.rdev.region));
503 /* Adjust size of region device to cut everything after selected offset */
504 cbd.rdev.region.size = second_file_start + s->ex.file_length;
505
506 /* CBFS initialization should not fail if last file is not valid */
507 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
508
509 size_out = 0;
510 expect_lookup_result(CB_SUCCESS);
511 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
512 assert_ptr_equal(mapping, &s->cbfs_buf[be32_to_cpu(test_file_1.header.offset)]);
513 assert_int_equal(size_out, TEST_DATA_1_SIZE);
514
515 size_out = 0;
516 if (s->ex.lookup_result == CB_SUCCESS) {
517 expect_value(ulzman, srcn, TEST_DATA_2_SIZE);
518 expect_value(ulzman, dstn, TEST_DATA_2_SIZE);
519 expect_value(mem_pool_alloc, sz, TEST_DATA_2_SIZE);
520 }
521 expect_lookup_result(s->ex.lookup_result);
522 cbfs_map(TEST_DATA_2_FILENAME, &size_out);
523}
524
525static void test_cbfs_unaligned_file_in_the_middle(void **state)
526{
527 void *mapping;
528 size_t size_out;
529 struct cbfs_test_state *s = *state;
530 size_t second_file_start = ALIGN_UP(sizeof(test_file_1), CBFS_ALIGNMENT) + 5;
531 size_t third_file_start =
532 ALIGN_UP(sizeof(test_file_int_1) + second_file_start, CBFS_ALIGNMENT);
533
534 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
535 memcpy(&s->cbfs_buf[second_file_start], &test_file_int_1, sizeof(test_file_int_1));
536 memcpy(&s->cbfs_buf[third_file_start], &test_file_int_2, sizeof(test_file_int_2));
537
538 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
539
540 size_out = 0;
541 expect_lookup_result(CB_SUCCESS);
542 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
543 assert_ptr_equal(mapping, &s->cbfs_buf[be32_to_cpu(test_file_1.header.offset)]);
544 assert_int_equal(size_out, be32_to_cpu(test_file_1.header.len));
545
546 size_out = 0;
547 expect_lookup_result(CB_CBFS_NOT_FOUND);
548 mapping = cbfs_map(TEST_DATA_INT_1_FILENAME, &size_out);
549 assert_null(mapping);
550
551 size_out = 0;
552 expect_lookup_result(CB_SUCCESS);
553 mapping = cbfs_map(TEST_DATA_INT_2_FILENAME, &size_out);
554 assert_ptr_equal(
555 mapping,
556 &s->cbfs_buf[third_file_start + be32_to_cpu(test_file_int_2.header.offset)]);
557 assert_int_equal(size_out, be32_to_cpu(test_file_int_2.header.len));
558}
559
560static void test_cbfs_overlapping_files(void **state)
561{
562 void *mapping;
563 size_t size_out;
564 struct cbfs_test_state *s = *state;
565 size_t second_file_start = ALIGN_UP(sizeof(test_file_1), CBFS_ALIGNMENT);
566 size_t third_file_start =
567 ALIGN_UP(sizeof(test_file_int_1) + second_file_start, CBFS_ALIGNMENT);
568 size_t second_file_size =
569 third_file_start + sizeof(test_file_int_2) - second_file_start;
570 struct cbfs_test_file *f;
571
572 /* Third file is inside second file, thus it should not be found */
573 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
574 memcpy(&s->cbfs_buf[second_file_start], &test_file_int_1, sizeof(test_file_int_1));
575 memcpy(&s->cbfs_buf[third_file_start], &test_file_int_2, sizeof(test_file_int_2));
576 f = (struct cbfs_test_file *)&s->cbfs_buf[second_file_start];
577 f->header.len = cpu_to_be32(second_file_size);
578
579 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
580
581 size_out = 0;
582 expect_lookup_result(CB_SUCCESS);
583 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
584 assert_ptr_equal(mapping, &s->cbfs_buf[be32_to_cpu(test_file_1.header.offset)]);
585 assert_int_equal(size_out, be32_to_cpu(test_file_1.header.len));
586
587 size_out = 0;
588 expect_lookup_result(CB_SUCCESS);
589 mapping = cbfs_map(TEST_DATA_INT_1_FILENAME, &size_out);
590 assert_ptr_equal(
591 mapping,
592 &s->cbfs_buf[second_file_start + be32_to_cpu(test_file_int_1.header.offset)]);
593 assert_int_equal(size_out, second_file_size);
594
595 size_out = 0;
596 expect_lookup_result(CB_CBFS_NOT_FOUND);
597 mapping = cbfs_map(TEST_DATA_INT_2_FILENAME, &size_out);
598 assert_null(mapping);
599}
600
601static void test_cbfs_incorrect_file_in_the_middle(void **state)
602{
603 void *mapping;
604 size_t size_out;
605 struct cbfs_test_state *s = *state;
606 size_t second_file_start = ALIGN_UP(sizeof(test_file_1), CBFS_ALIGNMENT);
607 size_t third_file_start =
608 ALIGN_UP(sizeof(test_file_int_1) + second_file_start, CBFS_ALIGNMENT);
609 struct cbfs_test_file *f;
610
611 /* Zero offset is illegal. File is not correct */
612 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
613 memcpy(&s->cbfs_buf[second_file_start], &test_file_int_1, sizeof(test_file_int_1));
614 memcpy(&s->cbfs_buf[third_file_start], &test_file_int_2, sizeof(test_file_int_2));
615 f = (struct cbfs_test_file *)&s->cbfs_buf[second_file_start];
616 f->header.offset = cpu_to_be32(0);
617
618 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
619
620 size_out = 0;
621 expect_lookup_result(CB_SUCCESS);
622 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
623 assert_ptr_equal(mapping, &s->cbfs_buf[be32_to_cpu(test_file_1.header.offset)]);
624 assert_int_equal(size_out, be32_to_cpu(test_file_1.header.len));
625
626 size_out = 0;
627 expect_lookup_result(CB_CBFS_NOT_FOUND);
628 mapping = cbfs_map(TEST_DATA_INT_1_FILENAME, &size_out);
629 assert_null(mapping);
630
631 size_out = 0;
632 expect_lookup_result(CB_SUCCESS);
633 mapping = cbfs_map(TEST_DATA_INT_2_FILENAME, &size_out);
634 assert_ptr_equal(
635 mapping,
636 &s->cbfs_buf[third_file_start + be32_to_cpu(test_file_int_2.header.offset)]);
637 assert_int_equal(size_out, be32_to_cpu(test_file_int_2.header.len));
638}
639
640static void test_cbfs_two_files_with_same_name(void **state)
641{
642 void *mapping;
643 size_t size_out;
644 struct cbfs_test_state *s = *state;
645 size_t second_file_start = ALIGN_UP(sizeof(test_file_1), CBFS_ALIGNMENT);
646 size_t third_file_start =
647 ALIGN_UP(sizeof(test_file_1) + second_file_start, CBFS_ALIGNMENT);
648
649 /* Only first occurrence of file will be found */
650 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
651 memcpy(&s->cbfs_buf[second_file_start], &test_file_1, sizeof(test_file_1));
652 memcpy(&s->cbfs_buf[third_file_start], &test_file_int_1, sizeof(test_file_int_1));
653
654 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
655
656 size_out = 0;
657 expect_lookup_result(CB_SUCCESS);
658 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
659 assert_ptr_equal(mapping, &s->cbfs_buf[be32_to_cpu(test_file_1.header.offset)]);
660 assert_int_equal(size_out, be32_to_cpu(test_file_1.header.len));
661
662 size_out = 0;
663 expect_lookup_result(CB_SUCCESS);
664 mapping = cbfs_map(TEST_DATA_INT_1_FILENAME, &size_out);
665 assert_ptr_equal(mapping, &s->cbfs_buf[third_file_start
666 + be32_to_cpu(test_file_int_1.header.offset)]);
667 assert_int_equal(size_out, be32_to_cpu(test_file_int_1.header.len));
668}
669
670static void test_cbfs_filename_not_terminated(void **state)
671{
672 void *mapping;
673 size_t size_out;
674 struct cbfs_test_state *s = *state;
675 struct cbfs_test_file *f;
676 const char fname[] = "abcdefghijklmnop";
677
678 assert_true(sizeof(test_file_1.filename) == strlen(fname));
679 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
680 f = (struct cbfs_test_file *)s->cbfs_buf;
681 memcpy(f->filename, fname, strlen(fname));
682
683 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
684
685 size_out = 0;
686 /* Filename is too long and does not include NULL-terminator. */
687 expect_lookup_result(CB_CBFS_NOT_FOUND);
688 mapping = cbfs_map(fname, &size_out);
689 assert_null(mapping);
690}
691
692static void test_cbfs_filename_terminated_but_too_long(void **state)
693{
694 void *mapping;
695 size_t size_out;
696 struct cbfs_test_state *s = *state;
697 struct cbfs_test_file *f;
698
699 /* Filename length in header offset field is too short by one to include
700 NULL-terminator of filename */
701 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
702 f = (struct cbfs_test_file *)s->cbfs_buf;
703 f->header.offset = cpu_to_be32(offsetof(struct cbfs_test_file, filename)
704 + strlen(TEST_DATA_1_FILENAME));
705
706 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
707
708 size_out = 0;
709 expect_lookup_result(CB_CBFS_NOT_FOUND);
710 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
711 assert_null(mapping);
712}
713
714static void test_cbfs_attributes_offset_larger_than_offset(void **state)
715{
716 void *mapping;
717 size_t size_out;
718 struct cbfs_test_state *s = *state;
719 struct cbfs_test_file *f;
720
721 /* Require attributes for this test */
722 assert_true(be32_to_cpu(test_file_2.header.attributes_offset) != 0);
723 memcpy(s->cbfs_buf, &test_file_2, sizeof(test_file_2));
724 f = (struct cbfs_test_file *)s->cbfs_buf;
725 f->header.attributes_offset = cpu_to_be32(
726 sizeof(struct cbfs_file) + FILENAME_SIZE
727 + sizeof(struct cbfs_file_attr_compression));
728 f->header.offset = cpu_to_be32(sizeof(struct cbfs_file) + FILENAME_SIZE);
729
730 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
731
732 size_out = 0;
733 expect_lookup_result(CB_CBFS_NOT_FOUND);
734 mapping = cbfs_map(TEST_DATA_2_FILENAME, &size_out);
735 assert_null(mapping);
736}
737
738static void test_cbfs_attributes_offset_cut_off_at_len(void **state)
739{
740 void *mapping;
741 size_t size_out;
742 struct cbfs_test_state *s = *state;
743 struct cbfs_test_file *f;
744
745 /* Require attributes for this test */
746 assert_true(be32_to_cpu(test_file_2.header.attributes_offset) != 0);
747 memcpy(s->cbfs_buf, &test_file_2, sizeof(test_file_2));
748 f = (struct cbfs_test_file *)s->cbfs_buf;
749 f->header.attributes_offset =
750 cpu_to_be32(offsetof(struct cbfs_test_file, attrs_and_data)
751 + offsetof(struct cbfs_file_attribute, len));
752
753 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
754
755 /* No attributes will be found, because attributes_offset value is too big to cover
756 cbfs_file_attribute tag. Compression attribute of ths file will not be found, and
757 that is why there is no need to call expect_value(ulzma).
758 However, file will be found, because the offset is correct. */
759 size_out = 0;
760 expect_lookup_result(CB_SUCCESS);
761 mapping = cbfs_map(TEST_DATA_2_FILENAME, &size_out);
762 assert_ptr_equal(mapping, &s->cbfs_buf[be32_to_cpu(f->header.offset)]);
763 assert_int_equal(size_out, TEST_DATA_2_SIZE);
764}
765
766static void test_cbfs_attributes_offset_cut_off_at_data(void **state)
767{
768 void *mapping;
769 size_t size_out;
770 struct cbfs_test_state *s = *state;
771 struct cbfs_test_file *f;
772
773 /* Require attributes for this test */
774 assert_true(be32_to_cpu(test_file_2.header.attributes_offset) != 0);
775 memcpy(s->cbfs_buf, &test_file_2, sizeof(test_file_2));
776 f = (struct cbfs_test_file *)s->cbfs_buf;
777 f->header.attributes_offset = cpu_to_be32(sizeof(struct cbfs_file) + FILENAME_SIZE
778 + offsetof(struct cbfs_file_attribute, data));
779
780 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
781
782 /* No attributes will be found, because attributes_offset value is too big to cover
783 cbfs_file_attribute tag and length. Compression attribute of ths file will not be
784 found, and that is why there is no need to call expect_value(ulzma).
785 However, file will be found, because the offset is correct. */
786 size_out = 0;
787 expect_lookup_result(CB_SUCCESS);
788 mapping = cbfs_map(TEST_DATA_2_FILENAME, &size_out);
789 assert_ptr_equal(mapping, &s->cbfs_buf[be32_to_cpu(f->header.offset)]);
790 assert_int_equal(size_out, TEST_DATA_2_SIZE);
791}
792
793static void test_cbfs_attributes_offset_smaller_than_file_struct(void **state)
794{
795 void *mapping;
796 size_t size_out;
797 struct cbfs_test_state *s = *state;
798 struct cbfs_test_file *f;
799
800 assert_true(be32_to_cpu(test_file_2.header.attributes_offset) != 0);
801 memcpy(s->cbfs_buf, &test_file_2, sizeof(test_file_2));
802 f = (struct cbfs_test_file *)s->cbfs_buf;
803 f->header.attributes_offset = cpu_to_be32(sizeof(struct cbfs_file) / 2);
804
805 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
806
807 size_out = 0;
808 expect_lookup_result(CB_CBFS_NOT_FOUND);
809 mapping = cbfs_map(TEST_DATA_2_FILENAME, &size_out);
810 assert_null(mapping);
811}
812
813static void test_cbfs_offset_smaller_than_header_size(void **state)
814{
815 void *mapping;
816 size_t size_out;
817 struct cbfs_test_state *s = *state;
818 struct cbfs_test_file *f;
819
820 assert_true(be32_to_cpu(test_file_int_1.header.attributes_offset) == 0);
821 memcpy(s->cbfs_buf, &test_file_int_1, sizeof(test_file_int_1));
822 f = (struct cbfs_test_file *)s->cbfs_buf;
823 f->header.offset = cpu_to_be32(sizeof(struct cbfs_file) / 2);
824
825 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
826
827 size_out = 0;
828 expect_lookup_result(CB_CBFS_NOT_FOUND);
829 mapping = cbfs_map(TEST_DATA_INT_1_FILENAME, &size_out);
830 assert_null(mapping);
831}
832
833static void test_cbfs_attributes_offset_is_zero(void **state)
834{
835 void *mapping;
836 size_t size_out;
837 struct cbfs_test_state *s = *state;
838
839 assert_true(be32_to_cpu(test_file_int_1.header.attributes_offset) == 0);
840 memcpy(s->cbfs_buf, &test_file_int_1, sizeof(test_file_int_1));
841
842 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
843
844 size_out = 0;
845 expect_lookup_result(CB_SUCCESS);
846 mapping = cbfs_map(TEST_DATA_INT_1_FILENAME, &size_out);
847 assert_int_equal(TEST_DATA_INT_1_SIZE, size_out);
848 assert_ptr_equal(mapping, &s->cbfs_buf[be32_to_cpu(test_file_int_1.header.offset)]);
849}
850
851static void test_cbfs_offset_is_zero(void **state)
852{
853 void *mapping;
854 size_t size_out;
855 struct cbfs_test_state *s = *state;
856 struct cbfs_test_file *f;
857
858 assert_true(be32_to_cpu(test_file_int_1.header.attributes_offset) == 0);
859 memcpy(s->cbfs_buf, &test_file_int_1, sizeof(test_file_int_1));
860 f = (struct cbfs_test_file *)s->cbfs_buf;
861 f->header.offset = cpu_to_be32(0);
862
863 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
864
865 size_out = 0;
866 expect_lookup_result(CB_CBFS_NOT_FOUND);
867 mapping = cbfs_map(TEST_DATA_INT_1_FILENAME, &size_out);
868 assert_null(mapping);
869}
870
871static void test_cbfs_attributes_too_large(void **state)
872{
873 void *mapping;
874 size_t size_out;
875 struct cbfs_test_state *s = *state;
876 struct cbfs_test_file *f;
877
878 assert_true(be32_to_cpu(test_file_2.header.attributes_offset) != 0);
879 memcpy(s->cbfs_buf, &test_file_2, sizeof(test_file_2));
880 f = (struct cbfs_test_file *)s->cbfs_buf;
881 /* Offset determines size of header and attributes. CBFS module uses cbfs_mdata union to
882 store it, so offset (thus attributes) bigger than it should cause an error in the
883 lookup code. */
884 f->header.offset =
885 cpu_to_be32(be32_to_cpu(f->header.offset) + sizeof(union cbfs_mdata));
886
887 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
888
889 size_out = 0;
890 expect_lookup_result(CB_CBFS_NOT_FOUND);
891 mapping = cbfs_map(TEST_DATA_2_FILENAME, &size_out);
892 assert_null(mapping);
893}
894
895/* Requires cbfs_test_state.ex.file_length to be set */
896static void test_cbfs_file_length(void **state)
897{
898 void *mapping;
899 size_t size_out;
900 struct cbfs_test_state *s = *state;
901 struct cbfs_test_file *f;
902
903 assert_true(be32_to_cpu(test_file_1.header.attributes_offset) == 0);
904 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
905 f = (struct cbfs_test_file *)s->cbfs_buf;
906 f->header.len = cpu_to_be32(s->ex.file_length);
907
908 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
909
910 size_out = 0;
911 expect_lookup_result(CB_CBFS_NOT_FOUND);
912 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
913 assert_null(mapping);
914}
915
916static void test_cbfs_attributes_offset_uint32_max(void **state)
917{
918 void *mapping;
919 size_t size_out;
920 struct cbfs_test_state *s = *state;
921 struct cbfs_test_file *f;
922
923 assert_true(be32_to_cpu(test_file_1.header.attributes_offset) == 0);
924 memcpy(s->cbfs_buf, &test_file_1, sizeof(test_file_1));
925 f = (struct cbfs_test_file *)s->cbfs_buf;
926 f->header.attributes_offset = cpu_to_be32(UINT32_MAX);
927
928 assert_int_equal(CB_SUCCESS, cbfs_init_boot_device(&cbd, NULL));
929
930 size_out = 0;
931 expect_lookup_result(CB_CBFS_NOT_FOUND);
932 mapping = cbfs_map(TEST_DATA_1_FILENAME, &size_out);
933 assert_null(mapping);
934}
935
936#define CBFS_LOOKUP_NAME_SETUP_PRESTATE_COMMON_TEST(name, test_fn, setup_fn, prestate) \
937 { \
938 (name), (test_fn), (setup_fn), teardown_test_cbfs, (prestate), \
939 }
940
941#define CBFS_LOOKUP_NAME_PRESTATE_TEST(name, test_fn, prestate) \
942 EMPTY_WRAP( \
943 CBFS_LOOKUP_NAME_SETUP_PRESTATE_COMMON_TEST( \
944 ("aligned, " name), (test_fn), setup_test_cbfs_aligned, (prestate)), \
945 CBFS_LOOKUP_NAME_SETUP_PRESTATE_COMMON_TEST( \
946 ("unaligned, " name), (test_fn), setup_test_cbfs_unaligned, (prestate)))
947
948#define CBFS_LOOKUP_TEST(test_fn) CBFS_LOOKUP_NAME_PRESTATE_TEST(#test_fn, test_fn, NULL)
949
950#define CBFS_LOOKUP_TEST_FAIL_BEYOND_RDEV(name, file_len, lookup_res) \
951 EMPTY_WRAP(CBFS_LOOKUP_NAME_PRESTATE_TEST(name ", CBFS_TYPE_RAW", \
952 test_cbfs_fail_beyond_rdev, \
953 (&(struct cbfs_test_state_ex){ \
954 .file_type = CBFS_TYPE_RAW, \
955 .file_length = (file_len), \
956 .lookup_result = (lookup_res), \
957 })), \
958 CBFS_LOOKUP_NAME_PRESTATE_TEST(name ", CBFS_TYPE_NULL", \
959 test_cbfs_fail_beyond_rdev, \
960 (&(struct cbfs_test_state_ex){ \
961 .file_type = CBFS_TYPE_NULL, \
962 .file_length = (file_len), \
963 .lookup_result = (lookup_res), \
964 })))
965
966#define CBFS_LOOKUP_TEST_FILE_LENGTH(file_len) \
967 CBFS_LOOKUP_NAME_PRESTATE_TEST("test_cbfs_file_length, " #file_len, \
968 test_cbfs_file_length, \
969 (&(struct cbfs_test_state_ex){ \
970 .file_length = (file_len), \
971 }))
972
973int main(void)
974{
975 const struct CMUnitTest cbfs_lookup_aligned_and_unaligned_tests[] = {
976 CBFS_LOOKUP_TEST(test_cbfs_map),
977 CBFS_LOOKUP_TEST(test_cbfs_cbmem_alloc),
978
979 CBFS_LOOKUP_TEST(test_cbfs_image_not_aligned),
980 CBFS_LOOKUP_TEST(test_cbfs_file_not_aligned),
981
982 CBFS_LOOKUP_TEST(test_cbfs_garbage_data_before_aligned_file),
983 CBFS_LOOKUP_TEST(test_cbfs_garbage_data_before_unaligned_file),
984
985 CBFS_LOOKUP_TEST(test_cbfs_file_bigger_than_rdev),
986
987 /* Correct file */
988 CBFS_LOOKUP_TEST_FAIL_BEYOND_RDEV("File fitting in rdev",
989 sizeof(struct cbfs_test_file), CB_SUCCESS),
990
991 /* Attributes beyond rdev */
992 CBFS_LOOKUP_TEST_FAIL_BEYOND_RDEV(
993 "Attributes and data beyond rdev",
994 offsetof(struct cbfs_test_file, attrs_and_data), CB_CBFS_NOT_FOUND),
995
996 /* Attributes except tag beyond rdev */
997 CBFS_LOOKUP_TEST_FAIL_BEYOND_RDEV(
998 "Attributes except tag beyond rdev",
999 offsetof(struct cbfs_test_file, attrs_and_data)
1000 - offsetof(struct cbfs_file_attribute, len),
1001 CB_CBFS_NOT_FOUND),
1002
1003 /* Attributes except tag and len beyond rdev */
1004 CBFS_LOOKUP_TEST_FAIL_BEYOND_RDEV(
1005 "Attributes except tag and len beyond rdev",
1006 offsetof(struct cbfs_test_file, attrs_and_data)
1007 - offsetof(struct cbfs_file_attribute, data),
1008 CB_CBFS_NOT_FOUND),
1009
1010 /* Filename beyond rdev */
1011 CBFS_LOOKUP_TEST_FAIL_BEYOND_RDEV("Filename beyond rdev",
1012 offsetof(struct cbfs_test_file, filename),
1013 CB_CBFS_NOT_FOUND),
1014
1015 /* Part of filename beyond rdev */
1016 CBFS_LOOKUP_TEST_FAIL_BEYOND_RDEV("Part of filename beyond rdev",
1017 offsetof(struct cbfs_test_file, filename)
1018 + FILENAME_SIZE / 2,
1019 CB_CBFS_NOT_FOUND),
1020
1021 /* Part of cbfs_file struct beyond rdev */
1022 CBFS_LOOKUP_TEST_FAIL_BEYOND_RDEV("Part of cbfs_file struct beyond rdev",
1023 offsetof(struct cbfs_test_file, filename) / 2,
1024 CB_CBFS_NOT_FOUND),
1025
1026 CBFS_LOOKUP_TEST(test_cbfs_unaligned_file_in_the_middle),
1027 CBFS_LOOKUP_TEST(test_cbfs_overlapping_files),
1028 CBFS_LOOKUP_TEST(test_cbfs_incorrect_file_in_the_middle),
1029
1030 CBFS_LOOKUP_TEST(test_cbfs_two_files_with_same_name),
1031
1032 CBFS_LOOKUP_TEST(test_cbfs_filename_not_terminated),
1033 CBFS_LOOKUP_TEST(test_cbfs_filename_terminated_but_too_long),
1034
1035 CBFS_LOOKUP_TEST(test_cbfs_attributes_offset_larger_than_offset),
1036 CBFS_LOOKUP_TEST(test_cbfs_attributes_offset_cut_off_at_len),
1037 CBFS_LOOKUP_TEST(test_cbfs_attributes_offset_cut_off_at_data),
1038
1039 CBFS_LOOKUP_TEST(test_cbfs_attributes_offset_smaller_than_file_struct),
1040
1041 CBFS_LOOKUP_TEST(test_cbfs_offset_smaller_than_header_size),
1042 CBFS_LOOKUP_TEST(test_cbfs_attributes_offset_is_zero),
1043 CBFS_LOOKUP_TEST(test_cbfs_offset_is_zero),
1044 CBFS_LOOKUP_TEST(test_cbfs_attributes_too_large),
1045
1046 CBFS_LOOKUP_TEST_FILE_LENGTH(UINT32_MAX),
1047 CBFS_LOOKUP_TEST_FILE_LENGTH(UINT32_MAX
1048 - offsetof(struct cbfs_test_file, attrs_and_data)),
1049 CBFS_LOOKUP_TEST_FILE_LENGTH(
1050 UINT32_MAX - offsetof(struct cbfs_test_file, attrs_and_data) / 2),
1051 CBFS_LOOKUP_TEST_FILE_LENGTH(
1052 UINT32_MAX - offsetof(struct cbfs_test_file, attrs_and_data) * 2),
1053 CBFS_LOOKUP_TEST_FILE_LENGTH(
1054 UINT32_MAX - offsetof(struct cbfs_test_file, attrs_and_data) - 1),
1055 CBFS_LOOKUP_TEST_FILE_LENGTH(
1056 UINT32_MAX - offsetof(struct cbfs_test_file, attrs_and_data) + 1),
1057
1058 CBFS_LOOKUP_TEST(test_cbfs_attributes_offset_uint32_max),
1059 };
1060
1061 return cb_run_group_tests(cbfs_lookup_aligned_and_unaligned_tests, NULL, NULL);
1062}