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