blob: 600b18c1e5df25e5484cdd49b3e9077afe67afa2 [file] [log] [blame]
Etienne Carriere9b7b70d2020-05-16 10:27:23 +02001// SPDX-License-Identifier: GPL-2.0
Jens Wiklander02389a92016-12-16 11:13:38 +01002/*
3 * Copyright (c) 2016, Linaro Limited
Jens Wiklander02389a92016-12-16 11:13:38 +01004 */
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
27struct socket_handle {
28 uint64_t buf[2];
29 size_t blen;
30};
31
32static 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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010037 TEE_Result res = TEE_ERROR_GENERIC;
Jens Wiklander02389a92016-12-16 11:13:38 +010038 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
62static 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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010067 TEE_Result res = TEE_ERROR_GENERIC;
Jens Wiklander02389a92016-12-16 11:13:38 +010068 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
92static 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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010097 TEE_Result res = TEE_ERROR_GENERIC;
Jens Wiklander02389a92016-12-16 11:13:38 +010098 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
116static 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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100121 TEE_Result res = TEE_ERROR_GENERIC;
Jens Wiklander02389a92016-12-16 11:13:38 +0100122 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
140static TEE_Result socket_get_error(TEEC_Session *session,
141 struct socket_handle *handle,
142 uint32_t *proto_error, uint32_t *ret_orig)
143{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100144 TEE_Result res = TEE_ERROR_GENERIC;
Jens Wiklander02389a92016-12-16 11:13:38 +0100145 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
160static 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
174static 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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100178 TEE_Result res = TEE_ERROR_GENERIC;
Jens Wiklander02389a92016-12-16 11:13:38 +0100179 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
199struct test_200x_io_state {
200 struct rand_stream *read_rs;
201 struct rand_stream *write_rs;
202 bool rfail;
203};
204
205static 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
214static 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
222static bool test_200x_tcp_read_cb(void *ptr, int fd, short *events)
223{
224 struct test_200x_io_state *iostate = ptr;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100225 ssize_t r = 0;
226 uint8_t buf[100] = { };
227 uint8_t buf2[100] = { };
Jens Wiklander02389a92016-12-16 11:13:38 +0100228
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
243static 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;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100247 const void *bytes = NULL;
248 ssize_t r = 0;
Jens Wiklander02389a92016-12-16 11:13:38 +0100249
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
261static void xtest_tee_test_2001(ADBG_Case_t *c)
262{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100263 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 = { };
Jens Wiklander02389a92016-12-16 11:13:38 +0100273 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
385out_close_session:
386 TEEC_CloseSession(&session);
387out:
388 sock_server_uninit(&ts);
389}
Jens Wiklander14f48872018-06-29 15:30:13 +0200390ADBG_CASE_DEFINE(regression, 2001, xtest_tee_test_2001,
391 "Trivial TCP iSocket API tests");
Jens Wiklander02389a92016-12-16 11:13:38 +0100392
393struct test_2002_barrier {
394 pthread_mutex_t mu;
395 pthread_barrier_t bar;
396};
397
398struct test_2002_arg {
399 bool success;
400 size_t tnum;
401 struct test_2002_barrier *bar;
402};
403
404static 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
415static void *xtest_tee_test_2002_thread(void *arg)
416{
417 struct test_2002_arg *a = arg;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100418 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 = { };
Jens Wiklander02389a92016-12-16 11:13:38 +0100426 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) {
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100459 const void *peek = NULL;
460 uint8_t buf[64] = { };
461 uint8_t buf2[64] = { };
462 size_t blen = 0;
Jens Wiklander02389a92016-12-16 11:13:38 +0100463
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
495out_close_session:
496 TEEC_CloseSession(&session);
497out:
498 sock_server_uninit(&ts);
499 return NULL;
500}
501
502#define NUM_THREADS 3
503
504static void xtest_tee_test_2002(ADBG_Case_t *c)
505{
Jens Wiklander02389a92016-12-16 11:13:38 +0100506 struct test_2002_barrier bar = { .mu = PTHREAD_MUTEX_INITIALIZER };
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100507 struct test_2002_arg arg[NUM_THREADS] = { };
508 size_t n = 0;
509 size_t nt = 0;
510 pthread_t thr[NUM_THREADS] = { };
Jens Wiklander02389a92016-12-16 11:13:38 +0100511
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}
Jens Wiklander14f48872018-06-29 15:30:13 +0200540ADBG_CASE_DEFINE(regression, 2002, xtest_tee_test_2002,
541 "Concurrent stressing TCP iSocket API tests");
Jens Wiklander02389a92016-12-16 11:13:38 +0100542
543static bool test_2003_accept_cb(void *ptr, int fd, short *events)
544{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100545 int val = 0;
Jens Wiklander02389a92016-12-16 11:13:38 +0100546
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
556static void xtest_tee_test_2003(ADBG_Case_t *c)
557{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100558 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;
Jens Wiklander02389a92016-12-16 11:13:38 +0100564 const size_t blen0 = 16 * 1024;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100565 size_t blen = 0;
566 uint32_t val = 0;
Jens Wiklander02389a92016-12-16 11:13:38 +0100567 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) {
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100603 TEE_Result res = TEE_ERROR_GENERIC;
Jens Wiklander02389a92016-12-16 11:13:38 +0100604
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
631out_close_session:
632 TEEC_CloseSession(&session);
633out:
634 free(buf);
635 sock_server_uninit(&ts);
636}
Jens Wiklander14f48872018-06-29 15:30:13 +0200637ADBG_CASE_DEFINE(regression, 2003, xtest_tee_test_2003,
638 "Timeout TCP iSocket API tests");
Jens Wiklander02389a92016-12-16 11:13:38 +0100639
640static bool test_200x_udp_accept_cb(void *ptr, int fd, short *events)
641{
642 struct test_200x_io_state *iostate = ptr;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100643 struct sockaddr_storage sass = { };
Jens Wiklander02389a92016-12-16 11:13:38 +0100644 struct sockaddr *sa = (struct sockaddr *)&sass;
645 socklen_t slen = sizeof(sass);
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100646 uint8_t buf[100] = { };
647 uint8_t buf2[100] = { };
648 ssize_t r = 0;
649 size_t l = 0;
Jens Wiklander02389a92016-12-16 11:13:38 +0100650
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
Jens Wiklander4ffddce2021-10-27 17:08:56 +0200666static bool test_2004_send_recv(ADBG_Case_t *c,
667 struct test_200x_io_state *srv_ios,
668 struct test_200x_io_state *local_ios,
669 TEEC_Session *session, struct socket_handle *sh,
670 size_t send_sz, size_t recv_sz)
671{
672 bool ret = false;
673 uint32_t ret_orig = 0;
674 uint8_t *buf = calloc(1, send_sz);
675 uint8_t *buf2 = calloc(1, send_sz);
676 size_t blen = 0;
677
678 /* If recv_sz < send_sz we're receiving a truncated datagram */
679
680 if (!ADBG_EXPECT_NOT_NULL(c, buf) || !ADBG_EXPECT_NOT_NULL(c, buf2) ||
681 !ADBG_EXPECT_COMPARE_UNSIGNED(c, send_sz, >=, recv_sz))
682 goto out;
683
684 /* First we're sending the packet to the echo server */
685 Do_ADBG_BeginSubCase(c, "UDP Socket send");
686 blen = send_sz;
687 rand_stream_read(local_ios->write_rs, buf, blen);
688 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_send(session, sh,
689 buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
690 goto out;
691 ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, send_sz);
692 Do_ADBG_EndSubCase(c, "UDP Socket send");
693
694 /* Then we're receiving the packet from the echo server */
695 Do_ADBG_BeginSubCase(c, "UDP Socket recv");
696 blen = 0;
697 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_recv(session, sh,
698 buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
699 goto out;
700 ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, send_sz);
701 blen = recv_sz;
702 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_recv(session, sh,
703 buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig)))
704 goto out;
705 if (recv_sz < send_sz)
706 ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, >=, recv_sz);
707 else
708 ADBG_EXPECT_COMPARE_UNSIGNED(c, blen, ==, send_sz);
709 rand_stream_read(local_ios->read_rs, buf2, send_sz);
710 ADBG_EXPECT_BUFFER(c, buf2, recv_sz, buf, recv_sz);
711 ADBG_EXPECT_TRUE(c, !srv_ios->rfail);
712 Do_ADBG_EndSubCase(c, "UDP Socket recv");
713
714 ret = true;
715out:
716 free(buf);
717 free(buf2);
718
719 return ret;
720}
721
Jens Wiklander02389a92016-12-16 11:13:38 +0100722static void xtest_tee_test_2004(ADBG_Case_t *c)
723{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100724 struct sock_server ts = { };
725 struct sock_server ts2 = { };
726 struct sock_server ts3 = { };
Jens Wiklander02389a92016-12-16 11:13:38 +0100727 bool ts_inited = false;
728 bool ts2_inited = false;
729 bool ts3_inited = false;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100730 TEEC_Session session = { };
731 uint32_t ret_orig = 0;
732 uint32_t proto_error = 0;
733 struct socket_handle sh = { };
734 uint8_t buf[64] = { };
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100735 size_t blen = 0;
736 uint16_t port = 0;
737 struct test_200x_io_state server_iostate = { };
738 struct test_200x_io_state local_iostate = { };
Jens Wiklander02389a92016-12-16 11:13:38 +0100739 struct sock_io_cb cb = {
740 .accept = test_200x_udp_accept_cb,
741 .ptr = &server_iostate,
742 };
743
744 test_200x_init_io_state(&server_iostate, 1, 2);
745 test_200x_init_io_state(&local_iostate, 2, 1);
746
747 Do_ADBG_BeginSubCase(c, "Start server");
748 if (!ADBG_EXPECT_TRUE(c, sock_server_init_udp(&ts, &cb)))
749 return;
750 ts_inited = true;
751 if (!ADBG_EXPECT_TRUE(c, sock_server_init_udp(&ts2, &cb)))
752 goto out;
753 ts2_inited = true;
754 if (!ADBG_EXPECT_TRUE(c, sock_server_init_udp(&ts3, &cb)))
755 goto out;
756 ts3_inited = true;
757 Do_ADBG_EndSubCase(c, "Start server");
758
759 Do_ADBG_BeginSubCase(c, "UDP Socket open");
760 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
761 &session, &socket_ta_uuid, NULL, &ret_orig)))
762 goto out;
763
764 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
765 TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
766 &sh, &proto_error, &ret_orig)))
767 goto out_close_session;
768
769 Do_ADBG_EndSubCase(c, "UDP Socket open");
770
Jens Wiklander4ffddce2021-10-27 17:08:56 +0200771 Do_ADBG_BeginSubCase(c, "Normal send and receive");
772 if (!ADBG_EXPECT_TRUE(c, test_2004_send_recv(c, &server_iostate,
773 &local_iostate, &session,
774 &sh, 64, 64)))
Jens Wiklander02389a92016-12-16 11:13:38 +0100775 goto out_close_session;
Jens Wiklander4ffddce2021-10-27 17:08:56 +0200776 Do_ADBG_EndSubCase(c, "Normal send and receive");
Jens Wiklander02389a92016-12-16 11:13:38 +0100777
Jens Wiklander4ffddce2021-10-27 17:08:56 +0200778 Do_ADBG_BeginSubCase(c, "UDP Socket truncated recv");
779 if (!ADBG_EXPECT_TRUE(c, test_2004_send_recv(c, &server_iostate,
780 &local_iostate, &session,
781 &sh, 64, 32)))
Jens Wiklander02389a92016-12-16 11:13:38 +0100782 goto out_close_session;
Jens Wiklander4ffddce2021-10-27 17:08:56 +0200783 Do_ADBG_EndSubCase(c, "UDP Socket truncated recv");
Jens Wiklander02389a92016-12-16 11:13:38 +0100784
785 Do_ADBG_BeginSubCase(c, "UDP Socket get error");
786 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_get_error(&session, &sh,
787 &proto_error, &ret_orig)))
788 goto out_close_session;
789 if (!ADBG_EXPECT_TEEC_SUCCESS(c, proto_error))
790 goto out_close_session;
791 Do_ADBG_EndSubCase(c, "UDP Socket get error");
792
793 Do_ADBG_BeginSubCase(c, "UDP Socket close");
794 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_close(&session, &sh,
795 &ret_orig)))
796 goto out_close_session;
797 Do_ADBG_EndSubCase(c, "UDP Socket close");
798
799 Do_ADBG_BeginSubCase(c, "UDP Socket ioctl");
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
806 blen = sizeof(buf);
807 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh, 0x00F00000,
808 buf, &blen, &ret_orig)))
809 goto out_close_session;
810
811 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_close(&session, &sh,
812 &ret_orig)))
813 goto out_close_session;
814
815
816 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
817 TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
818 &sh, &proto_error, &ret_orig)))
819 goto out_close_session;
820
821 blen = sizeof(buf);
822 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
823 socket_ioctl(&session, &sh,
824 TEE_ISOCKET_PROTOCOLID_UDP << 24,
825 buf, &blen, &ret_orig));
826 TEEC_CloseSession(&session);
827
828 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
829 &session, &socket_ta_uuid, NULL, &ret_orig)))
830 goto out;
831
832 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
833 TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
834 &sh, &proto_error, &ret_orig)))
835 goto out_close_session;
836
837 blen = sizeof(buf);
838 ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
839 socket_ioctl(&session, &sh, 0x32 << 24,
840 buf, &blen, &ret_orig));
Clement Faure13c4de12021-11-02 15:22:22 +0100841 TEEC_CloseSession(&session);
Jens Wiklander02389a92016-12-16 11:13:38 +0100842
843 Do_ADBG_EndSubCase(c, "UDP Socket ioctl");
844
845 Do_ADBG_BeginSubCase(c, "UDP Socket change port");
846
847 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
848 &session, &socket_ta_uuid, NULL, &ret_orig)))
849 goto out;
850
851 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
852 TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port,
853 &sh, &proto_error, &ret_orig)))
854 goto out_close_session;
855 sock_server_uninit(&ts);
856 ts_inited = false;
857
858 port = ts2.bind->port;
859 blen = sizeof(port);
860 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh,
861 TEE_UDP_CHANGEPORT, &port, &blen, &ret_orig)))
862 goto out_close_session;
863
Jens Wiklander02389a92016-12-16 11:13:38 +0100864
Jens Wiklander4ffddce2021-10-27 17:08:56 +0200865 if (!ADBG_EXPECT_TRUE(c, test_2004_send_recv(c, &server_iostate,
866 &local_iostate, &session,
867 &sh, 64, 64)))
Jens Wiklander02389a92016-12-16 11:13:38 +0100868 goto out_close_session;
Clement Faure13c4de12021-11-02 15:22:22 +0100869 TEEC_CloseSession(&session);
Jens Wiklander02389a92016-12-16 11:13:38 +0100870
871 Do_ADBG_EndSubCase(c, "UDP Socket change port");
872
873 Do_ADBG_BeginSubCase(c, "UDP Socket change addr");
874
875 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
876 &session, &socket_ta_uuid, NULL, &ret_orig)))
877 goto out;
878
879 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_udp_open(&session,
880 TEE_IP_VERSION_DC, ts2.bind->host, ts2.bind->port,
881 &sh, &proto_error, &ret_orig)))
882 goto out_close_session;
883 sock_server_uninit(&ts2);
884 ts2_inited = false;
885
886 port = ts3.bind->port;
887 blen = sizeof(port);
888 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh,
889 TEE_UDP_CHANGEPORT, &port, &blen, &ret_orig)))
890 goto out_close_session;
891
892 blen = strlen(ts3.bind->host) + 1;
893 if (!ADBG_EXPECT_TEEC_SUCCESS(c, socket_ioctl(&session, &sh,
894 TEE_UDP_CHANGEADDR, ts3.bind->host, &blen, &ret_orig)))
895 goto out_close_session;
896
Jens Wiklander4ffddce2021-10-27 17:08:56 +0200897 if (!ADBG_EXPECT_TRUE(c, test_2004_send_recv(c, &server_iostate,
898 &local_iostate, &session,
899 &sh, 64, 64)))
Jens Wiklander02389a92016-12-16 11:13:38 +0100900 goto out_close_session;
Jens Wiklander02389a92016-12-16 11:13:38 +0100901
902 Do_ADBG_EndSubCase(c, "UDP Socket change addr");
903
904
905out_close_session:
906 TEEC_CloseSession(&session);
907out:
908 if (ts_inited)
909 sock_server_uninit(&ts);
910 if (ts2_inited)
911 sock_server_uninit(&ts2);
912 if (ts3_inited)
913 sock_server_uninit(&ts3);
914}
Jens Wiklander02389a92016-12-16 11:13:38 +0100915ADBG_CASE_DEFINE(regression, 2004, xtest_tee_test_2004,
916 "UDP iSocket API tests");