1 /*
2 * Copyright (C) 2019 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 #include <ctype.h>
18 #include <elf.h>
19 #include <endian.h>
20 #include <errno.h>
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <trusty/string.h>
27 #include <trusty/uuid.h>
28 #include <uapi/err.h>
29
30 #if defined(TRUSTY_USERSPACE)
31 #include <sys/auxv.h>
32 #include <trusty/sys/mman.h>
33 #include <trusty/time.h>
34 #include <trusty_unittest.h>
35 #else
36 #include <lib/trusty/uuid.h>
37 #include <lib/unittest/unittest.h>
38
39 #include <lk/trusty_unittest.h>
40 #endif
41
42 #include <unistd.h>
43
44 #define CHECK_ERRNO(e) \
45 do { \
46 ASSERT_EQ(e, errno); \
47 errno = 0; \
48 } while (0)
49 #define CLEAR_ERRNO() \
50 do { \
51 errno = 0; \
52 } while (0)
53
54 typedef struct libc {
55 } libc_t;
56
TEST_F_SETUP(libc)57 TEST_F_SETUP(libc) {
58 /* Isolate the tests. */
59 CLEAR_ERRNO();
60 }
61
TEST_F_TEARDOWN(libc)62 TEST_F_TEARDOWN(libc) {
63 /* errno should have been checked and cleared if the test sets errno. */
64 CHECK_ERRNO(0);
65
66 test_abort:;
67 }
68
69 #define BUFFER_SIZE 100
70
71 #define EXPECT_STREQ_COND(lhs, rhs_true, rhs_false, condition) \
72 EXPECT_STREQ((lhs), (condition) ? (rhs_true) : (rhs_false))
73
74 /*
75 * Smoke test to make sure the endian functions are defined.
76 * Musl may or may not expose them, depending on the feature test macros.
77 */
TEST_F(libc,endian)78 TEST_F(libc, endian) {
79 const uint32_t test_data = 0x12345678;
80 /* TODO test le32, etc, once they are provided. */
81 ASSERT_EQ(test_data, be32toh(htobe32(test_data)));
82 test_abort:;
83 }
84
85 /*
86 * Test explicit_bzero() is present and functional.
87 * explicit_bzero() exists is to defeat optimisations that may remove 'dead'
88 * writes when trying to remove secrets from memory. The success of this is
89 * hard to detect at runtime and best achieved by inspecting assembly listings
90 * where needed.
91 */
TEST_F(libc,explicit_bzero_test)92 TEST_F(libc, explicit_bzero_test) {
93 uint32_t test_data = 0x12345678;
94 explicit_bzero(&test_data, sizeof(uint32_t));
95 EXPECT_EQ(test_data, 0);
96 }
97
TEST_F(libc,memset_test)98 TEST_F(libc, memset_test) {
99 unsigned char buf[130];
100 buf[0] = 0;
101 buf[129] = 0;
102 for (int val = 1; val < 256; val <<= 1) {
103 memset(&buf[1], val, 128);
104 ASSERT_EQ(0, buf[0], "iteration %d", val);
105 for (unsigned int i = 1; i < 128; i++) {
106 ASSERT_EQ(val, buf[i], "iteration %d", val);
107 }
108 ASSERT_EQ(0, buf[129], "iteration %d", val);
109 }
110
111 test_abort:;
112 }
113
TEST_F(libc,memcmp_test)114 TEST_F(libc, memcmp_test) {
115 unsigned char buf1[128];
116 unsigned char buf2[128];
117
118 /* Identical buffers. */
119 memset(buf1, 7, sizeof(buf1));
120 memset(buf2, 7, sizeof(buf2));
121 ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
122
123 /* buf1 slightly greater. */
124 buf1[127] = 9;
125 buf2[127] = 8;
126 ASSERT_LT(0, memcmp(buf1, buf2, sizeof(buf1)));
127
128 /* buf1 much greater. */
129 buf1[127] = 127;
130 buf2[127] = 0;
131 ASSERT_LT(0, memcmp(buf1, buf2, sizeof(buf1)));
132
133 /* buf2 slightly greater. */
134 buf1[127] = 8;
135 buf2[127] = 9;
136 ASSERT_GT(0, memcmp(buf1, buf2, sizeof(buf1)));
137
138 /* buf2 much greater. */
139 buf1[127] = 0;
140 buf2[127] = 127;
141 ASSERT_GT(0, memcmp(buf1, buf2, sizeof(buf1)));
142
143 /* Buffers are identical again. */
144 memcpy(buf2, buf1, sizeof(buf1));
145 ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
146
147 test_abort:;
148 }
149
TEST_F(libc,strcmp_test)150 TEST_F(libc, strcmp_test) {
151 ASSERT_EQ(0, strcmp("", ""));
152 ASSERT_GT(0, strcmp("", "bar"));
153 ASSERT_LT(0, strcmp("bar", ""));
154
155 ASSERT_EQ(0, strcmp("bar", "bar"));
156 ASSERT_GT(0, strcmp("bar", "baz"));
157 ASSERT_LT(0, strcmp("baz", "bar"));
158
159 ASSERT_GT(0, strcmp("bar", "barbar"));
160 ASSERT_LT(0, strcmp("barbar", "bar"));
161
162 char negative[2] = {-127, 0};
163 char positive[2] = {0, 0};
164 // strcmp must treat characters as unsigned
165 ASSERT_LT(0, strcmp(negative, positive));
166 ASSERT_LT(0, strncmp(negative, positive, 1));
167
168 test_abort:;
169 }
170
171 #if defined(TRUSTY_USERSPACE)
172 #define MSEC 1000000ULL
173
174 /*
175 * Smoke test the time-related functions.
176 * As long as gettime and nanosleep behave semi-reasonablly, we're happy.
177 */
TEST_F(libc,time)178 TEST_F(libc, time) {
179 int64_t begin = 0;
180 int64_t end = 0;
181 int64_t delta = 0;
182
183 trusty_gettime(0, &begin);
184 trusty_nanosleep(0, 0, 10 * MSEC);
185 trusty_gettime(0, &end);
186 delta = end - begin;
187
188 ASSERT_LT(1 * MSEC, delta);
189 /* We've observed 200 ms sleeps in the emulator, so be generous. */
190 ASSERT_LT(delta, 1000 * MSEC);
191
192 test_abort:;
193 }
194
195 /* Smoke test because we mocked out timezone functions. */
TEST_F(libc,localtime)196 TEST_F(libc, localtime) {
197 time_t time = 0;
198 struct tm* result = localtime(&time);
199 ASSERT_NE(NULL, result);
200
201 /* Epoch. */
202 EXPECT_EQ(70, result->tm_year);
203 EXPECT_EQ(0, result->tm_mon);
204 EXPECT_EQ(1, result->tm_mday);
205 EXPECT_EQ(0, result->tm_hour);
206 EXPECT_EQ(0, result->tm_min);
207 EXPECT_EQ(0, result->tm_sec);
208
209 time += 24 * 60 * 60;
210 result = localtime(&time);
211 ASSERT_NE(NULL, result);
212
213 EXPECT_EQ(70, result->tm_year);
214 EXPECT_EQ(0, result->tm_mon);
215 EXPECT_EQ(2, result->tm_mday);
216 EXPECT_EQ(0, result->tm_hour);
217 EXPECT_EQ(0, result->tm_min);
218 EXPECT_EQ(0, result->tm_sec);
219
220 test_abort:;
221 }
222 #endif
223
TEST_F(libc,snprintf_test)224 TEST_F(libc, snprintf_test) {
225 char buffer[16];
226 ASSERT_EQ(17, snprintf(buffer, sizeof(buffer), "%d %x %s...", 12345, 254,
227 "hello"));
228 ASSERT_EQ(0, strcmp(buffer, "12345 fe hello."));
229
230 test_abort:;
231 }
232
TEST_F(libc,atoi_test)233 TEST_F(libc, atoi_test) {
234 ASSERT_EQ(12345, atoi("12345"));
235 ASSERT_EQ(-67890, atoi("-67890"));
236 /* Note: Out-of-bound values are undefined behavior. */
237
238 test_abort:;
239 }
240
TEST_F(libc,print_test)241 TEST_F(libc, print_test) {
242 /*
243 * Test printing compiles and doesn't crash. Yes, this is a weak test.
244 * A stronger test would be better, but also more complicated. Stay simple,
245 * for now.
246 */
247 printf("Hello, stdout.\n");
248 fprintf(stderr, "Hello, stderr.\n");
249 CHECK_ERRNO(0);
250
251 test_abort:;
252 }
253
254 #if defined(TRUSTY_USERSPACE)
TEST_F(libc,print_float_test)255 TEST_F(libc, print_float_test) {
256 /*
257 * %f should be valid and not cause an error, even if floating point
258 * support is disabled.
259 */
260 printf("num: %f\n", 1.23);
261 CHECK_ERRNO(0);
262
263 test_abort:;
264 }
265 #endif
266
TEST_F(libc,print_errno_test)267 TEST_F(libc, print_errno_test) {
268 /*
269 * %m is not supported, but should not be an error, either.
270 */
271 printf("err: %m\n");
272 CHECK_ERRNO(0);
273
274 test_abort:;
275 }
276
TEST_F(libc,print_bad_test)277 TEST_F(libc, print_bad_test) {
278 printf("[%k]\n");
279 /* TODO: EINVAL */
280 CLEAR_ERRNO();
281
282 test_abort:;
283 }
284
285 /*
286 * Grab the frame pointer in a simple, non-inlined function.
287 * Note this isn't a static function. We're trying to game the optimizer and
288 * ensure it doesn't change the calling convention.
289 */
frame_ptr(void)290 __attribute__((__noinline__)) uintptr_t frame_ptr(void) {
291 return (uintptr_t)__builtin_frame_address(0);
292 }
293
294 #if defined(TRUSTY_USERSPACE)
TEST_F(libc,stack_alignment)295 TEST_F(libc, stack_alignment) {
296 /*
297 * On all the platforms we support, the frame pointer should be aligned to 2
298 * times pointer size. This includes x86_64 because the stack pointer is
299 * implicitly re-aligned after function entry before it becomes the frame
300 * pointer.
301 * Note that this test passing does not guarantee correctness, but it can
302 * catch badness.
303 */
304 const uintptr_t alignment_mask = sizeof(void*) * 2 - 1;
305 ASSERT_EQ(0, frame_ptr() & alignment_mask);
306
307 test_abort:;
308 }
309
TEST_F(libc,stack_cookies)310 TEST_F(libc, stack_cookies) {
311 uint64_t* p = (uint64_t*)getauxval(AT_RANDOM);
312 ASSERT_NE(0, p);
313 ASSERT_EQ(true, 0 != *p || 0 != *(p + 1));
314
315 test_abort:;
316 }
317
318 #if __has_feature(shadow_call_stack)
319 void** guard_region_ptr(void);
320
TEST_F(libc,shadow_call_stack)321 TEST_F(libc, shadow_call_stack) {
322 /*
323 * Leaf functions keep return address in the link register but the call
324 * to guard_region_ptr will not get inlined which makes this a non-leaf
325 * function -> return address of this function goes on the shadow stack
326 */
327 void** guard_region_top = guard_region_ptr();
328 ASSERT_NE(0, guard_region_top);
329
330 /* Get return address from stack */
331 void* ret_addr = __builtin_return_address(0);
332 /*
333 * Guard region top points to next free word so the
334 * shadow copy of the return address is right below
335 */
336 void* shadow_ret_addr = *(guard_region_top - 1);
337 ASSERT_EQ(ret_addr, shadow_ret_addr);
338
339 test_abort:;
340 }
341 #endif /* __has_feature(shadow_call_stack) */
342 #endif
343
344 #define SCNPRINTF_TEST_BUF_LEN 8
TEST_F(libc,scnprintf)345 TEST_F(libc, scnprintf) {
346 char buf[SCNPRINTF_TEST_BUF_LEN];
347 const size_t buf_size = SCNPRINTF_TEST_BUF_LEN - 2;
348
349 buf[0] = 'z';
350 /* We should always return 0 in the case of a zero size */
351 EXPECT_EQ(0, scnprintf(buf, 0, "foo"));
352 /* We should have written nothing to the buffer */
353 EXPECT_EQ('z', buf[0]);
354
355 buf[buf_size] = 'q';
356 /* If we would overflow, we should return chars printed */
357 EXPECT_EQ(buf_size - 1, scnprintf(buf, buf_size, "aaaaaaa"));
358 /* If we would overflow, we should also not have written past end */
359 EXPECT_EQ('q', buf[buf_size]);
360 /* The buffer should still be null terminated */
361 EXPECT_EQ(0, buf[buf_size - 1]);
362
363 /* If we would fit, we should return the same as snprintf */
364 EXPECT_EQ(3, scnprintf(buf, buf_size, "%d\n", 10));
365 /* If it would fit, there should be a null terminator */
366 EXPECT_EQ(buf[3], 0);
367
368 test_abort:;
369 }
370
TEST_F(libc,str_to_uuid)371 TEST_F(libc, str_to_uuid) {
372 const char* valid_str = "b100aae1-c0b3-4b8b-9e25-e69523968f7e";
373 const char* invalid_str;
374 struct uuid res_uuid;
375 struct uuid expected_uuid = {
376 0xb100aae1,
377 0xc0b3,
378 0x4b8b,
379 {0x9e, 0x25, 0xe6, 0x95, 0x23, 0x96, 0x8f, 0x7e}};
380
381 invalid_str = "b100aae1-c0b3-4b8b-9e25-e69523968f7";
382 /* The string must be exactly 36 characters */
383 EXPECT_EQ(-1, str_to_uuid(invalid_str, &res_uuid));
384
385 invalid_str = "b100aae1c0b3-4b8b-9e25-e69523968f7e";
386 /* There must be exactly 5 groups */
387 EXPECT_EQ(-1, str_to_uuid(invalid_str, &res_uuid));
388
389 invalid_str = "b100aa-e1c0b3-4b8b-9e25-e69523968f7e";
390 /* Hyphens must be at specific locations */
391 EXPECT_EQ(-1, str_to_uuid(invalid_str, &res_uuid));
392
393 invalid_str = "g100aae1-c0b3-4b8b-9e25-e69523968f7e";
394 /* The string must contain only hyphens and hex characters */
395 EXPECT_EQ(-1, str_to_uuid(invalid_str, &res_uuid));
396
397 invalid_str = "B100aae1-c0b3-4b8b-9e25-e69523968f7e";
398 /* Hex characters must be lower case */
399 EXPECT_EQ(-1, str_to_uuid(invalid_str, &res_uuid));
400
401 EXPECT_EQ(0, str_to_uuid(valid_str, &res_uuid));
402
403 EXPECT_EQ(0, memcmp(&expected_uuid, &res_uuid, sizeof(struct uuid)));
404 }
405
TEST_F(libc,uuid_to_str)406 TEST_F(libc, uuid_to_str) {
407 const char* expected_str = "b100aae1-c0b3-4b8b-9e25-e69523968f7e";
408 const char* zero_str = "00000000-0000-0000-0000-000000000000";
409 struct uuid zero_uuid = {0};
410 char result_str[UUID_STR_SIZE];
411 struct uuid uuid = {0xb100aae1,
412 0xc0b3,
413 0x4b8b,
414 {0x9e, 0x25, 0xe6, 0x95, 0x23, 0x96, 0x8f, 0x7e}};
415
416 /* Check for correct padding */
417 uuid_to_str(&zero_uuid, result_str);
418 EXPECT_EQ(0, strncmp(zero_str, result_str, UUID_STR_SIZE));
419
420 uuid_to_str(&uuid, result_str);
421 EXPECT_EQ(0, strncmp(expected_str, result_str, UUID_STR_SIZE));
422 }
423
424 #if defined(TRUSTY_USERSPACE)
425 /*
426 * We're linking a prebuilt libgcc / compiler_rt provided by the toolchain.
427 * It wasn't designed for Trusty, so does it actually work? If we set things up
428 * wrong there may be ABI issues. One way to smoke these issues out is call
429 * functions that take floating point arguments. However - libgcc does not
430 * provide a full set of functions for every arch, only the ones it expects to
431 * use. This means we need to do some arch-specific testing.
432 */
433
434 #ifdef __arm__
435 extern double __extendsfdf2(float a);
436 extern float __truncdfsf2(double a);
437
TEST_F(libc,float_builtins)438 TEST_F(libc, float_builtins) {
439 EXPECT_EQ(123, (int)__truncdfsf2(__extendsfdf2(123.0f)));
440 }
441 #endif
442
443 #ifdef __aarch64__
444 extern long double __extendsftf2(float a);
445 extern float __trunctfsf2(long double a);
446
TEST_F(libc,float_builtins)447 TEST_F(libc, float_builtins) {
448 EXPECT_EQ(123, (int)__trunctfsf2(__extendsftf2(123.0f)));
449 }
450 #endif
451
452 /*
453 * We provide a mock implementation of stdin because libcxx refers to it.
454 * Make sure the mock behaves in a reasonable manner.
455 */
TEST_F(libc,getc)456 TEST_F(libc, getc) {
457 EXPECT_EQ(EOF, getc(stdin));
458
459 test_abort:;
460 }
461 #endif
462
463 #if __ARM_NEON__ || __ARM_NEON
464
465 #include <arm_neon.h>
466
467 /*
468 * NOTE this is a fairly weak test that checks if a neon instruction can be
469 * executed. This will help detect cases where the build flags do not match the
470 * actual system the code is running on.
471 */
TEST_F(libc,basic_neon)472 TEST_F(libc, basic_neon) {
473 int8x16_t block1 = vdupq_n_u8(0x55);
474 int8x16_t block2 = vdupq_n_u8(0x33);
475 int8x16_t expected;
476 int8x16_t result;
477
478 /* memset just to be sure. */
479 memset(&expected, 0x66, sizeof(int8x16_t));
480
481 result = veorq_s8(block1, block2);
482 ASSERT_EQ(0, memcmp(&expected, &result, sizeof(int8x16_t)));
483
484 test_abort:;
485 }
486
487 #endif
488
489 #if defined(TRUSTY_USERSPACE)
TEST_F(libc,sbrk)490 TEST_F(libc, sbrk) {
491 /* Allocating and releasing a small range should succeed */
492 const ssize_t brk_test_size = 64;
493 void* orig_brk = sbrk(brk_test_size);
494 ASSERT_NE(orig_brk, (void*)-1);
495 void* test_brk = sbrk(0);
496 ASSERT_EQ(sbrk(-brk_test_size), test_brk);
497 ASSERT_EQ(orig_brk, sbrk(0));
498
499 /* Allocating an oversized range should fail */
500 ASSERT_EQ(sbrk(10 * 4096), (void*)-1);
501 ASSERT_EQ(errno, ENOMEM);
502
503 test_abort:
504 CLEAR_ERRNO();
505 }
506 #endif
507
TEST_F(libc,SnprintfLargePointerTest)508 TEST_F(libc, SnprintfLargePointerTest) {
509 char buffer[BUFFER_SIZE];
510
511 snprintf(buffer, BUFFER_SIZE, "pointer: %p", (void*)0x5000);
512
513 EXPECT_STREQ(buffer, "pointer: 0x5000");
514 }
515
TEST_F(libc,SmallIntegerPrintTest)516 TEST_F(libc, SmallIntegerPrintTest) {
517 char buffer[BUFFER_SIZE];
518
519 snprintf_filtered(buffer, BUFFER_SIZE, "%d", 100);
520 EXPECT_STREQ(buffer, "100");
521 }
522
TEST_F(libc,NullPointerPrintTest)523 TEST_F(libc, NullPointerPrintTest) {
524 char buffer[BUFFER_SIZE];
525
526 snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)0);
527 #if defined(TRUSTY_USERSPACE)
528 EXPECT_STREQ(buffer, "pointer: 0");
529 #else
530 EXPECT_STREQ(buffer, "pointer: 0x0");
531 #endif
532 }
533
TEST_F(libc,SmallPointerPrintTest)534 TEST_F(libc, SmallPointerPrintTest) {
535 char buffer[BUFFER_SIZE];
536
537 snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)0x1000);
538 EXPECT_STREQ(buffer, "pointer: 0x1000");
539 }
540
TEST_F(libc,SmallPseudoNegativePointerPrintTest)541 TEST_F(libc, SmallPseudoNegativePointerPrintTest) {
542 char buffer[BUFFER_SIZE];
543
544 snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)-4096);
545 if (sizeof(void*) == 4) {
546 EXPECT_STREQ(buffer, "pointer: 0xfffff000");
547 } else {
548 EXPECT_STREQ(buffer, "pointer: 0xfffffffffffff000");
549 }
550 }
551
TEST_F(libc,BiggerPseudoNegativePointerPrintTest)552 TEST_F(libc, BiggerPseudoNegativePointerPrintTest) {
553 char buffer[BUFFER_SIZE];
554
555 snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)-4097);
556 if (sizeof(void*) == 4) {
557 EXPECT_STREQ_COND(buffer, "pointer: 0x***", "pointer: 0xffffefff",
558 RELEASE_BUILD);
559 } else {
560 EXPECT_STREQ_COND(buffer, "pointer: 0x***",
561 "pointer: 0xffffffffffffefff", RELEASE_BUILD);
562 }
563 }
564
TEST_F(libc,SmallestPseudoNegativePointerPrintTest)565 TEST_F(libc, SmallestPseudoNegativePointerPrintTest) {
566 char buffer[BUFFER_SIZE];
567
568 snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)-1);
569
570 if (sizeof(void*) == 4) {
571 EXPECT_STREQ(buffer, "pointer: 0xffffffff");
572 } else {
573 EXPECT_STREQ(buffer, "pointer: 0xffffffffffffffff");
574 }
575 }
576
TEST_F(libc,PointerPrintTest)577 TEST_F(libc, PointerPrintTest) {
578 char buffer[BUFFER_SIZE];
579
580 snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)0x5000);
581 EXPECT_STREQ_COND(buffer, "pointer: 0x***", "pointer: 0x5000",
582 RELEASE_BUILD);
583 }
584
TEST_F(libc,PointerSprintfTest)585 TEST_F(libc, PointerSprintfTest) {
586 char buffer[BUFFER_SIZE];
587
588 sprintf(buffer, "pointer: %p", (void*)0x5000);
589 EXPECT_STREQ(buffer, "pointer: 0x5000");
590 }
591
TEST_F(libc,PointerSnprintfTest)592 TEST_F(libc, PointerSnprintfTest) {
593 char buffer[BUFFER_SIZE];
594
595 snprintf(buffer, BUFFER_SIZE, "pointer: %p", (void*)0x5000);
596 EXPECT_STREQ(buffer, "pointer: 0x5000");
597 }
598
TEST_F(libc,LargerIntTest)599 TEST_F(libc, LargerIntTest) {
600 char buffer[BUFFER_SIZE];
601
602 snprintf_filtered(buffer, BUFFER_SIZE, "integer: %d", 4097);
603 EXPECT_STREQ_COND(buffer, "integer: ***", "integer: 4097", RELEASE_BUILD);
604 }
605
TEST_F(libc,LargerNegIntTest)606 TEST_F(libc, LargerNegIntTest) {
607 char buffer[BUFFER_SIZE];
608
609 snprintf_filtered(buffer, BUFFER_SIZE, "integer: %d", -4097);
610 EXPECT_STREQ_COND(buffer, "integer: ***", "integer: -4097", RELEASE_BUILD);
611 }
612
TEST_F(libc,PointerAndUnsignedOneLineOneBigOneSmall)613 TEST_F(libc, PointerAndUnsignedOneLineOneBigOneSmall) {
614 char buffer[BUFFER_SIZE];
615
616 snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u", 0x5000,
617 100);
618 EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: 100",
619 "pointer1: 0x5000 number: 100", RELEASE_BUILD);
620 }
621
TEST_F(libc,PointerAndUnsignedOneLineOneBigOneSmallInverse)622 TEST_F(libc, PointerAndUnsignedOneLineOneBigOneSmallInverse) {
623 char buffer[BUFFER_SIZE];
624
625 snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u", 0x500,
626 10000);
627 EXPECT_STREQ_COND(buffer, "pointer1: 0x500 number: ***",
628 "pointer1: 0x500 number: 10000", RELEASE_BUILD);
629 }
630
TEST_F(libc,OnePointersTwoIntsOneLineOneSmallTwoBig)631 TEST_F(libc, OnePointersTwoIntsOneLineOneSmallTwoBig) {
632 char buffer[BUFFER_SIZE];
633
634 snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u hex: %x",
635 0x5, 10000, 0X70);
636 EXPECT_STREQ_COND(buffer, "pointer1: 0x5 number: *** hex: 70",
637 "pointer1: 0x5 number: 10000 hex: 70", RELEASE_BUILD);
638 }
639
TEST_F(libc,OnePointersTwoIntsOneLineOneSmallTwoBigInverse)640 TEST_F(libc, OnePointersTwoIntsOneLineOneSmallTwoBigInverse) {
641 char buffer[BUFFER_SIZE];
642
643 snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u hex: %x",
644 0x5000, 10, 0X7000);
645 EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: 10 hex: ***",
646 "pointer1: 0x5000 number: 10 hex: 7000", RELEASE_BUILD);
647 }
648
TEST_F(libc,SmallIntTest)649 TEST_F(libc, SmallIntTest) {
650 char buffer[BUFFER_SIZE];
651
652 snprintf_filtered(buffer, BUFFER_SIZE, "integer: %d", 4096);
653 EXPECT_STREQ(buffer, "integer: 4096");
654 }
655
TEST_F(libc,SmallNegIntTest)656 TEST_F(libc, SmallNegIntTest) {
657 char buffer[BUFFER_SIZE];
658
659 snprintf_filtered(buffer, BUFFER_SIZE, "integer: %d", -4096);
660 EXPECT_STREQ(buffer, "integer: -4096");
661 }
662
TEST_F(libc,LargerUintTest)663 TEST_F(libc, LargerUintTest) {
664 char buffer[BUFFER_SIZE];
665
666 snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: %u", 4097);
667 EXPECT_STREQ_COND(buffer, "unsigned integer: ***", "unsigned integer: 4097",
668 RELEASE_BUILD);
669 }
670
TEST_F(libc,LargerHexTest)671 TEST_F(libc, LargerHexTest) {
672 char buffer[BUFFER_SIZE];
673
674 snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: 0x%x", 0x1001);
675 EXPECT_STREQ_COND(buffer, "unsigned integer: 0x***",
676 "unsigned integer: 0x1001", RELEASE_BUILD);
677 }
678
TEST_F(libc,PrintfBufferLargeEnough)679 TEST_F(libc, PrintfBufferLargeEnough) {
680 char buffer[BUFFER_SIZE];
681 buffer[5] = '@';
682
683 snprintf_filtered(buffer, 5, "%x", 0x3000);
684 EXPECT_STREQ_COND(buffer, "***", "3000", RELEASE_BUILD);
685 EXPECT_EQ(buffer[5], '@');
686 }
687
TEST_F(libc,PrintfBufferLargeEnoughForRelease)688 TEST_F(libc, PrintfBufferLargeEnoughForRelease) {
689 char buffer[BUFFER_SIZE];
690 buffer[4] = '@';
691
692 snprintf_filtered(buffer, 4, "%x", 0x3000);
693 EXPECT_STREQ_COND(buffer, "***", "300", RELEASE_BUILD);
694 EXPECT_EQ(buffer[4], '@');
695 }
696
TEST_F(libc,PrintfBufferTooSmallForRelease)697 TEST_F(libc, PrintfBufferTooSmallForRelease) {
698 char buffer[BUFFER_SIZE];
699 buffer[3] = '@';
700
701 snprintf_filtered(buffer, 3, "%x", 0x3000);
702 EXPECT_STREQ_COND(buffer, "**", "30", RELEASE_BUILD);
703 EXPECT_EQ(buffer[3], '@');
704 }
705
TEST_F(libc,SmallHexTest)706 TEST_F(libc, SmallHexTest) {
707 char buffer[BUFFER_SIZE];
708
709 snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: 0x%x", 0x1000);
710 EXPECT_STREQ(buffer, "unsigned integer: 0x1000");
711 }
712
TEST_F(libc,PointerAndUnsignedOneLine)713 TEST_F(libc, PointerAndUnsignedOneLine) {
714 char buffer[BUFFER_SIZE];
715
716 snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u", 0x5000,
717 10000);
718 EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: ***",
719 "pointer1: 0x5000 number: 10000", RELEASE_BUILD);
720 }
721
TEST_F(libc,PointerUnsignedOneLineFilterOne)722 TEST_F(libc, PointerUnsignedOneLineFilterOne) {
723 char buffer[BUFFER_SIZE];
724
725 snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %px number: %u", 0x5000,
726 10000);
727 EXPECT_STREQ_COND(buffer, "pointer1: 0x5000 number: ***",
728 "pointer1: 0x5000 number: 10000", RELEASE_BUILD);
729 }
730
TEST_F(libc,PointerUnsignedOneLineFilterOneInverse)731 TEST_F(libc, PointerUnsignedOneLineFilterOneInverse) {
732 char buffer[BUFFER_SIZE];
733
734 snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %ux", 0x5000,
735 10000);
736 EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: 10000",
737 "pointer1: 0x5000 number: 10000", RELEASE_BUILD);
738 }
739
TEST_F(libc,PointerUnsignedHexOneLineFilterOne)740 TEST_F(libc, PointerUnsignedHexOneLineFilterOne) {
741 char buffer[BUFFER_SIZE];
742
743 snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %px number: %u hex: %xx",
744 0x5000, 10000, 0X7000);
745 EXPECT_STREQ_COND(buffer, "pointer1: 0x5000 number: *** hex: 7000",
746 "pointer1: 0x5000 number: 10000 hex: 7000",
747 RELEASE_BUILD);
748 }
749
TEST_F(libc,PointerUnsignedHexOneLineFilterOneInverse)750 TEST_F(libc, PointerUnsignedHexOneLineFilterOneInverse) {
751 char buffer[BUFFER_SIZE];
752
753 snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %ux hex: %x",
754 0x5000, 10000, 0X7000);
755 EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: 10000 hex: ***",
756 "pointer1: 0x5000 number: 10000 hex: 7000",
757 RELEASE_BUILD);
758 }
759
TEST_F(libc,ReleaseUnfilteredPointerPrintTest)760 TEST_F(libc, ReleaseUnfilteredPointerPrintTest) {
761 char buffer[BUFFER_SIZE];
762
763 snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %px", (void*)0x5000);
764 EXPECT_STREQ(buffer, "pointer: 0x5000");
765 }
766
TEST_F(libc,ReleaseUnfilteredLargNegIntTest)767 TEST_F(libc, ReleaseUnfilteredLargNegIntTest) {
768 char buffer[BUFFER_SIZE];
769
770 snprintf_filtered(buffer, BUFFER_SIZE, "integer: %dx", -4097);
771 EXPECT_STREQ(buffer, "integer: -4097");
772 }
773
TEST_F(libc,ReleaseUnfilteredLargerHexTest)774 TEST_F(libc, ReleaseUnfilteredLargerHexTest) {
775 char buffer[BUFFER_SIZE];
776
777 snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: 0x%xx", 0x1001);
778 EXPECT_STREQ(buffer, "unsigned integer: 0x1001");
779 }
780
TEST_F(libc,ReleaseUnfilteredLargerUintTest)781 TEST_F(libc, ReleaseUnfilteredLargerUintTest) {
782 char buffer[BUFFER_SIZE];
783
784 snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: %ux", 4097);
785 EXPECT_STREQ(buffer, "unsigned integer: 4097");
786 }
787
TEST_F(libc,ReleaseUnfilteredLargerUintXAtEndTest)788 TEST_F(libc, ReleaseUnfilteredLargerUintXAtEndTest) {
789 char buffer[BUFFER_SIZE];
790
791 snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: %uxx", 34127);
792 EXPECT_STREQ(buffer, "unsigned integer: 34127x");
793 }
794
TEST_F(libc,ReleaseUnfilteredPrintfBufferLargeEnoughTest)795 TEST_F(libc, ReleaseUnfilteredPrintfBufferLargeEnoughTest) {
796 char buffer[BUFFER_SIZE];
797 memset(buffer, 0, BUFFER_SIZE);
798 buffer[5] = '@';
799
800 snprintf_filtered(buffer, 5, "%xx", 0x3000);
801 EXPECT_STREQ(buffer, "3000");
802 EXPECT_EQ(buffer[5], '@');
803 }
804
TEST_F(libc,ReleaseUnfilteredPrintfBufferLargeEnoughForReleaseTest)805 TEST_F(libc, ReleaseUnfilteredPrintfBufferLargeEnoughForReleaseTest) {
806 char buffer[BUFFER_SIZE];
807 memset(buffer, 0, BUFFER_SIZE);
808 buffer[4] = '@';
809
810 snprintf_filtered(buffer, 4, "%xx", 0x3000);
811 EXPECT_STREQ(buffer, "300");
812 EXPECT_EQ(buffer[4], '@');
813 }
814
TEST_F(libc,ReleaseUnfilteredPrintfBufferTooSmallForReleaseTest)815 TEST_F(libc, ReleaseUnfilteredPrintfBufferTooSmallForReleaseTest) {
816 char buffer[BUFFER_SIZE];
817 memset(buffer, 0, BUFFER_SIZE);
818 buffer[3] = '@';
819
820 snprintf_filtered(buffer, 3, "%xx", 0x3000);
821 EXPECT_STREQ(buffer, "30");
822 EXPECT_EQ(buffer[3], '@');
823 }
824
TEST_F(libc,ReleaseUnfilteredPrintfStringXPrintsTest)825 TEST_F(libc, ReleaseUnfilteredPrintfStringXPrintsTest) {
826 char buffer[BUFFER_SIZE];
827
828 snprintf_filtered(buffer, BUFFER_SIZE, "%sx", "hello");
829 EXPECT_STREQ(buffer, "hellox");
830 }
831
TEST_F(libc,ThreeModifierTogetherOneNotFilteredTest)832 TEST_F(libc, ThreeModifierTogetherOneNotFilteredTest) {
833 char buffer[BUFFER_SIZE];
834
835 snprintf_filtered(buffer, BUFFER_SIZE, "%d%xx%u", 98765, 0x43210, 123456);
836 EXPECT_STREQ_COND(buffer, "***43210***", "9876543210123456", RELEASE_BUILD);
837 }
838
TEST_F(libc,ThreeModifierTogetherOneNotFilteredInverseTest)839 TEST_F(libc, ThreeModifierTogetherOneNotFilteredInverseTest) {
840 char buffer[BUFFER_SIZE];
841
842 snprintf_filtered(buffer, BUFFER_SIZE, "%dx%x%ux", 98765, 0x43210, 123456);
843 EXPECT_STREQ_COND(buffer, "98765***123456", "9876543210123456",
844 RELEASE_BUILD);
845 }
846
TEST_F(libc,ReleaseUnfilteredThreeModifiersTest)847 TEST_F(libc, ReleaseUnfilteredThreeModifiersTest) {
848 char buffer[BUFFER_SIZE];
849
850 snprintf_filtered(buffer, BUFFER_SIZE,
851 "pointer: %px unsigned: %ux signed: %dx", (void*)0x5000,
852 7000, 80000);
853 EXPECT_STREQ(buffer, "pointer: 0x5000 unsigned: 7000 signed: 80000");
854 }
855
TEST_F(libc,SnprintfModifierNotUsedTest)856 TEST_F(libc, SnprintfModifierNotUsedTest) {
857 char buffer[BUFFER_SIZE];
858
859 snprintf(buffer, BUFFER_SIZE,
860 "hex: %xx pointer: %px unsigned: %ux signed: %dx", 2, (void*)3, 4,
861 5);
862
863 EXPECT_STREQ(buffer, "hex: 2x pointer: 0x3x unsigned: 4x signed: 5x");
864 }
865
TEST_F(libc,UnsignedOverflowMacros)866 TEST_F(libc, UnsignedOverflowMacros) {
867 for (int i = 0; i < 0x100; i++) {
868 // When the macros defined in ctype.h are used for these functions, they
869 // trigger UBSAN for a subset of the inputs. Otherwise the function
870 // calls are likely optimized out since the results aren't used.
871 (void)isalpha(i);
872 (void)isdigit(i);
873 (void)islower(i);
874 (void)isupper(i);
875 (void)isprint(i);
876 (void)isgraph(i);
877 (void)isspace(i);
878 }
879 }
880
881 #if defined(TRUSTY_USERSPACE)
882
883 #define TEST_BUF_SIZE 64
884
TEST_F(libc,PrepareDmaFailsOnMultipleCalls)885 TEST_F(libc, PrepareDmaFailsOnMultipleCalls) {
886 uint8_t buf[TEST_BUF_SIZE] = {0};
887 struct dma_pmem dma;
888
889 int rc = prepare_dma(buf, TEST_BUF_SIZE, DMA_FLAG_TO_DEVICE, &dma);
890 EXPECT_GE(rc, 1);
891
892 /* Second prepare should fail */
893 rc = prepare_dma(buf, TEST_BUF_SIZE, DMA_FLAG_TO_DEVICE, &dma);
894 EXPECT_EQ(ERR_INVALID_ARGS, rc);
895
896 rc = finish_dma(buf, TEST_BUF_SIZE, DMA_FLAG_TO_DEVICE);
897 EXPECT_EQ(NO_ERROR, rc);
898 }
899
TEST_F(libc,PrepareInputOutputDmaDifferentBufs)900 TEST_F(libc, PrepareInputOutputDmaDifferentBufs) {
901 uint8_t buf_in[TEST_BUF_SIZE] = {0};
902 uint8_t buf_out[TEST_BUF_SIZE] = {0};
903 struct dma_pmem dma_in;
904 struct dma_pmem dma_out;
905
906 int rc = prepare_input_output_dma(buf_in, TEST_BUF_SIZE, buf_out,
907 TEST_BUF_SIZE, &dma_in, &dma_out);
908 EXPECT_EQ(NO_ERROR, rc);
909
910 /* Two areas should have been tracked */
911 rc = finish_dma(buf_in, TEST_BUF_SIZE, DMA_FLAG_TO_DEVICE);
912 EXPECT_EQ(NO_ERROR, rc);
913 rc = finish_dma(buf_out, TEST_BUF_SIZE, DMA_FLAG_FROM_DEVICE);
914 EXPECT_EQ(NO_ERROR, rc);
915 }
916
TEST_F(libc,PrepareWithDifferentBufSizes)917 TEST_F(libc, PrepareWithDifferentBufSizes) {
918 uint8_t buf[TEST_BUF_SIZE] = {0};
919 struct dma_pmem dma_in;
920 struct dma_pmem dma_out;
921
922 int rc = prepare_input_output_dma(buf, TEST_BUF_SIZE, buf,
923 TEST_BUF_SIZE / 2, &dma_in, &dma_out);
924 EXPECT_EQ(ERR_INVALID_ARGS, rc);
925 }
926
TEST_F(libc,PrepareInputOutputDmaSameBufs)927 TEST_F(libc, PrepareInputOutputDmaSameBufs) {
928 uint8_t buf_in[TEST_BUF_SIZE] = {0};
929 uint8_t* buf_out = buf_in;
930 struct dma_pmem dma_in;
931 struct dma_pmem dma_out;
932
933 int rc = prepare_input_output_dma(buf_in, TEST_BUF_SIZE, buf_out,
934 TEST_BUF_SIZE, &dma_in, &dma_out);
935 EXPECT_EQ(NO_ERROR, rc);
936
937 /* One area should have been tracked */
938 rc = finish_dma(buf_in, TEST_BUF_SIZE, DMA_FLAG_BIDIRECTION);
939 EXPECT_EQ(NO_ERROR, rc);
940 }
941
TEST_F(libc,FinishInputOutputDmaDifferentBufs)942 TEST_F(libc, FinishInputOutputDmaDifferentBufs) {
943 uint8_t buf_in[TEST_BUF_SIZE] = {0};
944 uint8_t buf_out[TEST_BUF_SIZE] = {0};
945 struct dma_pmem dma_in;
946 struct dma_pmem dma_out;
947
948 int rc = prepare_dma(buf_in, TEST_BUF_SIZE, DMA_FLAG_TO_DEVICE, &dma_in);
949 EXPECT_GE(rc, 1);
950 rc = prepare_dma(buf_out, TEST_BUF_SIZE, DMA_FLAG_TO_DEVICE, &dma_out);
951 EXPECT_GE(rc, 1);
952
953 rc = finish_input_output_dma(buf_in, TEST_BUF_SIZE, buf_out, TEST_BUF_SIZE);
954 EXPECT_EQ(NO_ERROR, rc);
955
956 /* DMAs should already be finished, finish should return ERR_NOT_FOUND */
957 rc = finish_dma(buf_in, TEST_BUF_SIZE, DMA_FLAG_TO_DEVICE);
958 EXPECT_EQ(ERR_NOT_FOUND, rc);
959 rc = finish_dma(buf_out, TEST_BUF_SIZE, DMA_FLAG_FROM_DEVICE);
960 EXPECT_EQ(ERR_NOT_FOUND, rc);
961 }
962
TEST_F(libc,FinishInputOutputSameDifferentBufs)963 TEST_F(libc, FinishInputOutputSameDifferentBufs) {
964 uint8_t buf_in[TEST_BUF_SIZE] = {0};
965 uint8_t* buf_out = buf_in;
966 struct dma_pmem dma_in;
967
968 int rc = prepare_dma(buf_in, TEST_BUF_SIZE, DMA_FLAG_BIDIRECTION, &dma_in);
969 EXPECT_GE(rc, 1);
970
971 rc = finish_input_output_dma(buf_in, TEST_BUF_SIZE, buf_out, TEST_BUF_SIZE);
972 EXPECT_EQ(NO_ERROR, rc);
973
974 /* DMAs should already be finished, finish should return ERR_NOT_FOUND */
975 rc = finish_dma(buf_in, TEST_BUF_SIZE, DMA_FLAG_BIDIRECTION);
976 EXPECT_EQ(ERR_NOT_FOUND, rc);
977 }
978 #endif
979
980 #if defined(TRUSTY_USERSPACE)
981 PORT_TEST(libc, "com.android.libctest");
982 #else
983 PORT_TEST(libc, "com.android.kernel.libctest");
984 #endif
985