xref: /OK3568_Linux_fs/external/security/rk_tee_user/v2/host/xtest/regression_2000.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <err.h>
8 #include <pthread.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/param.h>
13 #include <sys/socket.h>
14 #include <sys/types.h>
15 #include <ta_socket.h>
16 #include <tee_isocket.h>
17 #include <tee_tcpsocket.h>
18 #include <__tee_tcpsocket_defines_extensions.h>
19 #include <tee_udpsocket.h>
20 #include <unistd.h>
21 
22 #include "xtest_test.h"
23 #include "xtest_helpers.h"
24 #include "sock_server.h"
25 #include "rand_stream.h"
26 
27 struct socket_handle {
28 	uint64_t buf[2];
29 	size_t blen;
30 };
31 
socket_tcp_open(TEEC_Session * session,uint32_t ip_vers,const char * addr,uint16_t port,struct socket_handle * handle,uint32_t * error,uint32_t * ret_orig)32 static TEE_Result socket_tcp_open(TEEC_Session *session, uint32_t ip_vers,
33 				  const char *addr, uint16_t port,
34 				  struct socket_handle *handle,
35 				  uint32_t *error, uint32_t *ret_orig)
36 {
37 	TEE_Result res = TEE_ERROR_GENERIC;
38 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
39 
40 	memset(handle, 0, sizeof(*handle));
41 
42 	op.params[0].value.a = ip_vers;
43 	op.params[0].value.b = port;
44 	op.params[1].tmpref.buffer = (void *)addr;
45 	op.params[1].tmpref.size = strlen(addr) + 1;
46 	op.params[2].tmpref.buffer = handle->buf;
47 	op.params[2].tmpref.size = sizeof(handle->buf);
48 
49 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
50 					 TEEC_MEMREF_TEMP_INPUT,
51 					 TEEC_MEMREF_TEMP_OUTPUT,
52 					 TEEC_VALUE_OUTPUT);
53 
54 	res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_TCP_OPEN,
55 				 &op, ret_orig);
56 
57 	handle->blen = op.params[2].tmpref.size;
58 	*error = op.params[3].value.a;
59 	return res;
60 }
61 
socket_udp_open(TEEC_Session * session,uint32_t ip_vers,const char * addr,uint16_t port,struct socket_handle * handle,uint32_t * error,uint32_t * ret_orig)62 static TEE_Result socket_udp_open(TEEC_Session *session, uint32_t ip_vers,
63 				  const char *addr, uint16_t port,
64 				  struct socket_handle *handle,
65 				  uint32_t *error, uint32_t *ret_orig)
66 {
67 	TEE_Result res = TEE_ERROR_GENERIC;
68 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
69 
70 	memset(handle, 0, sizeof(*handle));
71 
72 	op.params[0].value.a = ip_vers;
73 	op.params[0].value.b = port;
74 	op.params[1].tmpref.buffer = (void *)addr;
75 	op.params[1].tmpref.size = strlen(addr) + 1;
76 	op.params[2].tmpref.buffer = handle->buf;
77 	op.params[2].tmpref.size = sizeof(handle->buf);
78 
79 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
80 					 TEEC_MEMREF_TEMP_INPUT,
81 					 TEEC_MEMREF_TEMP_OUTPUT,
82 					 TEEC_VALUE_OUTPUT);
83 
84 	res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_UDP_OPEN,
85 				 &op, ret_orig);
86 
87 	handle->blen = op.params[2].tmpref.size;
88 	*error = op.params[3].value.a;
89 	return res;
90 }
91 
socket_send(TEEC_Session * session,struct socket_handle * handle,const void * data,size_t * dlen,uint32_t timeout,uint32_t * ret_orig)92 static TEE_Result socket_send(TEEC_Session *session,
93 			      struct socket_handle *handle,
94 			      const void *data, size_t *dlen,
95 			      uint32_t timeout, uint32_t *ret_orig)
96 {
97 	TEE_Result res = TEE_ERROR_GENERIC;
98 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
99 
100 	op.params[0].tmpref.buffer = handle->buf;
101 	op.params[0].tmpref.size = handle->blen;
102 	op.params[1].tmpref.buffer = (void *)data;
103 	op.params[1].tmpref.size = *dlen;
104 	op.params[2].value.a = timeout;
105 
106 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
107 					 TEEC_MEMREF_TEMP_INPUT,
108 					 TEEC_VALUE_INOUT, TEEC_NONE);
109 
110 	res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_SEND, &op, ret_orig);
111 
112 	*dlen = op.params[2].value.b;
113 	return res;
114 }
115 
socket_recv(TEEC_Session * session,struct socket_handle * handle,void * data,size_t * dlen,uint32_t timeout,uint32_t * ret_orig)116 static TEE_Result socket_recv(TEEC_Session *session,
117 			      struct socket_handle *handle,
118 			      void *data, size_t *dlen,
119 			      uint32_t timeout, uint32_t *ret_orig)
120 {
121 	TEE_Result res = TEE_ERROR_GENERIC;
122 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
123 
124 	op.params[0].tmpref.buffer = handle->buf;
125 	op.params[0].tmpref.size = handle->blen;
126 	op.params[1].tmpref.buffer = (void *)data;
127 	op.params[1].tmpref.size = *dlen;
128 	op.params[2].value.a = timeout;
129 
130 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
131 					 TEEC_MEMREF_TEMP_OUTPUT,
132 					 TEEC_VALUE_INPUT, TEEC_NONE);
133 
134 	res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_RECV, &op, ret_orig);
135 
136 	*dlen = op.params[1].tmpref.size;
137 	return res;
138 }
139 
socket_get_error(TEEC_Session * session,struct socket_handle * handle,uint32_t * proto_error,uint32_t * ret_orig)140 static TEE_Result socket_get_error(TEEC_Session *session,
141 			      struct socket_handle *handle,
142 			      uint32_t *proto_error, uint32_t *ret_orig)
143 {
144 	TEE_Result res = TEE_ERROR_GENERIC;
145 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
146 
147 	op.params[0].tmpref.buffer = handle->buf;
148 	op.params[0].tmpref.size = handle->blen;
149 
150 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
151 					 TEEC_VALUE_OUTPUT,
152 					 TEEC_NONE, TEEC_NONE);
153 
154 	res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_ERROR, &op, ret_orig);
155 
156 	*proto_error = op.params[1].value.a;
157 	return res;
158 }
159 
socket_close(TEEC_Session * session,struct socket_handle * handle,uint32_t * ret_orig)160 static TEE_Result socket_close(TEEC_Session *session,
161 			      struct socket_handle *handle, uint32_t *ret_orig)
162 {
163 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
164 
165 	op.params[0].tmpref.buffer = handle->buf;
166 	op.params[0].tmpref.size = handle->blen;
167 
168 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
169 					 TEEC_NONE, TEEC_NONE, TEEC_NONE);
170 
171 	return TEEC_InvokeCommand(session, TA_SOCKET_CMD_CLOSE, &op, ret_orig);
172 }
173 
socket_ioctl(TEEC_Session * session,struct socket_handle * handle,uint32_t ioctl_cmd,void * data,size_t * dlen,uint32_t * ret_orig)174 static TEE_Result socket_ioctl(TEEC_Session *session,
175 			      struct socket_handle *handle, uint32_t ioctl_cmd,
176 			      void *data, size_t *dlen, uint32_t *ret_orig)
177 {
178 	TEE_Result res = TEE_ERROR_GENERIC;
179 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
180 
181 	op.params[0].tmpref.buffer = handle->buf;
182 	op.params[0].tmpref.size = handle->blen;
183 	op.params[1].tmpref.buffer = data;
184 	op.params[1].tmpref.size = *dlen;
185 	op.params[2].value.a = ioctl_cmd;
186 
187 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
188 					 TEEC_MEMREF_TEMP_INOUT,
189 					 TEEC_VALUE_INPUT, TEEC_NONE);
190 
191 	res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_IOCTL, &op, ret_orig);
192 
193 	*dlen = op.params[1].tmpref.size;
194 	return res;
195 }
196 
197 
198 
199 struct test_200x_io_state {
200 	struct rand_stream *read_rs;
201 	struct rand_stream *write_rs;
202 	bool rfail;
203 };
204 
test_200x_init_io_state(struct test_200x_io_state * s,int read_seed,int write_seed)205 static void test_200x_init_io_state(struct test_200x_io_state *s,
206 				    int read_seed, int write_seed)
207 {
208 	memset(s, 0, sizeof(*s));
209 	s->read_rs = rand_stream_alloc(read_seed, 100);
210 	s->write_rs = rand_stream_alloc(write_seed, 100);
211 	assert(s->read_rs && s->write_rs);
212 }
213 
test_200x_tcp_accept_cb(void * ptr,int fd,short * events)214 static bool test_200x_tcp_accept_cb(void *ptr, int fd, short *events)
215 {
216 	(void)ptr;
217 	(void)fd;
218 	(void)events;
219 	return true;
220 }
221 
test_200x_tcp_read_cb(void * ptr,int fd,short * events)222 static bool test_200x_tcp_read_cb(void *ptr, int fd, short *events)
223 {
224 	struct test_200x_io_state *iostate = ptr;
225 	ssize_t r = 0;
226 	uint8_t buf[100] = { };
227 	uint8_t buf2[100] = { };
228 
229 	(void)events;
230 	r = read(fd, buf, sizeof(buf));
231 	if (r <= 0)
232 		return false;
233 
234 	rand_stream_read(iostate->read_rs, buf2, r);
235 	if (memcmp(buf, buf2, r)) {
236 		iostate->rfail = true;
237 		return false;
238 	}
239 
240 	return true;
241 }
242 
test_200x_tcp_write_cb(void * ptr,int fd,short * events)243 static bool test_200x_tcp_write_cb(void *ptr, int fd, short *events)
244 {
245 	struct test_200x_io_state *iostate = ptr;
246 	size_t num_bytes = 100;
247 	const void *bytes = NULL;
248 	ssize_t r = 0;
249 
250 	(void)events;
251 
252 	bytes = rand_stream_peek(iostate->write_rs, &num_bytes);
253 	r = write(fd, bytes, num_bytes);
254 	if (r < 0)
255 		return false;
256 
257 	rand_stream_advance(iostate->write_rs, num_bytes);
258 	return true;
259 }
260 
xtest_tee_test_2001(ADBG_Case_t * c)261 static void xtest_tee_test_2001(ADBG_Case_t *c)
262 {
263 	struct sock_server ts = { };
264 	TEEC_Session session = { };
265 	uint32_t ret_orig = 0;
266 	uint32_t proto_error = 9;
267 	struct socket_handle sh = { };
268 	uint8_t buf[64] = { };
269 	uint8_t buf2[64] = { };
270 	size_t blen = 0;
271 	struct test_200x_io_state server_iostate = { };
272 	struct test_200x_io_state local_iostate = { };
273 	struct sock_io_cb cb = {
274 		.accept = test_200x_tcp_accept_cb,
275 		.read = test_200x_tcp_read_cb,
276 		.write = test_200x_tcp_write_cb,
277 		.ptr = &server_iostate,
278 	};
279 
280 	test_200x_init_io_state(&server_iostate, 1, 2);
281 	test_200x_init_io_state(&local_iostate, 2, 1);
282 
283 	Do_ADBG_BeginSubCase(c, "Start server");
284 	if (!ADBG_EXPECT_TRUE(c, sock_server_init_tcp(&ts, &cb)))
285 		return;
286 	Do_ADBG_EndSubCase(c, "Start server");
287 
288 	Do_ADBG_BeginSubCase(c, "TCP Socket open");
289 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
290 			&session, &socket_ta_uuid, NULL, &ret_orig)))
291 		goto out;
292 
293 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_tcp_open(&session,
294 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
295 			&sh, &proto_error, &ret_orig)))
296 		goto out_close_session;
297 
298 	Do_ADBG_EndSubCase(c, "TCP Socket open");
299 
300 	Do_ADBG_BeginSubCase(c, "TCP Socket send");
301 	blen = sizeof(buf);
302 	rand_stream_read(local_iostate.write_rs, buf, blen);
303 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_send(&session, &sh,
304 			buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
305 		goto out_close_session;
306 	ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, sizeof(buf));
307 	Do_ADBG_EndSubCase(c, "TCP Socket send");
308 
309 	Do_ADBG_BeginSubCase(c, "TCP Socket recv");
310 	blen = sizeof(buf);
311 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_recv(&session, &sh,
312 			buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
313 		goto out_close_session;
314 	ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, sizeof(buf));
315 	rand_stream_read(local_iostate.read_rs, buf2, blen);
316 	ADBG_EXPECT_BUFFER(c, buf2, blen, buf, blen);
317 	Do_ADBG_EndSubCase(c, "TCP Socket recv");
318 
319 	/*
320 	 * All written bytes above (with the TA) is quite likely to have
321 	 * hit the tcp server by now.
322 	 */
323 	ADBG_EXPECT_TRUE(c, !server_iostate.rfail);
324 
325 	Do_ADBG_BeginSubCase(c, "TCP Socket get error");
326 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_get_error(&session, &sh,
327 			&proto_error, &ret_orig)))
328 		goto out_close_session;
329 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, proto_error))
330 		goto out_close_session;
331 	Do_ADBG_EndSubCase(c, "TCP Socket get error");
332 
333 	Do_ADBG_BeginSubCase(c, "TCP Socket close");
334 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_close(&session, &sh,
335 			&ret_orig)))
336 		goto out_close_session;
337 	Do_ADBG_EndSubCase(c, "TCP Socket close");
338 
339 	Do_ADBG_BeginSubCase(c, "TCP Socket ioctl");
340 
341 
342 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_tcp_open(&session,
343 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
344 			&sh, &proto_error, &ret_orig)))
345 		goto out_close_session;
346 
347 	blen = sizeof(buf);
348 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh, 0x00F00000,
349 			buf, &blen, &ret_orig)))
350 		goto out_close_session;
351 
352 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_close(&session, &sh,
353 			&ret_orig)))
354 		goto out_close_session;
355 
356 
357 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_tcp_open(&session,
358 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
359 			&sh, &proto_error, &ret_orig)))
360 		goto out_close_session;
361 
362 	blen = sizeof(buf);
363 	ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
364 				socket_ioctl(&session, &sh,
365 					TEE_ISOCKET_PROTOCOLID_TCP << 24,
366 					buf, &blen, &ret_orig));
367 	TEEC_CloseSession(&session);
368 
369 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
370 			&session, &socket_ta_uuid, NULL, &ret_orig)))
371 		goto out;
372 
373 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_tcp_open(&session,
374 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
375 			&sh, &proto_error, &ret_orig)))
376 		goto out_close_session;
377 
378 	blen = sizeof(buf);
379 	ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
380 				socket_ioctl(&session, &sh, 0x32 << 24,
381 				buf, &blen, &ret_orig));
382 
383 	Do_ADBG_EndSubCase(c, "TCP Socket ioctl");
384 
385 out_close_session:
386 	TEEC_CloseSession(&session);
387 out:
388 	sock_server_uninit(&ts);
389 }
390 ADBG_CASE_DEFINE(regression, 2001, xtest_tee_test_2001,
391 		"Trivial TCP iSocket API tests");
392 
393 struct test_2002_barrier {
394 	pthread_mutex_t mu;
395 	pthread_barrier_t bar;
396 };
397 
398 struct test_2002_arg {
399 	bool success;
400 	size_t tnum;
401 	struct test_2002_barrier *bar;
402 };
403 
xtest_2002_wait_barrier(struct test_2002_barrier * bar)404 static void  xtest_2002_wait_barrier(struct test_2002_barrier *bar)
405 {
406 	/*
407 	 * Once the mutex is taken the barrier is initialized so the mutex
408 	 * can be released immediately.
409 	 */
410 	xtest_mutex_lock(&bar->mu);
411 	xtest_mutex_unlock(&bar->mu);
412 	xtest_barrier_wait(&bar->bar);
413 }
414 
xtest_tee_test_2002_thread(void * arg)415 static void *xtest_tee_test_2002_thread(void *arg)
416 {
417 	struct test_2002_arg *a = arg;
418 	TEE_Result res = TEE_ERROR_GENERIC;
419 	struct sock_server ts = { };
420 	TEEC_Session session = { };
421 	uint32_t ret_orig = 0;
422 	uint32_t proto_error = 0;
423 	struct socket_handle sh = { };
424 	struct test_200x_io_state server_iostate = { };
425 	struct test_200x_io_state local_iostate = { };
426 	struct sock_io_cb cb = {
427 		.accept = test_200x_tcp_accept_cb,
428 		.read = test_200x_tcp_read_cb,
429 		.write = test_200x_tcp_write_cb,
430 		.ptr = &server_iostate,
431 	};
432 	int seed[2] = { 1 + a->tnum * 2, 2 + a->tnum * 2 };
433 	size_t send_limit = 10000;
434 	size_t recv_limit = 10000;
435 	size_t sent_bytes = 0;
436 	size_t recvd_bytes = 0;
437 
438 	test_200x_init_io_state(&server_iostate, seed[0], seed[1]);
439 	test_200x_init_io_state(&local_iostate, seed[1], seed[0]);
440 
441 	if (!sock_server_init_tcp(&ts, &cb)) {
442 		xtest_2002_wait_barrier(a->bar);
443 		return NULL;
444 	}
445 
446 	res = xtest_teec_open_session(&session, &socket_ta_uuid, NULL,
447 				      &ret_orig);
448 
449 	xtest_2002_wait_barrier(a->bar);
450 	if (res != TEE_SUCCESS)
451 		goto out;
452 
453 	res = socket_tcp_open(&session, TEE_IP_VERSION_DC, ts.bind->host,
454 			      ts.bind->port, &sh, &proto_error, &ret_orig);
455 	if (res != TEE_SUCCESS)
456 		goto out_close_session;
457 
458 	while (sent_bytes < send_limit && recvd_bytes < recv_limit) {
459 		const void *peek = NULL;
460 		uint8_t buf[64] = { };
461 		uint8_t buf2[64] = { };
462 		size_t blen = 0;
463 
464 		blen = sizeof(buf);
465 		peek = rand_stream_peek(local_iostate.write_rs, &blen);
466 		res = socket_send(&session, &sh, peek, &blen,
467 				  TEE_TIMEOUT_INFINITE, &ret_orig);
468 		if (res != TEE_SUCCESS)
469 			goto out_close_session;
470 		rand_stream_advance(local_iostate.write_rs, blen);
471 		sent_bytes += blen;
472 
473 		blen = sizeof(buf);
474 		res = socket_recv(&session, &sh, buf, &blen,
475 				  TEE_TIMEOUT_INFINITE, &ret_orig);
476 		if (res != TEE_SUCCESS)
477 			goto out_close_session;
478 		rand_stream_read(local_iostate.read_rs, buf2, blen);
479 		if (memcmp(buf2, buf, blen))
480 			goto out_close_session;
481 		recvd_bytes += blen;
482 	}
483 
484 
485 	res = socket_close(&session, &sh, &ret_orig);
486 	if (res != TEE_SUCCESS)
487 		goto out_close_session;
488 
489 	/*
490 	 * All written bytes above (with the TA) is quite likely to have
491 	 * hit the tcp server by now.
492 	 */
493 	a->success = !server_iostate.rfail;
494 
495 out_close_session:
496 	TEEC_CloseSession(&session);
497 out:
498 	sock_server_uninit(&ts);
499 	return NULL;
500 }
501 
502 #define NUM_THREADS	3
503 
xtest_tee_test_2002(ADBG_Case_t * c)504 static void xtest_tee_test_2002(ADBG_Case_t *c)
505 {
506 	struct test_2002_barrier bar = { .mu = PTHREAD_MUTEX_INITIALIZER };
507 	struct test_2002_arg arg[NUM_THREADS] = { };
508 	size_t n = 0;
509 	size_t nt = 0;
510 	pthread_t thr[NUM_THREADS] = { };
511 
512 	Do_ADBG_BeginSubCase(c, "Stressing with %d threads", NUM_THREADS);
513 
514 	xtest_mutex_lock(&bar.mu);
515 
516 	nt = NUM_THREADS;
517 	for (n = 0; n < nt; n++) {
518 		arg[n].success = false;
519 		arg[n].tnum = n;
520 		arg[n].bar = &bar;
521 		if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
522 					xtest_tee_test_2002_thread, arg + n)))
523 			nt = n; /* break loop and start cleanup */
524 	}
525 
526 	xtest_barrier_init(&bar.bar, nt + 1);
527 	xtest_mutex_unlock(&bar.mu);
528 	xtest_barrier_wait(&bar.bar);
529 
530 	for (n = 0; n < nt; n++) {
531 		ADBG_EXPECT(c, 0, pthread_join(thr[n], NULL));
532 		ADBG_EXPECT_TRUE(c, arg[n].success);
533 	}
534 
535 	xtest_mutex_destroy(&bar.mu);
536 	xtest_barrier_destroy(&bar.bar);
537 
538 	Do_ADBG_EndSubCase(c, "Stressing with %d threads", NUM_THREADS);
539 }
540 ADBG_CASE_DEFINE(regression, 2002, xtest_tee_test_2002,
541 		"Concurrent stressing TCP iSocket API tests");
542 
test_2003_accept_cb(void * ptr,int fd,short * events)543 static bool test_2003_accept_cb(void *ptr, int fd, short *events)
544 {
545 	int val = 0;
546 
547 	(void)ptr;
548 	(void)events;
549 
550 	val = 4 * 1024;
551 	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)))
552 		warn("test_2003_accept_cb: setsockopt");
553 	return true;
554 }
555 
xtest_tee_test_2003(ADBG_Case_t * c)556 static void xtest_tee_test_2003(ADBG_Case_t *c)
557 {
558 	struct sock_server ts = { };
559 	TEEC_Session session = { };
560 	uint32_t ret_orig = 0;
561 	uint32_t proto_error = 0;
562 	struct socket_handle sh = { };
563 	void *buf = NULL;
564 	const size_t blen0 = 16 * 1024;
565 	size_t blen = 0;
566 	uint32_t val = 0;
567 	struct sock_io_cb cb = { .accept = test_2003_accept_cb };
568 
569 	Do_ADBG_BeginSubCase(c, "Start server");
570 	if (!ADBG_EXPECT_TRUE(c, sock_server_init_tcp(&ts, &cb)))
571 		return;
572 	buf = calloc(1, blen0);
573 	if (!ADBG_EXPECT_NOT_NULL(c, buf))
574 		goto out;
575 	Do_ADBG_EndSubCase(c, "Start server");
576 
577 	Do_ADBG_BeginSubCase(c, "TCP Socket open");
578 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
579 			&session, &socket_ta_uuid, NULL, &ret_orig)))
580 		goto out;
581 
582 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_tcp_open(&session,
583 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
584 			&sh, &proto_error, &ret_orig)))
585 		goto out_close_session;
586 
587 	blen = sizeof(val);
588 	val = 4 * 1024;
589 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh,
590 			TEE_TCP_SET_RECVBUF, &val, &blen, &ret_orig)))
591 		goto out_close_session;
592 
593 	blen = sizeof(val);
594 	val = 4 * 1024;
595 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh,
596 			TEE_TCP_SET_SENDBUF, &val, &blen, &ret_orig)))
597 		goto out_close_session;
598 
599 	Do_ADBG_EndSubCase(c, "TCP Socket open");
600 
601 	Do_ADBG_BeginSubCase(c, "TCP Socket send (10 ms timeout)");
602 	while (true) {
603 		TEE_Result res = TEE_ERROR_GENERIC;
604 
605 		blen = blen0;
606 		memset(buf, 0, blen0);
607 		res = socket_send(&session, &sh, buf, &blen, 10, &ret_orig);
608 		if (res == TEE_ISOCKET_ERROR_TIMEOUT)
609 			break;
610 		if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
611 			goto out_close_session;
612 		ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, blen0);
613 	}
614 	Do_ADBG_EndSubCase(c, "TCP Socket send (10 ms timeout)");
615 
616 	Do_ADBG_BeginSubCase(c, "TCP Socket recv (10 ms timeout)");
617 	blen = blen0;
618 	ADBG_EXPECT_TEEC_RESULT(c, TEE_ISOCKET_ERROR_TIMEOUT,
619 				socket_recv(&session, &sh, buf, &blen,
620 					    10, &ret_orig));
621 	ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, blen0);
622 	Do_ADBG_EndSubCase(c, "TCP Socket recv (10 ms timeout)");
623 
624 	Do_ADBG_BeginSubCase(c, "TCP Socket get error");
625 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_get_error(&session, &sh,
626 			&proto_error, &ret_orig)))
627 		goto out_close_session;
628 	ADBG_EXPECT_TEEC_RESULT(c, TEE_ISOCKET_ERROR_TIMEOUT, proto_error);
629 	Do_ADBG_EndSubCase(c, "TCP Socket get error");
630 
631 out_close_session:
632 	TEEC_CloseSession(&session);
633 out:
634 	free(buf);
635 	sock_server_uninit(&ts);
636 }
637 ADBG_CASE_DEFINE(regression, 2003, xtest_tee_test_2003,
638 		"Timeout TCP iSocket API tests");
639 
test_200x_udp_accept_cb(void * ptr,int fd,short * events)640 static bool test_200x_udp_accept_cb(void *ptr, int fd, short *events)
641 {
642 	struct test_200x_io_state *iostate = ptr;
643 	struct sockaddr_storage sass = { };
644 	struct sockaddr *sa = (struct sockaddr *)&sass;
645 	socklen_t slen = sizeof(sass);
646 	uint8_t buf[100] = { };
647 	uint8_t buf2[100] = { };
648 	ssize_t r = 0;
649 	size_t l = 0;
650 
651 	(void)events;
652 
653 	r = recvfrom(fd, buf, sizeof(buf), 0, sa, &slen);
654 	if (r == -1)
655 		return false;
656 
657 	l = r;
658 	rand_stream_read(iostate->read_rs, buf2, l);
659 	if (memcmp(buf, buf2, l))
660 		iostate->rfail = true;
661 
662 	rand_stream_read(iostate->write_rs, buf, l);
663 	return sendto(fd, buf, l, 0, sa, slen) != -1;
664 }
665 
xtest_tee_test_2004(ADBG_Case_t * c)666 static void xtest_tee_test_2004(ADBG_Case_t *c)
667 {
668 	struct sock_server ts = { };
669 	struct sock_server ts2 = { };
670 	struct sock_server ts3 = { };
671 	bool ts_inited = false;
672 	bool ts2_inited = false;
673 	bool ts3_inited = false;
674 	TEEC_Session session = { };
675 	uint32_t ret_orig = 0;
676 	uint32_t proto_error = 0;
677 	struct socket_handle sh = { };
678 	uint8_t buf[64] = { };
679 	uint8_t buf2[64] = { };
680 	size_t blen = 0;
681 	uint16_t port = 0;
682 	struct test_200x_io_state server_iostate = { };
683 	struct test_200x_io_state local_iostate = { };
684 	struct sock_io_cb cb = {
685 		.accept = test_200x_udp_accept_cb,
686 		.ptr = &server_iostate,
687 	};
688 
689 	test_200x_init_io_state(&server_iostate, 1, 2);
690 	test_200x_init_io_state(&local_iostate, 2, 1);
691 
692 	Do_ADBG_BeginSubCase(c, "Start server");
693 	if (!ADBG_EXPECT_TRUE(c, sock_server_init_udp(&ts, &cb)))
694 		return;
695 	ts_inited = true;
696 	if (!ADBG_EXPECT_TRUE(c, sock_server_init_udp(&ts2, &cb)))
697 		goto out;
698 	ts2_inited = true;
699 	if (!ADBG_EXPECT_TRUE(c, sock_server_init_udp(&ts3, &cb)))
700 		goto out;
701 	ts3_inited = true;
702 	Do_ADBG_EndSubCase(c, "Start server");
703 
704 	Do_ADBG_BeginSubCase(c, "UDP Socket open");
705 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
706 			&session, &socket_ta_uuid, NULL, &ret_orig)))
707 		goto out;
708 
709 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
710 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
711 			&sh, &proto_error, &ret_orig)))
712 		goto out_close_session;
713 
714 	Do_ADBG_EndSubCase(c, "UDP Socket open");
715 
716 	Do_ADBG_BeginSubCase(c, "UDP Socket send");
717 	blen = sizeof(buf);
718 	rand_stream_read(local_iostate.write_rs, buf, blen);
719 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_send(&session, &sh,
720 			buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
721 		goto out_close_session;
722 	ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, sizeof(buf));
723 	Do_ADBG_EndSubCase(c, "UDP Socket send");
724 
725 	Do_ADBG_BeginSubCase(c, "UDP Socket recv");
726 	blen = sizeof(buf);
727 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_recv(&session, &sh,
728 			buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
729 		goto out_close_session;
730 	ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, sizeof(buf));
731 	rand_stream_read(local_iostate.read_rs, buf2, blen);
732 	ADBG_EXPECT_BUFFER(c, buf2, blen, buf, blen);
733 	ADBG_EXPECT_TRUE(c, !server_iostate.rfail);
734 	Do_ADBG_EndSubCase(c, "UDP Socket recv");
735 
736 	Do_ADBG_BeginSubCase(c, "UDP Socket get error");
737 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_get_error(&session, &sh,
738 			&proto_error, &ret_orig)))
739 		goto out_close_session;
740 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, proto_error))
741 		goto out_close_session;
742 	Do_ADBG_EndSubCase(c, "UDP Socket get error");
743 
744 	Do_ADBG_BeginSubCase(c, "UDP Socket close");
745 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_close(&session, &sh,
746 			&ret_orig)))
747 		goto out_close_session;
748 	Do_ADBG_EndSubCase(c, "UDP Socket close");
749 
750 	Do_ADBG_BeginSubCase(c, "UDP Socket ioctl");
751 
752 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
753 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
754 			&sh, &proto_error, &ret_orig)))
755 		goto out_close_session;
756 
757 	blen = sizeof(buf);
758 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh, 0x00F00000,
759 			buf, &blen, &ret_orig)))
760 		goto out_close_session;
761 
762 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_close(&session, &sh,
763 			&ret_orig)))
764 		goto out_close_session;
765 
766 
767 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
768 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
769 			&sh, &proto_error, &ret_orig)))
770 		goto out_close_session;
771 
772 	blen = sizeof(buf);
773 	ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
774 				socket_ioctl(&session, &sh,
775 					TEE_ISOCKET_PROTOCOLID_UDP << 24,
776 					buf, &blen, &ret_orig));
777 	TEEC_CloseSession(&session);
778 
779 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
780 			&session, &socket_ta_uuid, NULL, &ret_orig)))
781 		goto out;
782 
783 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
784 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
785 			&sh, &proto_error, &ret_orig)))
786 		goto out_close_session;
787 
788 	blen = sizeof(buf);
789 	ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
790 				socket_ioctl(&session, &sh, 0x32 << 24,
791 				buf, &blen, &ret_orig));
792 
793 	Do_ADBG_EndSubCase(c, "UDP Socket ioctl");
794 
795 	Do_ADBG_BeginSubCase(c, "UDP Socket change port");
796 
797 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
798 			&session, &socket_ta_uuid, NULL, &ret_orig)))
799 		goto out;
800 
801 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
802 			TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
803 			&sh, &proto_error, &ret_orig)))
804 		goto out_close_session;
805 	sock_server_uninit(&ts);
806 	ts_inited = false;
807 
808 	port = ts2.bind->port;
809 	blen = sizeof(port);
810 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh,
811 			TEE_UDP_CHANGEPORT, &port, &blen, &ret_orig)))
812 		goto out_close_session;
813 
814 	Do_ADBG_BeginSubCase(c, "UDP Socket send");
815 	blen = sizeof(buf);
816 	rand_stream_read(local_iostate.write_rs, buf, blen);
817 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_send(&session, &sh,
818 			buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
819 		goto out_close_session;
820 	ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, sizeof(buf));
821 	Do_ADBG_EndSubCase(c, "UDP Socket send");
822 
823 	Do_ADBG_BeginSubCase(c, "UDP Socket recv");
824 	blen = sizeof(buf);
825 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_recv(&session, &sh,
826 			buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
827 		goto out_close_session;
828 	ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, sizeof(buf));
829 	rand_stream_read(local_iostate.read_rs, buf2, blen);
830 	ADBG_EXPECT_BUFFER(c, buf2, blen, buf, blen);
831 	ADBG_EXPECT_TRUE(c, !server_iostate.rfail);
832 	Do_ADBG_EndSubCase(c, "UDP Socket recv");
833 
834 	Do_ADBG_EndSubCase(c, "UDP Socket change port");
835 
836 	Do_ADBG_BeginSubCase(c, "UDP Socket change addr");
837 
838 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
839 			&session, &socket_ta_uuid, NULL, &ret_orig)))
840 		goto out;
841 
842 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
843 			TEE_IP_VERSION_DC, ts2.bind->host, ts2.bind->port,
844 			&sh, &proto_error, &ret_orig)))
845 		goto out_close_session;
846 	sock_server_uninit(&ts2);
847 	ts2_inited = false;
848 
849 	port = ts3.bind->port;
850 	blen = sizeof(port);
851 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh,
852 			TEE_UDP_CHANGEPORT, &port, &blen, &ret_orig)))
853 		goto out_close_session;
854 
855 	blen = strlen(ts3.bind->host) + 1;
856 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh,
857 			TEE_UDP_CHANGEADDR, ts3.bind->host, &blen, &ret_orig)))
858 		goto out_close_session;
859 
860 	Do_ADBG_BeginSubCase(c, "UDP Socket send");
861 	blen = sizeof(buf);
862 	rand_stream_read(local_iostate.write_rs, buf, blen);
863 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_send(&session, &sh,
864 			buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
865 		goto out_close_session;
866 	ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, sizeof(buf));
867 	Do_ADBG_EndSubCase(c, "UDP Socket send");
868 
869 	Do_ADBG_BeginSubCase(c, "UDP Socket recv");
870 	blen = sizeof(buf);
871 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_recv(&session, &sh,
872 			buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
873 		goto out_close_session;
874 	ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, sizeof(buf));
875 	rand_stream_read(local_iostate.read_rs, buf2, blen);
876 	ADBG_EXPECT_BUFFER(c, buf2, blen, buf, blen);
877 	ADBG_EXPECT_TRUE(c, !server_iostate.rfail);
878 	Do_ADBG_EndSubCase(c, "UDP Socket recv");
879 
880 	Do_ADBG_EndSubCase(c, "UDP Socket change addr");
881 
882 
883 out_close_session:
884 	TEEC_CloseSession(&session);
885 out:
886 	if (ts_inited)
887 		sock_server_uninit(&ts);
888 	if (ts2_inited)
889 		sock_server_uninit(&ts2);
890 	if (ts3_inited)
891 		sock_server_uninit(&ts3);
892 }
893 ADBG_CASE_DEFINE(regression, 2004, xtest_tee_test_2004,
894 		"UDP iSocket API tests");
895