xref: /optee_os/core/pta/tests/misc.c (revision 5b25c76ac40f830867e3d60800120ffd7874e8dc)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  */
5 #include <assert.h>
6 #include <malloc.h>
7 #include <stdbool.h>
8 #include <trace.h>
9 #include <kernel/panic.h>
10 #include <util.h>
11 
12 #include "misc.h"
13 
14 /*
15  * Enable expect LOG macro to enable/disable self tests traces.
16  *
17  * #define LOG     DMSG_RAW
18  * #define LOG(...)
19  */
20 #define LOG(...)
21 
22 static int self_test_add_overflow(void)
23 {
24 	uint32_t r_u32;
25 	int32_t r_s32;
26 	uintmax_t r_um;
27 	intmax_t r_sm;
28 
29 	if (ADD_OVERFLOW(8U, 0U, &r_s32))
30 		return -1;
31 	if (r_s32 != 8)
32 		return -1;
33 	if (ADD_OVERFLOW(32U, 30U, &r_u32))
34 		return -1;
35 	if (r_u32 != 62)
36 		return -1;
37 	if (!ADD_OVERFLOW(UINT32_MAX, UINT32_MAX, &r_u32))
38 		return -1;
39 	if (!ADD_OVERFLOW(UINT32_MAX / 2 + 1, UINT32_MAX / 2 + 1, &r_u32))
40 		return -1;
41 	if (ADD_OVERFLOW(UINT32_MAX / 2, UINT32_MAX / 2 + 1, &r_u32))
42 		return -1;
43 	if (r_u32 != UINT32_MAX)
44 		return -1;
45 
46 	if (ADD_OVERFLOW((uint32_t)30, (int32_t)-31, &r_s32))
47 		return -1;
48 	if (r_s32 != -1)
49 		return -1;
50 	if (ADD_OVERFLOW((int32_t)30, (int32_t)-31, &r_s32))
51 		return -1;
52 	if (r_s32 != -1)
53 		return -1;
54 	if (ADD_OVERFLOW((int32_t)-31, (uint32_t)30, &r_s32))
55 		return -1;
56 	if (r_s32 != -1)
57 		return -1;
58 
59 	if (ADD_OVERFLOW(INT32_MIN + 1, -1, &r_s32))
60 		return -1;
61 	if (r_s32 != INT32_MIN)
62 		return -1;
63 	if (!ADD_OVERFLOW(INT32_MIN, -1, &r_s32))
64 		return -1;
65 	if (!ADD_OVERFLOW(INT32_MIN + 1, -2, &r_s32))
66 		return -1;
67 	if (!ADD_OVERFLOW(INT32_MAX, INT32_MAX, &r_s32))
68 		return -1;
69 	if (ADD_OVERFLOW(INT32_MAX, INT32_MAX, &r_u32))
70 		return -1;
71 	if (!ADD_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r_sm))
72 		return -1;
73 	if (ADD_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r_um))
74 		return -1;
75 	if (!ADD_OVERFLOW(INT32_MAX / 2 + 1, INT32_MAX / 2 + 1, &r_s32))
76 		return -1;
77 	if (ADD_OVERFLOW(INT32_MAX / 2, INT32_MAX / 2 + 1, &r_s32))
78 		return -1;
79 	if (r_s32 != INT32_MAX)
80 		return -1;
81 
82 	return 0;
83 }
84 
85 static int self_test_sub_overflow(void)
86 {
87 	uint32_t r_u32;
88 	int32_t r_s32;
89 	intmax_t r_sm;
90 
91 	if (SUB_OVERFLOW(8U, 1U, &r_s32))
92 		return -1;
93 	if (r_s32 != 7)
94 		return -1;
95 	if (SUB_OVERFLOW(32U, 30U, &r_u32))
96 		return -1;
97 	if (r_u32 != 2)
98 		return -1;
99 	if (!SUB_OVERFLOW(30U, 31U, &r_u32))
100 		return -1;
101 
102 	if (SUB_OVERFLOW(30, 31, &r_s32))
103 		return -1;
104 	if (r_s32 != -1)
105 		return -1;
106 	if (SUB_OVERFLOW(-1, INT32_MAX, &r_s32))
107 		return -1;
108 	if (r_s32 != INT32_MIN)
109 		return -1;
110 	if (!SUB_OVERFLOW(-2, INT32_MAX, &r_s32))
111 		return -1;
112 
113 	if (SUB_OVERFLOW((uint32_t)30, (int32_t)-31, &r_s32))
114 		return -1;
115 	if (r_s32 != 61)
116 		return -1;
117 	if (SUB_OVERFLOW((int32_t)30, (int32_t)-31, &r_s32))
118 		return -1;
119 	if (r_s32 != 61)
120 		return -1;
121 	if (SUB_OVERFLOW((int32_t)-31, (uint32_t)30, &r_s32))
122 		return -1;
123 	if (r_s32 != -61)
124 		return -1;
125 	if (SUB_OVERFLOW((int32_t)-31, (int32_t)-30, &r_s32))
126 		return -1;
127 	if (r_s32 != -1)
128 		return -1;
129 
130 	if (SUB_OVERFLOW((int32_t)31, -(INTMAX_MIN + 1), &r_sm))
131 		return -1;
132 	if (r_sm != (INTMAX_MIN + 32))
133 		return -1;
134 
135 	return 0;
136 }
137 
138 static int self_test_mul_unsigned_overflow(void)
139 {
140 	const size_t um_half_shift = sizeof(uintmax_t) * 8 / 2;
141 	const uintmax_t um_half_mask = UINTMAX_MAX >> um_half_shift;
142 	uint32_t r_u32;
143 	uintmax_t r_um;
144 
145 	if (MUL_OVERFLOW(32, 30, &r_u32))
146 		return -1;
147 	if (r_u32 != 960)
148 		return -1;
149 	if (MUL_OVERFLOW(-32, -30, &r_u32))
150 		return -1;
151 	if (r_u32 != 960)
152 		return -1;
153 
154 	if (MUL_OVERFLOW(UINTMAX_MAX, 1, &r_um))
155 		return -1;
156 	if (r_um != UINTMAX_MAX)
157 		return -1;
158 	if (MUL_OVERFLOW(UINTMAX_MAX / 4, 4, &r_um))
159 		return -1;
160 	if (r_um != (UINTMAX_MAX - 3))
161 		return -1;
162 	if (!MUL_OVERFLOW(UINTMAX_MAX / 4 + 1, 4, &r_um))
163 		return -1;
164 	if (!MUL_OVERFLOW(UINTMAX_MAX, UINTMAX_MAX, &r_um))
165 		return -1;
166 	if (!MUL_OVERFLOW(um_half_mask << um_half_shift,
167 			  um_half_mask << um_half_shift, &r_um))
168 		return -1;
169 
170 	return 0;
171 }
172 
173 static int self_test_mul_signed_overflow(void)
174 {
175 	intmax_t r;
176 
177 	if (MUL_OVERFLOW(32, -30, &r))
178 		return -1;
179 	if (r != -960)
180 		return -1;
181 	if (MUL_OVERFLOW(-32, 30, &r))
182 		return -1;
183 	if (r != -960)
184 		return -1;
185 	if (MUL_OVERFLOW(32, 30, &r))
186 		return -1;
187 	if (r != 960)
188 		return -1;
189 
190 	if (MUL_OVERFLOW(INTMAX_MAX, 1, &r))
191 		return -1;
192 	if (r != INTMAX_MAX)
193 		return -1;
194 	if (MUL_OVERFLOW(INTMAX_MAX / 4, 4, &r))
195 		return -1;
196 	if (r != (INTMAX_MAX - 3))
197 		return -1;
198 	if (!MUL_OVERFLOW(INTMAX_MAX / 4 + 1, 4, &r))
199 		return -1;
200 	if (!MUL_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r))
201 		return -1;
202 	if (MUL_OVERFLOW(INTMAX_MIN + 1, 1, &r))
203 		return -1;
204 	if (r != INTMAX_MIN + 1)
205 		return -1;
206 	if (MUL_OVERFLOW(1, INTMAX_MIN + 1, &r))
207 		return -1;
208 	if (r != INTMAX_MIN + 1)
209 		return -1;
210 	if (MUL_OVERFLOW(0, INTMAX_MIN, &r))
211 		return -1;
212 	if (r != 0)
213 		return -1;
214 	if (MUL_OVERFLOW(1, INTMAX_MIN, &r))
215 		return -1;
216 	if (r != INTMAX_MIN)
217 		return -1;
218 
219 	return 0;
220 }
221 
222 /* test division support. resulting trace shall be manually checked */
223 static int self_test_division(void)
224 {
225 	signed a, b, c, d;
226 	bool r;
227 	int ret = 0;
228 
229 	LOG("");
230 	LOG("division tests (division and modulo):");
231 	/* get some unpredicted values to prevent compilation optimizations: */
232 	/* => use the stack address */
233 
234 	LOG("- test with unsigned small integers:");
235 	a = (signed)((unsigned)(vaddr_t)&a & 0xFFFFF);
236 	b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1;
237 	c = a / b;
238 	d = a % b;
239 	r = ((b * c + d) == a);
240 	if (!r)
241 		ret = -1;
242 	LOG("  0x%08x / 0x%08x = %u / %u = %u = 0x%x)",
243 	    (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c,
244 	    (unsigned)c);
245 	LOG("  0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a,
246 	    (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d);
247 	LOG("  check results => %s", r ? "ok" : "FAILED !!!");
248 	LOG("");
249 
250 	LOG("- test with signed small integers, negative numerator:");
251 	a = (signed)(vaddr_t)&a;
252 	b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) - 1;
253 	c = a / b;
254 	d = a % b;
255 	r = ((b * c + d) == a);
256 	if (!r)
257 		ret = -1;
258 	LOG("  0x%08x / 0x%08x = %d / %d = %d = 0x%x)",
259 	    (unsigned)a, (unsigned)b, (signed)a, (signed)b, (signed)c,
260 	    (unsigned)c);
261 	LOG("  0x%08x %% 0x%08x = %d %% %d = %d = 0x%x)", (unsigned)a,
262 	    (unsigned)b, (signed)a, (signed)b, (signed)d, (unsigned)d);
263 	LOG("  check results => %s", r ? "ok" : "FAILED !!!");
264 	LOG("");
265 
266 	LOG("- test with signed small integers, negative denominator:");
267 	a = (signed)((unsigned)(vaddr_t)&a & 0xFFFFF);
268 	b = -(signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1;
269 	c = a / b;
270 	d = a % b;
271 
272 	LOG("- test with unsigned integers, big numerator (> 0x80000000):");
273 	a = (signed)(vaddr_t)&a;
274 	b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1;
275 	c = (signed)((unsigned)a / (unsigned)b);
276 	d = (signed)((unsigned)a % (unsigned)b);
277 	r = (((unsigned)b * (unsigned)c + (unsigned)d) == (unsigned)a);
278 	if (!r)
279 		ret = -1;
280 	LOG("  0x%08x / 0x%08x = %u / %u = %u = 0x%x)",
281 	    (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c,
282 	    (unsigned)c);
283 	LOG("  0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a,
284 	    (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d);
285 	LOG("  check results => %s", r ? "ok" : "FAILED !!!");
286 	LOG("");
287 
288 	LOG("- test with unsigned integers, big num. & denom. (> 0x80000000):");
289 	a = (signed)(vaddr_t)&a;
290 	b = (signed)((unsigned)(vaddr_t)&a - 1);
291 	c = (signed)((unsigned)a / (unsigned)b);
292 	d = (signed)((unsigned)a % (unsigned)b);
293 	r = (((unsigned)b * (unsigned)c + (unsigned)d) == (unsigned)a);
294 	if (!r)
295 		ret = -1;
296 	LOG("  0x%08x / 0x%08x = %u / %u = %u = 0x%x)",
297 	    (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c,
298 	    (unsigned)c);
299 	LOG("  0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a,
300 	    (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d);
301 	LOG("  check results => %s", r ? "ok" : "FAILED !!!");
302 	LOG("");
303 
304 	return ret;
305 }
306 
307 /* test malloc support. resulting trace shall be manually checked */
308 static int self_test_malloc(void)
309 {
310 	char *p1 = NULL, *p2 = NULL;
311 	int *p3 = NULL, *p4 = NULL;
312 	bool r;
313 	int ret = 0;
314 
315 	LOG("malloc tests (malloc, free, calloc, realloc):");
316 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
317 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
318 	/* test malloc */
319 	p1 = malloc(1024);
320 	LOG("- p1 = malloc(1024)");
321 	p2 = malloc(1024);
322 	LOG("- p2 = malloc(1024)");
323 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
324 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
325 	r = (p1 && p2 && malloc_buffer_is_within_alloced(p1, 1024) &&
326 		!malloc_buffer_is_within_alloced(p1 + 25, 1000) &&
327 		!malloc_buffer_is_within_alloced(p1 - 25, 500) &&
328 		malloc_buffer_overlaps_heap(p1 - 25, 500));
329 	if (!r)
330 		ret = -1;
331 	LOG("  => test %s", r ? "ok" : "FAILED");
332 	LOG("");
333 
334 	/* test realloc */
335 	p3 = realloc(p1, 3 * 1024);
336 	if (p3)
337 		p1 = NULL;
338 	LOG("- p3 = realloc(p1, 3*1024)");
339 	LOG("- free p2");
340 	free(p2);
341 	p2 = malloc(1024);
342 	LOG("- p2 = malloc(1024)");
343 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
344 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
345 	r = (p2 && p3);
346 	if (!r)
347 		ret = -1;
348 	LOG("  => test %s", r ? "ok" : "FAILED");
349 	LOG("");
350 	LOG("- free p1, p2, p3");
351 	free(p1);
352 	free(p2);
353 	free(p3);
354 	p1 = NULL;
355 	p2 = NULL;
356 	p3 = NULL;
357 
358 	/* test calloc */
359 	p3 = calloc(4, 1024);
360 	p4 = calloc(0x100, 1024 * 1024);
361 	LOG("- p3 = calloc(4, 1024)");
362 	LOG("- p4 = calloc(0x100, 1024*1024)   too big: should fail!");
363 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
364 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
365 	r = (p3 && !p4);
366 	if (!r)
367 		ret = -1;
368 	LOG("  => test %s", r ? "ok" : "FAILED");
369 	LOG("");
370 	LOG("- free p3, p4");
371 	free(p3);
372 	free(p4);
373 	p3 = NULL;
374 	p4 = NULL;
375 
376 	/* test free(NULL) */
377 	LOG("- free NULL");
378 	free(NULL);
379 	LOG("");
380 	LOG("malloc test done");
381 
382 	return ret;
383 }
384 
385 #ifdef CFG_VIRTUALIZATION
386 /* test nex_malloc support. resulting trace shall be manually checked */
387 static int self_test_nex_malloc(void)
388 {
389 	char *p1 = NULL, *p2 = NULL;
390 	int *p3 = NULL, *p4 = NULL;
391 	bool r;
392 	int ret = 0;
393 
394 	LOG("nex_malloc tests (nex_malloc, nex_free, nex_calloc, nex_realloc):");
395 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
396 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
397 	/* test malloc */
398 	p1 = nex_malloc(1024);
399 	LOG("- p1 = nex_malloc(1024)");
400 	p2 = nex_malloc(1024);
401 	LOG("- p2 = nex_malloc(1024)");
402 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
403 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
404 	r = (p1 && p2 && nex_malloc_buffer_is_within_alloced(p1, 1024) &&
405 		!nex_malloc_buffer_is_within_alloced(p1 + 25, 1000) &&
406 		!nex_malloc_buffer_is_within_alloced(p1 - 25, 500) &&
407 		nex_malloc_buffer_overlaps_heap(p1 - 25, 500));
408 	if (!r)
409 		ret = -1;
410 	LOG("  => test %s", r ? "ok" : "FAILED");
411 	LOG("");
412 
413 	/* test realloc */
414 	p3 = nex_realloc(p1, 3 * 1024);
415 	if (p3)
416 		p1 = NULL;
417 	LOG("- p3 = nex_realloc(p1, 3*1024)");
418 	LOG("- nex_free p2");
419 	nex_free(p2);
420 	p2 = nex_malloc(1024);
421 	LOG("- p2 = nex_malloc(1024)");
422 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
423 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
424 	r = (p2 && p3);
425 	if (!r)
426 		ret = -1;
427 	LOG("  => test %s", r ? "ok" : "FAILED");
428 	LOG("");
429 	LOG("- nex_free p1, p2, p3");
430 	nex_free(p1);
431 	nex_free(p2);
432 	nex_free(p3);
433 	p1 = NULL;
434 	p2 = NULL;
435 	p3 = NULL;
436 
437 	/* test calloc */
438 	p3 = nex_calloc(4, 1024);
439 	p4 = nex_calloc(0x100, 1024 * 1024);
440 	LOG("- p3 = nex_calloc(4, 1024)");
441 	LOG("- p4 = nex_calloc(0x100, 1024*1024)   too big: should fail!");
442 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
443 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
444 	r = (p3 && !p4);
445 	if (!r)
446 		ret = -1;
447 	LOG("  => test %s", r ? "ok" : "FAILED");
448 	LOG("");
449 	LOG("- nex_free p3, p4");
450 	nex_free(p3);
451 	nex_free(p4);
452 	p3 = NULL;
453 	p4 = NULL;
454 
455 	/* test free(NULL) */
456 	LOG("- nex_free NULL");
457 	nex_free(NULL);
458 	LOG("");
459 	LOG("nex_malloc test done");
460 
461 	return ret;
462 }
463 #else  /* CFG_VIRTUALIZATION */
464 static int self_test_nex_malloc(void)
465 {
466 	return 0;
467 }
468 #endif
469 /* exported entry points for some basic test */
470 TEE_Result core_self_tests(uint32_t nParamTypes __unused,
471 		TEE_Param pParams[TEE_NUM_PARAMS] __unused)
472 {
473 	if (self_test_mul_signed_overflow() || self_test_add_overflow() ||
474 	    self_test_sub_overflow() || self_test_mul_unsigned_overflow() ||
475 	    self_test_division() || self_test_malloc() ||
476 	    self_test_nex_malloc()) {
477 		EMSG("some self_test_xxx failed! you should enable local LOG");
478 		return TEE_ERROR_GENERIC;
479 	}
480 	return TEE_SUCCESS;
481 }
482