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 <app_mgmt_port_consts.h>
18 #include <app_mgmt_test.h>
19 #include <assert.h>
20 #include <interface/apploader/apploader.h>
21 #include <lib/system_state/system_state.h>
22 #include <lib/tipc/tipc.h>
23 #include <lib/unittest/unittest.h>
24 #include <stddef.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <sys/auxv.h>
28 #include <sys/mman.h>
29 #include <trusty/memref.h>
30 #include <trusty/time.h>
31 #include <trusty_ipc.h>
32 #include <trusty_unittest.h>
33 #include <uapi/err.h>
34 
35 #define TLOG_TAG "app-mgmt-test-client"
36 #define PORT_BASE "com.android.appmgmt-unittest.appmngr"
37 
38 /*
39  * These are expected to occur/elapse in passing test cases and as such there is
40  * a trade off between the degree of confidence provided by the tests and the
41  * runtime of the tests.
42  */
43 #define EXPECTED_TIMEOUT_MS 500
44 #define UNEXPECTED_TIMEOUT_MS 60000
45 #define WAIT_FOR_APP_SLEEP_NS 500000000
46 
47 /*
48  * These tests makes use of one client TA (this file), 7 test server TAs, and
49  * one malformed (unsigned) TA.
50  *
51  * boot-start-srv:
52  *  - Starts at boot
53  *  - Creates BOOT_START_PORT
54  *  - Never exits
55  *  - Does not restart at exit
56  *
57  * dev-only-srv:
58  *  - Starts at boot
59  *  - Tests that this app is only loadable if the unlocked system state flag is
60  *    set and that attempts to load it fails verification otherwise.
61  *  - Does not restart at exit
62  *
63  * never-start-srv:
64  *  - Should never be started
65  *  - Creates NEVER_START_PORT (if ever started i.e. failure case)
66  *  - Exits after receiving a connection
67  *  - Restarts after exiting
68  *
69  * restart-srv:
70  *  - Starts at boot
71  *  - Creates RESTART_PORT
72  *  - Exits after receiving a connection
73  *  - Restarts after exiting
74  *
75  * port-start-srv:
76  *  - Doesn't start at boot
77  *  - Starts on connections to START_PORT
78  *  - Creates START_PORT, CTRL_PORT and SHUTDOWN_PORT
79  *  - Exits after receiving a CMD_EXIT command on START_PORT or a connection on
80  *    SHUTDOWN_PORT
81  *  - Does not restart at exit
82  *
83  * port-start-fail-srv:
84  *  - Doesn't start at boot
85  *  - Fails to start because it requests almost 4GB heap and stack
86  *  - Never runs and thus never exits
87  *
88  * port-waiter-srv:
89  *  - Starts at boot
90  *  - Waits on the port of another loadable app that has yet to load
91  *  - Starts the second app
92  *  - Never exists
93  *  - Does not restart at exit
94  *
95  * unsigned:
96  *  - Tests that loading of malformed app leads to verification failure
97  */
98 
port_start_srv_running(void)99 static bool port_start_srv_running(void) {
100     int rc;
101 
102     trusty_nanosleep(0, 0, WAIT_FOR_APP_SLEEP_NS);
103     rc = connect(CTRL_PORT, IPC_CONNECT_ASYNC);
104     close((handle_t)rc);
105     return rc >= 0;
106 }
107 
chan_send_cmd(handle_t chan,uint8_t cmd)108 static void chan_send_cmd(handle_t chan, uint8_t cmd) {
109     uint8_t rsp;
110     uevent_t uevt;
111 
112     if (HasFailure())
113         return;
114 
115     ASSERT_EQ(sizeof(cmd), tipc_send1(chan, &cmd, sizeof(cmd)));
116     ASSERT_EQ(NO_ERROR, wait(chan, &uevt, INFINITE_TIME));
117     ASSERT_NE(0, uevt.event & IPC_HANDLE_POLL_MSG);
118     ASSERT_EQ(sizeof(rsp), tipc_recv1(chan, sizeof(rsp), &rsp, sizeof(rsp)));
119     ASSERT_EQ(RSP_OK, rsp);
120 
121 test_abort:
122     return;
123 }
124 
125 typedef enum {
126     /* Accepted on connect and served by port-start-srv */
127     MAIN_CHAN,
128 
129     /* Not accepted on connect. Put on pending list when established */
130     PEND_CHAN,
131 
132     /* Not accepted on connect. Put on waiting list when established */
133     WAIT_CHAN,
134 
135     CHAN_COUNT,
136 } chan_idx_t;
137 
138 typedef struct {
139     handle_t chans[CHAN_COUNT];
140 } AppMgrPortStart_t;
141 
send_cmd(AppMgrPortStart_t * state,chan_idx_t idx,uint8_t cmd)142 static void send_cmd(AppMgrPortStart_t* state, chan_idx_t idx, uint8_t cmd) {
143     assert(idx < CHAN_COUNT);
144 
145     if (HasFailure())
146         return;
147 
148     chan_send_cmd(state->chans[idx], cmd);
149 
150 test_abort:
151     return;
152 }
153 
establish_unhandled_channel(AppMgrPortStart_t * state,chan_idx_t idx)154 static void establish_unhandled_channel(AppMgrPortStart_t* state,
155                                         chan_idx_t idx) {
156     int rc;
157     uevent_t uevt;
158     handle_t chan = INVALID_IPC_HANDLE;
159 
160     assert(idx < CHAN_COUNT);
161 
162     if (HasFailure())
163         return;
164 
165     rc = connect(START_PORT, IPC_CONNECT_ASYNC);
166     ASSERT_GE(rc, 0);
167     chan = (handle_t)rc;
168 
169     /* Make sure port-start-srv does not accept the connection */
170     ASSERT_EQ(ERR_TIMED_OUT, wait(chan, &uevt, EXPECTED_TIMEOUT_MS));
171 
172     state->chans[idx] = chan;
173 
174 test_abort:
175     return;
176 }
177 
close_channel(AppMgrPortStart_t * state,chan_idx_t idx)178 static void close_channel(AppMgrPortStart_t* state, chan_idx_t idx) {
179     assert(idx < CHAN_COUNT);
180 
181     if (HasFailure())
182         return;
183 
184     close(state->chans[idx]);
185     state->chans[idx] = INVALID_IPC_HANDLE;
186 }
187 
send_exit(AppMgrPortStart_t * state,chan_idx_t idx)188 static void send_exit(AppMgrPortStart_t* state, chan_idx_t idx) {
189     assert(idx < CHAN_COUNT);
190 
191     if (HasFailure())
192         return;
193 
194     send_cmd(state, idx, CMD_EXIT);
195     close_channel(state, idx);
196 }
197 
wait_and_exit(AppMgrPortStart_t * state,chan_idx_t idx)198 static void wait_and_exit(AppMgrPortStart_t* state, chan_idx_t idx) {
199     uevent_t uevt;
200 
201     assert(idx < CHAN_COUNT);
202 
203     if (HasFailure())
204         return;
205 
206     ASSERT_EQ(NO_ERROR, wait(state->chans[idx], &uevt, INFINITE_TIME));
207     ASSERT_NE(0, IPC_HANDLE_POLL_READY & uevt.event);
208 
209     send_exit(state, idx);
210 
211 test_abort:
212     return;
213 }
214 
send_apploader_request(handle_t channel,uint32_t cmd,void * req,size_t req_size,handle_t handle)215 static void send_apploader_request(handle_t channel,
216                                    uint32_t cmd,
217                                    void* req,
218                                    size_t req_size,
219                                    handle_t handle) {
220     if (HasFailure())
221         return;
222 
223     struct apploader_header hdr = {
224             .cmd = cmd,
225     };
226     struct iovec iov[2] = {{&hdr, sizeof(hdr)}, {req, req_size}};
227     ipc_msg_t msg = {
228             .iov = iov,
229             .num_iov = (req && req_size) ? 2 : 1,
230             .handles = &handle,
231             .num_handles = (handle != INVALID_IPC_HANDLE) ? 1 : 0,
232     };
233 
234     int rc;
235     rc = send_msg(channel, &msg);
236     ASSERT_EQ(rc, (ssize_t)sizeof(hdr) + (ssize_t)req_size);
237 
238 test_abort:;
239 }
240 
read_apploader_response(handle_t channel,uint32_t cmd,handle_t * handles,size_t num_handles,ipc_msg_info_t * msg_inf)241 static uint32_t read_apploader_response(handle_t channel,
242                                         uint32_t cmd,
243                                         handle_t* handles,
244                                         size_t num_handles,
245                                         ipc_msg_info_t* msg_inf) {
246     int rc;
247     struct apploader_resp resp;
248     ASSERT_EQ(msg_inf->len, sizeof(resp));
249 
250     struct iovec iov = {
251             .iov_base = (void*)&resp,
252             .iov_len = sizeof(resp),
253     };
254     ipc_msg_t msg = {
255             .iov = &iov,
256             .num_iov = 1,
257             .handles = handles,
258             .num_handles = num_handles,
259     };
260     rc = read_msg(channel, msg_inf->id, 0, &msg);
261     ASSERT_EQ(rc, (ssize_t)sizeof(resp));
262     ASSERT_EQ(resp.hdr.cmd, cmd | APPLOADER_RESP_BIT);
263 
264     return resp.error;
265 
266 test_abort:
267     return 0;
268 }
269 
recv_apploader_response(handle_t channel,uint32_t cmd,handle_t * handles,size_t num_handles)270 static uint32_t recv_apploader_response(handle_t channel,
271                                         uint32_t cmd,
272                                         handle_t* handles,
273                                         size_t num_handles) {
274     int rc;
275     struct uevent event;
276     ipc_msg_info_t msg_inf;
277 
278     if (HasFailure())
279         return 0;
280 
281     rc = wait(channel, &event, INFINITE_TIME);
282     ASSERT_EQ(rc, NO_ERROR);
283     ASSERT_NE(event.event & IPC_HANDLE_POLL_MSG, 0);
284 
285     rc = get_msg(channel, &msg_inf);
286     ASSERT_EQ(rc, NO_ERROR);
287 
288     rc = read_apploader_response(channel, cmd, handles, num_handles, &msg_inf);
289     put_msg(channel, msg_inf.id);
290     return rc;
291 
292 test_abort:
293     return 0;
294 }
295 
load_app(char * app_begin,char * app_end)296 static uint32_t load_app(char* app_begin, char* app_end) {
297     int rc;
298     handle_t chan = INVALID_IPC_HANDLE;
299     handle_t handle = INVALID_IPC_HANDLE;
300 
301     rc = connect(APPLOADER_PORT, IPC_CONNECT_WAIT_FOR_PORT);
302     ASSERT_GT(rc, 0);
303     chan = (handle_t)rc;
304 
305     uint64_t page_size = getauxval(AT_PAGESZ);
306     ptrdiff_t app_size = app_end - app_begin;
307     size_t aligned_app_size = round_up(app_size, page_size);
308 
309     handle = memref_create(app_begin, aligned_app_size, MMAP_FLAG_PROT_READ);
310     ASSERT_GT(handle, 0);
311 
312     struct apploader_load_app_req req = {
313             .package_size = app_size,
314     };
315     send_apploader_request(chan, APPLOADER_CMD_LOAD_APPLICATION, &req,
316                            sizeof(req), handle);
317     ASSERT_EQ(false, HasFailure());
318 
319     uint32_t error;
320     error = recv_apploader_response(chan, APPLOADER_CMD_LOAD_APPLICATION, NULL,
321                                     0);
322     ASSERT_EQ(false, HasFailure());
323 
324     /* Wait for a bit for the app to start properly */
325     if (error == APPLOADER_NO_ERROR) {
326         trusty_nanosleep(0, 0, WAIT_FOR_APP_SLEEP_NS);
327     }
328 
329     close(handle);
330     close(chan);
331 
332     return error;
333 
334 test_abort:
335     if (handle > 0) {
336         close(handle);
337     }
338     close(chan);
339     return 0;
340 }
341 
342 extern char boot_start_app_begin[], boot_start_app_end[];
343 extern char never_start_app_begin[], never_start_app_end[];
344 extern char port_start_app_begin[], port_start_app_end[];
345 extern char port_start_fail_app_begin[], port_start_fail_app_end[];
346 extern char restart_app_begin[], restart_app_end[];
347 extern char port_waiter_app_begin[], port_waiter_app_end[];
348 extern char unsigned_app_begin[], unsigned_app_end[];
349 extern char dev_only_app_begin[], dev_only_app_end[];
350 
351 /*
352  * Loading an application the a second time should return
353  * APPLOADER_ERR_ALREADY_EXISTS. This test should be the first
354  * in the file to load boot-start-srv so we test both proper
355  * application loading and the second load attempt.
356  */
TEST(AppMgrBoot,DoubleLoad)357 TEST(AppMgrBoot, DoubleLoad) {
358     uint32_t error;
359 
360     error = load_app(boot_start_app_begin, boot_start_app_end);
361     ASSERT_EQ(false, HasFailure());
362     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
363                             error == APPLOADER_ERR_ALREADY_EXISTS);
364     if (error == APPLOADER_ERR_ALREADY_EXISTS) {
365         trusty_unittest_printf("[  WARNING ] boot-start-srv already loaded\n");
366     }
367 
368     error = load_app(boot_start_app_begin, boot_start_app_end);
369     ASSERT_EQ(false, HasFailure());
370     ASSERT_EQ(error, APPLOADER_ERR_ALREADY_EXISTS);
371 
372 test_abort:;
373 }
374 
375 /*
376  * Start an app that waits on the port of another loadable app that has not
377  * been loaded yet, then start the second app. The kernel should correctly wake
378  * up the first app after loading the second.
379  */
TEST(AppMgrWaitForPort,WaitConnectForPort)380 TEST(AppMgrWaitForPort, WaitConnectForPort) {
381     int rc;
382     handle_t chan = INVALID_IPC_HANDLE;
383     struct uevent uevt;
384     uint8_t rsp;
385 
386     /*
387      * port-start-srv should not be running
388      * TODO: unload it ourselves when app unloading is supported; until then,
389      * we only allow this test to be run once per boot, and it needs to be the
390      * first one in the file.
391      */
392     static bool skip = false;
393     if (skip) {
394         trusty_unittest_printf(
395                 "[  SKIPPED ] Can't run second time without unloading.\n");
396         return;
397     }
398     skip = true;
399     ASSERT_EQ(false, port_start_srv_running());
400 
401     /* Load port-waiter-srv */
402     uint32_t load_error = load_app(port_waiter_app_begin, port_waiter_app_end);
403     ASSERT_EQ(false, HasFailure());
404     ASSERT_EQ(true, load_error == APPLOADER_NO_ERROR ||
405                             load_error == APPLOADER_ERR_ALREADY_EXISTS);
406 
407     /* Load port-start-srv now, which should wake up port-waiter-srv */
408     load_error = load_app(port_start_app_begin, port_start_app_end);
409     ASSERT_EQ(false, HasFailure());
410     ASSERT_EQ(load_error, APPLOADER_NO_ERROR);
411 
412     /* Connect to port-waiter-srv */
413     rc = connect(PORT_WAITER_PORT,
414                  IPC_CONNECT_ASYNC | IPC_CONNECT_WAIT_FOR_PORT);
415     ASSERT_GE(rc, 0);
416     chan = (handle_t)rc;
417 
418     ASSERT_EQ(NO_ERROR, wait(chan, &uevt, UNEXPECTED_TIMEOUT_MS));
419     ASSERT_NE(0, uevt.event & IPC_HANDLE_POLL_READY);
420     if (!(uevt.event & IPC_HANDLE_POLL_MSG)) {
421         ASSERT_EQ(NO_ERROR, wait(chan, &uevt, INFINITE_TIME));
422         ASSERT_NE(0, uevt.event & IPC_HANDLE_POLL_MSG);
423     }
424     ASSERT_EQ(sizeof(rsp), tipc_recv1(chan, sizeof(rsp), &rsp, sizeof(rsp)));
425     ASSERT_EQ(RSP_OK, rsp);
426 
427 test_abort:
428     close(chan);
429 }
430 
AppMgrPortStart_SetUp(AppMgrPortStart_t * state)431 static void AppMgrPortStart_SetUp(AppMgrPortStart_t* state) {
432     int rc;
433     uevent_t uevt;
434     handle_t chan;
435 
436     uint32_t error = load_app(port_start_app_begin, port_start_app_end);
437     ASSERT_EQ(false, HasFailure());
438     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
439                             error == APPLOADER_ERR_ALREADY_EXISTS);
440 
441     for (size_t i = 0; i < CHAN_COUNT; i++) {
442         state->chans[i] = INVALID_IPC_HANDLE;
443     }
444 
445     /* Shutdown port-start-srv in case it is running from a previous test */
446     rc = connect(SHUTDOWN_PORT, IPC_CONNECT_ASYNC);
447     if (rc > 0) {
448         /* SHUTDOWN_PORT exists so the srv was running. Wait for it to exit */
449         chan = (handle_t)rc;
450         rc = wait(chan, &uevt, INFINITE_TIME);
451         close(chan);
452         ASSERT_GE(rc, 0);
453         ASSERT_NE(0, uevt.event & IPC_HANDLE_POLL_HUP);
454     }
455 
456     /* port-start-srv should not be running */
457     ASSERT_EQ(false, port_start_srv_running());
458 
459     /* Start and connect to port-start-srv */
460     rc = connect(START_PORT, 0);
461     ASSERT_GE(rc, 0);
462 
463     state->chans[MAIN_CHAN] = (handle_t)rc;
464 
465 test_abort:
466     return;
467 }
468 
AppMgrPortStart_TearDown(AppMgrPortStart_t * state)469 static void AppMgrPortStart_TearDown(AppMgrPortStart_t* state) {
470     ASSERT_EQ(false, HasFailure());
471 
472     /* port-start-srv should not be running at the end of a test */
473     ASSERT_EQ(false, port_start_srv_running());
474 
475     for (size_t i = 0; i < CHAN_COUNT; i++) {
476         ASSERT_EQ(INVALID_IPC_HANDLE, state->chans[i]);
477     }
478 
479 test_abort:
480     for (size_t i = 0; i < CHAN_COUNT; i++) {
481         close(state->chans[i]);
482     }
483 }
484 
485 /* Apps with deferred start should not start at boot */
TEST(AppMgrBoot,BootStartNegative)486 TEST(AppMgrBoot, BootStartNegative) {
487     int rc;
488 
489     uint32_t error = load_app(never_start_app_begin, never_start_app_end);
490     ASSERT_EQ(false, HasFailure());
491     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
492                             error == APPLOADER_ERR_ALREADY_EXISTS);
493 
494     /* never-start-srv should not be running */
495     rc = connect(NEVER_START_PORT, IPC_CONNECT_ASYNC);
496     EXPECT_LT(rc, 0);
497     close((handle_t)rc);
498 
499 test_abort:;
500 }
501 
502 /* Apps without deferred should start at boot */
TEST(AppMgrBoot,BootStartPositive)503 TEST(AppMgrBoot, BootStartPositive) {
504     int rc;
505 
506     uint32_t error = load_app(boot_start_app_begin, boot_start_app_end);
507     ASSERT_EQ(false, HasFailure());
508     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
509                             error == APPLOADER_ERR_ALREADY_EXISTS);
510 
511     /* boot-start-srv should be running from boot */
512     rc = connect(BOOT_START_PORT, IPC_CONNECT_ASYNC);
513     EXPECT_GE(rc, 0);
514     close((handle_t)rc);
515 
516 test_abort:;
517 }
518 
519 /* Apps with automatic restart should restart after exiting */
TEST(AppMgrRestart,AppRestartPositive)520 TEST(AppMgrRestart, AppRestartPositive) {
521     int rc;
522     uevent_t uevt;
523     handle_t chan = INVALID_IPC_HANDLE;
524 
525     uint32_t error = load_app(restart_app_begin, restart_app_end);
526     ASSERT_EQ(false, HasFailure());
527     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
528                             error == APPLOADER_ERR_ALREADY_EXISTS);
529 
530     /* restart-srv should be running from boot or a previous restart */
531     rc = connect(RESTART_PORT, IPC_CONNECT_ASYNC | IPC_CONNECT_WAIT_FOR_PORT);
532     ASSERT_GE(rc, 0);
533 
534     /* Wait for restart-srv to initiate shutdown */
535     chan = (handle_t)rc;
536     ASSERT_EQ(NO_ERROR, wait(chan, &uevt, INFINITE_TIME));
537     ASSERT_NE(0, IPC_HANDLE_POLL_HUP & uevt.event);
538     close(chan);
539 
540     /* restart-srv should eventually restart */
541     rc = connect(RESTART_PORT, IPC_CONNECT_ASYNC | IPC_CONNECT_WAIT_FOR_PORT);
542     ASSERT_GE(rc, 0);
543     chan = (handle_t)rc;
544 
545 test_abort:
546     close(chan);
547 }
548 
549 /*
550  * Apps without automatic restart should not restart after exiting
551  * Start ports should start an app on connection
552  */
TEST(AppMgrRestart,AppRestartNegativePortStartPositive)553 TEST(AppMgrRestart, AppRestartNegativePortStartPositive) {
554     int rc;
555     handle_t chan = INVALID_IPC_HANDLE;
556 
557     uint32_t error = load_app(port_start_app_begin, port_start_app_end);
558     ASSERT_EQ(false, HasFailure());
559     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
560                             error == APPLOADER_ERR_ALREADY_EXISTS);
561 
562     /* Start and connect to port-start-srv */
563     rc = connect(START_PORT, 0);
564     ASSERT_GE(rc, 0);
565     chan = (handle_t)rc;
566 
567     /* Shutdown port-start-srv */
568     chan_send_cmd(chan, CMD_EXIT);
569     ASSERT_EQ(false, HasFailure());
570 
571     /* port-start-srv should not restart */
572     ASSERT_EQ(false, port_start_srv_running());
573 
574 test_abort:
575     close(chan);
576 }
577 
578 /* Regular ports should not start an app on connection */
TEST(AppMgrPortStartFail,PortStartFail)579 TEST(AppMgrPortStartFail, PortStartFail) {
580     /*
581      * TODO: If no unloading, on the second run port is already in 'cancelled'
582      * state, so running the test second time makes no sense, just skip it.
583      */
584     static bool skip = false;
585     if (skip) {
586         trusty_unittest_printf(
587                 "[  SKIPPED ] Can't run second time without unloading.\n");
588         return;
589     }
590     skip = true;
591 
592     int rc;
593     handle_t chan = INVALID_IPC_HANDLE;
594     uevent_t uevt;
595 
596     uint32_t error =
597             load_app(port_start_fail_app_begin, port_start_fail_app_end);
598     ASSERT_EQ(false, HasFailure());
599     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
600                             error == APPLOADER_ERR_ALREADY_EXISTS);
601 
602     /*
603      * A connection to START_FAIL_PORT should fail to start the
604      * port-start-fail-srv app, but it will first create a handle we can wait on
605      */
606     rc = connect(START_FAIL_PORT, IPC_CONNECT_ASYNC);
607     ASSERT_GE(rc, 0);
608 
609     /* Wait for kernel to shut down channel after failing to start app */
610     chan = (handle_t)rc;
611     ASSERT_EQ(NO_ERROR, wait(chan, &uevt, UNEXPECTED_TIMEOUT_MS));
612     ASSERT_NE(0, IPC_HANDLE_POLL_HUP & uevt.event);
613     close(chan);
614 
615     /* Try again to make sure we get ERR_CANCELLED the second time */
616     rc = connect(START_FAIL_PORT, IPC_CONNECT_ASYNC);
617     ASSERT_EQ(ERR_CANCELLED, rc);
618 
619 test_abort:;
620 }
621 
622 /* Regular ports should not start an app on connection */
TEST(AppMgrPortStartNegative,PortStartNegative)623 TEST(AppMgrPortStartNegative, PortStartNegative) {
624     int rc;
625 
626     uint32_t error = load_app(port_start_app_begin, port_start_app_end);
627     ASSERT_EQ(false, HasFailure());
628     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
629                             error == APPLOADER_ERR_ALREADY_EXISTS);
630 
631     /* A connection to CTRL_PORT should not start port-start-srv */
632     rc = connect(CTRL_PORT, IPC_CONNECT_ASYNC);
633     EXPECT_LT(rc, 0);
634     close((handle_t)rc);
635 
636 test_abort:;
637 }
638 
639 /* Start ports with closed pending connections should not start an app */
TEST_F(AppMgrPortStart,PortStartPendingNegative)640 TEST_F(AppMgrPortStart, PortStartPendingNegative) {
641     /* Create a pending connection */
642     establish_unhandled_channel(_state, PEND_CHAN);
643 
644     /* Close the pending connection */
645     close_channel(_state, PEND_CHAN);
646 
647     /* Close the main channel and shutdown port-start-srv */
648     send_exit(_state, MAIN_CHAN);
649 
650 test_abort:;
651 }
652 
653 /* Start ports with pending connections should start an app */
TEST_F(AppMgrPortStart,PortStartPendingPositive)654 TEST_F(AppMgrPortStart, PortStartPendingPositive) {
655     /* Create a pending connection */
656     establish_unhandled_channel(_state, PEND_CHAN);
657 
658     /* Close the main channel and shutdown port-start-srv */
659     send_exit(_state, MAIN_CHAN);
660 
661     /*
662      * Wait for port-start-srv to restart due to the pending connection and then
663      * shut it down
664      */
665     wait_and_exit(_state, PEND_CHAN);
666 }
667 
668 /* Closed connections waiting for a start port should not start an app */
TEST_F(AppMgrPortStart,PortStartWaitingNegative)669 TEST_F(AppMgrPortStart, PortStartWaitingNegative) {
670     /* Make port-start-srv close START_PORT */
671     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
672 
673     /* Create a waiting connection */
674     establish_unhandled_channel(_state, WAIT_CHAN);
675 
676     /* Close the waiting connection */
677     close_channel(_state, WAIT_CHAN);
678 
679     /* Close the main channel and shutdown port-start-srv */
680     send_exit(_state, MAIN_CHAN);
681 }
682 
683 /* Connections waiting for a start port should start an app */
TEST_F(AppMgrPortStart,PortStartWaitingPositive)684 TEST_F(AppMgrPortStart, PortStartWaitingPositive) {
685     /* Make port-start-srv close START_PORT */
686     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
687 
688     /* Create a waiting connection */
689     establish_unhandled_channel(_state, WAIT_CHAN);
690 
691     /* Close the main channel and shutdown port-start-srv */
692     send_exit(_state, MAIN_CHAN);
693 
694     /*
695      * Wait for port-start-srv to restart due to the waiting connection and then
696      * shut it down
697      */
698     wait_and_exit(_state, WAIT_CHAN);
699 }
700 
701 /*
702  * Closed waiting connections that were pending on a start port should not start
703  * an app
704  */
TEST_F(AppMgrPortStart,PortStartPendingToWaitingNegative)705 TEST_F(AppMgrPortStart, PortStartPendingToWaitingNegative) {
706     /* Create a pending connection */
707     establish_unhandled_channel(_state, PEND_CHAN);
708 
709     /*
710      * Make port-start-srv close START_PORT (the pending connection becomes
711      * waiting)
712      */
713     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
714 
715     /* Close the waiting connection */
716     close_channel(_state, PEND_CHAN);
717 
718     /* Close the main channel and shutdown port-start-srv */
719     send_exit(_state, MAIN_CHAN);
720 }
721 
722 /*
723  * Waiting connections that were pending on a start port should start an app
724  */
TEST_F(AppMgrPortStart,PortStartPendingToWaitingPositive)725 TEST_F(AppMgrPortStart, PortStartPendingToWaitingPositive) {
726     /* Create a pending connection */
727     establish_unhandled_channel(_state, PEND_CHAN);
728 
729     /*
730      * Make port-start-srv close START_PORT (the pending connection becomes
731      * waiting)
732      */
733     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
734 
735     /* Close the main channel and shutdown port-start-srv */
736     send_exit(_state, MAIN_CHAN);
737 
738     /*
739      * Wait for port-start-srv to restart due to the waiting connection and then
740      * shut it down
741      */
742     wait_and_exit(_state, PEND_CHAN);
743 }
744 
745 /*
746  * Start ports with closed pending connections that were waiting for the port
747  * should not start an app
748  */
TEST_F(AppMgrPortStart,PortStartWaitingToPendingNegative)749 TEST_F(AppMgrPortStart, PortStartWaitingToPendingNegative) {
750     /* Make port-start-srv close START_PORT */
751     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
752 
753     /* Create a waiting connection */
754     establish_unhandled_channel(_state, WAIT_CHAN);
755 
756     /*
757      * Make port-start-srv open START_PORT (the waiting connection becomes
758      * pending)
759      */
760     send_cmd(_state, MAIN_CHAN, CMD_OPEN_PORT);
761 
762     /* Close the pending connection */
763     close_channel(_state, WAIT_CHAN);
764 
765     /* Close the main channel and shutdown port-start-srv */
766     send_exit(_state, MAIN_CHAN);
767 }
768 
769 /*
770  * Start ports with pending connections that were waiting for the port should
771  * start an app
772  */
TEST_F(AppMgrPortStart,PortStartWaitingToPendingPositive)773 TEST_F(AppMgrPortStart, PortStartWaitingToPendingPositive) {
774     /* Make port-start-srv close START_PORT */
775     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
776 
777     /* Create a waiting connection */
778     establish_unhandled_channel(_state, WAIT_CHAN);
779 
780     /*
781      * Make port-start-srv open START_PORT (the waiting connection becomes
782      * pending)
783      */
784     send_cmd(_state, MAIN_CHAN, CMD_OPEN_PORT);
785 
786     /* Close the main channel and shutdown port-start-srv */
787     send_exit(_state, MAIN_CHAN);
788 
789     /*
790      * Wait for port-start-srv to restart due to the pending connection and then
791      * shut it down
792      */
793     wait_and_exit(_state, WAIT_CHAN);
794 }
795 
796 /*
797  * Closed connections waiting for a start port with closed pending connections
798  * should not start an app
799  */
TEST_F(AppMgrPortStart,PortStartPendingWaitingNegative)800 TEST_F(AppMgrPortStart, PortStartPendingWaitingNegative) {
801     /* Create a pending connection */
802     establish_unhandled_channel(_state, PEND_CHAN);
803 
804     /*
805      * Make port-start-srv close START_PORT (the pending connection becomes
806      * waiting)
807      */
808     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
809 
810     /* Create a waiting connection */
811     establish_unhandled_channel(_state, WAIT_CHAN);
812 
813     /* Close the first waiting connection */
814     close_channel(_state, PEND_CHAN);
815 
816     /* Close the second waiting connection */
817     close_channel(_state, WAIT_CHAN);
818 
819     /* Close the main channel and shutdown port-start-srv */
820     send_exit(_state, MAIN_CHAN);
821 }
822 
823 /*
824  * Connections waiting for a start port with pending connections should start
825  * an app
826  */
TEST_F(AppMgrPortStart,PortStartPendingWaitingPositive)827 TEST_F(AppMgrPortStart, PortStartPendingWaitingPositive) {
828     /* Create a pending connection */
829     establish_unhandled_channel(_state, PEND_CHAN);
830 
831     /*
832      * Make port-start-srv close START_PORT (the pending connection becomes
833      * waiting)
834      */
835     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
836 
837     /* Create a waiting connection */
838     establish_unhandled_channel(_state, WAIT_CHAN);
839 
840     /* Close the main channel and shutdown port-start-srv */
841     send_exit(_state, MAIN_CHAN);
842 
843     /*
844      * Wait for port-start-srv to restart due to the first waiting connection
845      * and then shut it down
846      */
847     wait_and_exit(_state, PEND_CHAN);
848 
849     /*
850      * wait for port-start-srv to restart due to the second waiting connection
851      * and then shut it down
852      */
853     wait_and_exit(_state, WAIT_CHAN);
854 }
855 
856 /*
857  * Connections waiting for a start port with closed pending connections should
858  * start an app
859  */
TEST_F(AppMgrPortStart,PortStartPendingClosedWaitingPositive)860 TEST_F(AppMgrPortStart, PortStartPendingClosedWaitingPositive) {
861     /* Create a pending connection */
862     establish_unhandled_channel(_state, PEND_CHAN);
863 
864     /*
865      * Make port-start-srv close START_PORT (the pending connection becomes
866      * waiting)
867      */
868     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
869 
870     /* Create a waiting connection */
871     establish_unhandled_channel(_state, WAIT_CHAN);
872 
873     /* Close the first waiting connection */
874     close_channel(_state, PEND_CHAN);
875 
876     /* Close the main channel and shutdown port-start-srv */
877     send_exit(_state, MAIN_CHAN);
878 
879     /*
880      * wait for port-start-srv to restart due to the second waiting connection
881      * and then shut it down
882      */
883     wait_and_exit(_state, WAIT_CHAN);
884 }
885 
886 /*
887  * Start ports with pending connections and with closed connections waiting for
888  * the port should start an app
889  */
TEST_F(AppMgrPortStart,PortStartPendingWaitingClosedPositive)890 TEST_F(AppMgrPortStart, PortStartPendingWaitingClosedPositive) {
891     /* Create a pending connection */
892     establish_unhandled_channel(_state, PEND_CHAN);
893 
894     /*
895      * Make port-start-srv close START_PORT (the pending connection becomes
896      * waiting)
897      */
898     send_cmd(_state, MAIN_CHAN, CMD_CLOSE_PORT);
899 
900     /* Create a waiting connection */
901     establish_unhandled_channel(_state, WAIT_CHAN);
902 
903     /* Close the second waiting connection */
904     close_channel(_state, WAIT_CHAN);
905 
906     /* Close the main channel and shutdown port-start-srv */
907     send_exit(_state, MAIN_CHAN);
908 
909     /*
910      * wait for port-start-srv to restart due to the first waiting connection
911      * and then shut it down
912      */
913     wait_and_exit(_state, PEND_CHAN);
914 }
915 
916 /*
917  * Connecting to an app's start port as it terminating should always restart the
918  * app
919  */
TEST(AppMgrPortStartRacingTerminate,PortStartRacingTerminate)920 TEST(AppMgrPortStartRacingTerminate, PortStartRacingTerminate) {
921     int rc;
922     handle_t chan = INVALID_IPC_HANDLE;
923     uevent_t uevt;
924     uint32_t error = load_app(port_start_app_begin, port_start_app_end);
925     ASSERT_EQ(false, HasFailure());
926     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
927                             error == APPLOADER_ERR_ALREADY_EXISTS);
928 
929     /* Connect to the start port triggering app start */
930     rc = connect(START_PORT, IPC_CONNECT_ASYNC);
931     ASSERT_GE(rc, 0);
932     chan = (handle_t)rc;
933 
934     /* Make sure port-start-srv started successfully */
935     ASSERT_EQ(0, wait(chan, &uevt, UNEXPECTED_TIMEOUT_MS));
936     ASSERT_NE(0, IPC_HANDLE_POLL_READY & uevt.event);
937     ASSERT_EQ(true, port_start_srv_running());
938 
939     /* Close the main channel and shutdown port-start-srv */
940     chan_send_cmd(chan, CMD_EXIT);
941     ASSERT_EQ(false, HasFailure());
942     close(chan);
943 
944     /* Immediately reconnect to the start port triggering app start */
945     rc = connect(START_PORT, IPC_CONNECT_ASYNC);
946     ASSERT_GE(rc, 0);
947     chan = (handle_t)rc;
948 
949     /* Make sure port-start-srv started successfully */
950     ASSERT_EQ(0, wait(chan, &uevt, UNEXPECTED_TIMEOUT_MS));
951     ASSERT_NE(0, IPC_HANDLE_POLL_READY & uevt.event);
952     ASSERT_EQ(true, port_start_srv_running());
953 
954     /* Close the main channel and shutdown port-start-srv */
955     chan_send_cmd(chan, CMD_EXIT);
956     ASSERT_EQ(false, HasFailure());
957 
958 test_abort:
959     close(chan);
960 }
961 
962 /* Test loading an unsigned app */
TEST(AppLoader,UnsignedApp)963 TEST(AppLoader, UnsignedApp) {
964     uint32_t error = load_app(unsigned_app_begin, unsigned_app_end);
965     ASSERT_EQ(false, HasFailure());
966     ASSERT_EQ(APPLOADER_ERR_VERIFICATION_FAILED, error);
967 
968 test_abort:;
969 }
970 
971 /*
972  * Dev apploader keys should only be available when the system state service
973  * indicates that the system is in an unlocked state. This app is signed with
974  * apploader slot 1, which is the dev key and therefore must only load in the
975  * unlocked state.
976  */
TEST(AppMgrBoot,UnlockedDevLoad)977 TEST(AppMgrBoot, UnlockedDevLoad) {
978     uint32_t error = load_app(dev_only_app_begin, dev_only_app_end);
979     ASSERT_EQ(false, HasFailure());
980 
981     if (system_state_app_loading_unlocked()) {
982         ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
983                                 error == APPLOADER_ERR_ALREADY_EXISTS);
984     } else {
985         EXPECT_EQ(APPLOADER_ERR_VERIFICATION_FAILED, error);
986     }
987 
988 test_abort:;
989 }
990 
run_appmngr_tests(struct unittest * test)991 static bool run_appmngr_tests(struct unittest* test) {
992     return RUN_ALL_TESTS();
993 }
994 
run_appmngr_stress_tests(struct unittest * test)995 static bool run_appmngr_stress_tests(struct unittest* test) {
996     while (RUN_ALL_TESTS()) {
997     }
998 
999     return false;
1000 }
1001 
main(void)1002 int main(void) {
1003     static struct unittest appmgmt_unittests[] = {
1004             {
1005                     .port_name = PORT_BASE,
1006                     .run_test = run_appmngr_tests,
1007             },
1008             {
1009                     .port_name = PORT_BASE ".stress",
1010                     .run_test = run_appmngr_stress_tests,
1011             },
1012     };
1013     struct unittest* unittests[countof(appmgmt_unittests)];
1014 
1015     for (size_t i = 0; i < countof(appmgmt_unittests); i++)
1016         unittests[i] = &appmgmt_unittests[i];
1017 
1018     return unittest_main(unittests, countof(unittests));
1019 }
1020