1 /*
2  * Copyright (C) 2020 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 <interface/apploader/apploader.h>
18 #include <interface/apploader/apploader_secure.h>
19 #include <inttypes.h>
20 #include <lib/system_state/system_state.h>
21 #include <lib/tipc/tipc.h>
22 #include <lib/unittest/unittest.h>
23 #include <stdlib.h>
24 #include <sys/auxv.h>
25 #include <sys/mman.h>
26 #include <trusty/memref.h>
27 #include <trusty/string.h>
28 #include <trusty_unittest.h>
29 #include <uapi/err.h>
30 
31 #define TLOG_TAG "apploader-unittest"
32 
make_request(handle_t channel,uint32_t cmd,void * req,size_t req_size,handle_t req_handle,handle_t * resp_handles,size_t num_resp_handles)33 static uint32_t make_request(handle_t channel,
34                              uint32_t cmd,
35                              void* req,
36                              size_t req_size,
37                              handle_t req_handle,
38                              handle_t* resp_handles,
39                              size_t num_resp_handles) {
40     struct uevent event;
41     ipc_msg_info_t msg_inf;
42     bool got_msg = false;
43     struct apploader_resp resp;
44 
45     if (HasFailure()) {
46         return 0;
47     }
48 
49     struct apploader_header hdr = {
50             .cmd = cmd,
51     };
52     struct iovec req_iov[2] = {{&hdr, sizeof(hdr)}, {req, req_size}};
53     ipc_msg_t req_msg = {
54             .iov = req_iov,
55             .num_iov = (req && req_size) ? 2 : 1,
56             .handles = &req_handle,
57             .num_handles = (req_handle != INVALID_IPC_HANDLE) ? 1 : 0,
58     };
59 
60     int rc;
61     rc = send_msg(channel, &req_msg);
62     ASSERT_EQ(rc, (ssize_t)sizeof(hdr) + (ssize_t)req_size);
63 
64     rc = wait(channel, &event, INFINITE_TIME);
65     ASSERT_EQ(rc, NO_ERROR);
66     ASSERT_NE(event.event & IPC_HANDLE_POLL_MSG, 0);
67 
68     rc = get_msg(channel, &msg_inf);
69     ASSERT_EQ(rc, NO_ERROR);
70 
71     got_msg = true;
72     ASSERT_EQ(msg_inf.len, sizeof(resp));
73 
74     struct iovec resp_iov = {
75             .iov_base = (void*)&resp,
76             .iov_len = sizeof(resp),
77     };
78     ipc_msg_t resp_msg = {
79             .iov = &resp_iov,
80             .num_iov = 1,
81             .handles = resp_handles,
82             .num_handles = num_resp_handles,
83     };
84     rc = read_msg(channel, msg_inf.id, 0, &resp_msg);
85     ASSERT_EQ(rc, (ssize_t)sizeof(resp));
86     ASSERT_EQ(resp.hdr.cmd, cmd | APPLOADER_RESP_BIT);
87 
88     put_msg(channel, msg_inf.id);
89     return resp.error;
90 
91 test_abort:
92     if (got_msg) {
93         put_msg(channel, msg_inf.id);
94     }
95     return 0;
96 }
97 
load_test_app(handle_t channel,char * app_start,char * app_end)98 static uint32_t load_test_app(handle_t channel,
99                               char* app_start,
100                               char* app_end) {
101     uint32_t error = 0;
102 
103     uint64_t page_size = getauxval(AT_PAGESZ);
104     ptrdiff_t app_size = app_end - app_start;
105     size_t aligned_app_size = round_up(app_size, page_size);
106 
107     handle_t handle;
108     handle = memref_create(app_start, aligned_app_size, MMAP_FLAG_PROT_READ);
109     ASSERT_GT(handle, 0);
110 
111     struct apploader_load_app_req req = {
112             .package_size = app_size,
113     };
114     error = make_request(channel, APPLOADER_CMD_LOAD_APPLICATION, &req,
115                          sizeof(req), handle, NULL, 0);
116 
117 test_abort:
118     if (handle > 0) {
119         close(handle);
120     }
121     return error;
122 }
123 
get_memory_buffer_from_malloc(size_t size,handle_t * handle_ptr)124 static void* get_memory_buffer_from_malloc(size_t size, handle_t* handle_ptr) {
125     if (HasFailure()) {
126         return NULL;
127     }
128 
129     uint64_t page_size = getauxval(AT_PAGESZ);
130     size = round_up(size, page_size);
131 
132     void* base = memalign(page_size, size);
133     ASSERT_NE(base, NULL);
134 
135     if (handle_ptr) {
136         int rc = memref_create(base, size,
137                                MMAP_FLAG_PROT_READ | MMAP_FLAG_PROT_WRITE);
138         ASSERT_GE(rc, 0);
139         *handle_ptr = (handle_t)rc;
140     }
141 
142     return base;
143 
144 test_abort:
145     if (base) {
146         free(base);
147     }
148     return NULL;
149 }
150 
get_memory_handle_from_service(handle_t channel,size_t size)151 static handle_t get_memory_handle_from_service(handle_t channel, size_t size) {
152     if (HasFailure()) {
153         return INVALID_IPC_HANDLE;
154     }
155 
156     uint32_t error;
157     handle_t handle;
158     struct apploader_secure_get_memory_req req = {
159             .package_size = size,
160     };
161     error = make_request(channel, APPLOADER_SECURE_CMD_GET_MEMORY, &req,
162                          sizeof(req), INVALID_IPC_HANDLE, &handle, 1);
163     ASSERT_EQ(false, HasFailure());
164     ASSERT_EQ(error, APPLOADER_NO_ERROR);
165     ASSERT_NE(handle, INVALID_IPC_HANDLE);
166 
167     return handle;
168 
169 test_abort:
170     return INVALID_IPC_HANDLE;
171 }
172 
get_memory_buffer_from_service(handle_t channel,size_t size)173 static void* get_memory_buffer_from_service(handle_t channel, size_t size) {
174     if (HasFailure()) {
175         return NULL;
176     }
177 
178     handle_t handle = get_memory_handle_from_service(channel, size);
179     ASSERT_EQ(false, HasFailure());
180     ASSERT_NE(handle, INVALID_IPC_HANDLE);
181 
182     void* buf = mmap(NULL, size, PROT_READ | PROT_WRITE, 0, handle, 0);
183     ASSERT_NE(buf, MAP_FAILED);
184 
185     close(handle);
186 
187     return buf;
188 
189 test_abort:
190     if (handle != INVALID_IPC_HANDLE) {
191         close(handle);
192     }
193     return NULL;
194 }
195 
196 typedef struct apploader_user {
197     handle_t channel;
198 } apploader_user_t;
199 
TEST_F_SETUP(apploader_user)200 TEST_F_SETUP(apploader_user) {
201     int rc;
202 
203     rc = connect(APPLOADER_PORT, IPC_CONNECT_WAIT_FOR_PORT);
204     _state->channel = (handle_t)rc;
205     ASSERT_GE(_state->channel, 0);
206 
207 test_abort:;
208 }
209 
TEST_F_TEARDOWN(apploader_user)210 TEST_F_TEARDOWN(apploader_user) {
211     close(_state->channel);
212 }
213 
214 #define UNKNOWN_CMD 0xffff0000U
215 
TEST_F(apploader_user,UnknownCmd)216 TEST_F(apploader_user, UnknownCmd) {
217     uint32_t error;
218     error = make_request(_state->channel, UNKNOWN_CMD, NULL, 0, _state->channel,
219                          NULL, 0);
220     EXPECT_EQ(false, HasFailure());
221     EXPECT_EQ(error, APPLOADER_ERR_UNKNOWN_CMD);
222 }
223 
TEST_F(apploader_user,BadLoadCmdMsgSize)224 TEST_F(apploader_user, BadLoadCmdMsgSize) {
225     uint32_t error;
226     error = make_request(_state->channel, APPLOADER_CMD_LOAD_APPLICATION, NULL,
227                          0, _state->channel, NULL, 0);
228     EXPECT_EQ(false, HasFailure());
229     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
230 }
231 
TEST_F(apploader_user,BadLoadCmdReqSize)232 TEST_F(apploader_user, BadLoadCmdReqSize) {
233     uint32_t error;
234     struct apploader_load_app_req req = {
235             .package_size = 0,
236     };
237     error = make_request(_state->channel, APPLOADER_CMD_LOAD_APPLICATION, &req,
238                          1, _state->channel, NULL, 0);
239     EXPECT_EQ(false, HasFailure());
240     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
241 }
242 
TEST_F(apploader_user,BadLoadCmdHandle)243 TEST_F(apploader_user, BadLoadCmdHandle) {
244     uint32_t error;
245     struct apploader_load_app_req req = {
246             .package_size = 0,
247     };
248     error = make_request(_state->channel, APPLOADER_CMD_LOAD_APPLICATION, &req,
249                          sizeof(req), INVALID_IPC_HANDLE, NULL, 0);
250     EXPECT_EQ(false, HasFailure());
251     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
252 }
253 
TEST_F(apploader_user,LoadCmdPackageTooSmall)254 TEST_F(apploader_user, LoadCmdPackageTooSmall) {
255     const int package_size = 2;
256     handle_t handle = INVALID_IPC_HANDLE;
257     void* package = get_memory_buffer_from_malloc(package_size, &handle);
258     ASSERT_EQ(false, HasFailure());
259     ASSERT_NE(handle, INVALID_IPC_HANDLE);
260     ASSERT_NE(package, NULL);
261 
262     uint32_t error;
263     struct apploader_load_app_req req = {
264             .package_size = package_size,
265     };
266     error = make_request(_state->channel, APPLOADER_CMD_LOAD_APPLICATION, &req,
267                          sizeof(req), handle, NULL, 0);
268     EXPECT_EQ(false, HasFailure());
269     EXPECT_EQ(error, APPLOADER_ERR_VERIFICATION_FAILED);
270 
271 test_abort:
272     if (package) {
273         free(package);
274     }
275     if (handle != INVALID_IPC_HANDLE) {
276         close(handle);
277     }
278 }
279 
send_cbor_package(handle_t chan,const char * cbor,size_t cbor_size)280 static void send_cbor_package(handle_t chan,
281                               const char* cbor,
282                               size_t cbor_size) {
283     handle_t handle = INVALID_IPC_HANDLE;
284     void* package = get_memory_buffer_from_malloc(cbor_size, &handle);
285     ASSERT_EQ(false, HasFailure());
286     ASSERT_NE(handle, INVALID_IPC_HANDLE);
287     ASSERT_NE(package, NULL);
288 
289     memcpy(package, cbor, cbor_size);
290 
291     uint32_t error;
292     struct apploader_load_app_req req = {
293             .package_size = cbor_size,
294     };
295     error = make_request(chan, APPLOADER_CMD_LOAD_APPLICATION, &req,
296                          sizeof(req), handle, NULL, 0);
297     ASSERT_EQ(false, HasFailure());
298     EXPECT_EQ(error, APPLOADER_ERR_VERIFICATION_FAILED);
299 
300 test_abort:
301     if (package) {
302         free(package);
303     }
304     if (handle != INVALID_IPC_HANDLE) {
305         close(handle);
306     }
307 }
308 
TEST_F(apploader_user,BadLoadCmdPackageCBORTag)309 TEST_F(apploader_user, BadLoadCmdPackageCBORTag) {
310     /* Write an untagged UInt */
311     const char bad_tag_cbor[] = {
312             /* UInt: 0 */
313             0x00,
314     };
315     send_cbor_package(_state->channel, bad_tag_cbor, sizeof(bad_tag_cbor));
316 }
317 
TEST_F(apploader_user,BadLoadCmdPackageCBORLength)318 TEST_F(apploader_user, BadLoadCmdPackageCBORLength) {
319     /* Send an incomplete message */
320     const char bad_length_cbor[] = {
321             /* UInt followed by missing byte */
322             0x18,
323     };
324     send_cbor_package(_state->channel, bad_length_cbor,
325                       sizeof(bad_length_cbor));
326 }
327 
TEST_F(apploader_user,BadLoadCmdPackageCBORType)328 TEST_F(apploader_user, BadLoadCmdPackageCBORType) {
329     /* Write a tagged UInt */
330     const char bad_type_cbor[] = {
331             /* CBOR tag: 65536 */
332             0xda,
333             0x00,
334             0x01,
335             0x00,
336             0x00,
337             /* UInt: 0 */
338             0x00,
339     };
340     send_cbor_package(_state->channel, bad_type_cbor, sizeof(bad_type_cbor));
341 }
342 
TEST_F(apploader_user,BadLoadCmdPackageCBORMap)343 TEST_F(apploader_user, BadLoadCmdPackageCBORMap) {
344     /* Write a tagged empty map */
345     const char bad_map_cbor[] = {
346             /* CBOR tag: 65536 */
347             0xda,
348             0x00,
349             0x01,
350             0x00,
351             0x00,
352             /* Map: empty */
353             0xa0,
354     };
355     send_cbor_package(_state->channel, bad_map_cbor, sizeof(bad_map_cbor));
356 }
357 
358 extern char version_test_app_v1_start[], version_test_app_v1_end[];
359 extern char version_test_app_v2_start[], version_test_app_v2_end[];
360 extern char version_test_app_v3_start[], version_test_app_v3_end[];
361 
362 /*
363  * App with versions v1, v2 & v3 - min_version=1.
364  *  Test that v1 cannot be loaded after v2.
365  *  Then v3 can load after v2 (but has min_version to v1).
366  *  Then v1 still cannot be loaded.
367  *  Then v2 still can be loaded.
368  */
TEST_F(apploader_user,AppVersionTest)369 TEST_F(apploader_user, AppVersionTest) {
370     uint32_t error;
371 
372     /* Load v2, no min_version (so min defaults to v2) */
373     error = load_test_app(_state->channel, version_test_app_v2_start,
374                           version_test_app_v2_end);
375     ASSERT_EQ(false, HasFailure());
376     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
377                             error == APPLOADER_ERR_ALREADY_EXISTS);
378 
379     /* Try to load v1 - this should not be allowed */
380     error = load_test_app(_state->channel, version_test_app_v1_start,
381                           version_test_app_v1_end);
382     ASSERT_EQ(false, HasFailure());
383 
384     if (system_state_app_loading_skip_version_update()) {
385         trusty_unittest_printf(
386                 "[  SKIPPED ] AppVersionTest - version update is disabled\n");
387         ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
388                                 error == APPLOADER_ERR_ALREADY_EXISTS);
389     } else {
390         ASSERT_EQ(error, APPLOADER_ERR_INVALID_VERSION);
391     }
392 
393     /* Load v3, min_version = 1 */
394     error = load_test_app(_state->channel, version_test_app_v3_start,
395                           version_test_app_v3_end);
396     ASSERT_EQ(false, HasFailure());
397     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
398                             error == APPLOADER_ERR_ALREADY_EXISTS);
399 
400     /* Retry to load v1 - this should still not be allowed */
401     error = load_test_app(_state->channel, version_test_app_v1_start,
402                           version_test_app_v1_end);
403     ASSERT_EQ(false, HasFailure());
404 
405     if (system_state_app_loading_skip_version_update()) {
406         ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
407                                 error == APPLOADER_ERR_ALREADY_EXISTS);
408     } else {
409         ASSERT_EQ(error, APPLOADER_ERR_INVALID_VERSION);
410     }
411 
412     /* Load v2, should still be allowed */
413     error = load_test_app(_state->channel, version_test_app_v2_start,
414                           version_test_app_v2_end);
415     ASSERT_EQ(false, HasFailure());
416     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
417                             error == APPLOADER_ERR_ALREADY_EXISTS);
418 test_abort:;
419 }
420 
421 extern char mmio_test_app_allowed_start[], mmio_test_app_allowed_end[];
422 extern char mmio_test_app_bad_uuid_start[], mmio_test_app_bad_uuid_end[];
423 extern char mmio_test_app_bad_range_low_start[],
424         mmio_test_app_bad_range_low_end[];
425 extern char mmio_test_app_bad_range_high_start[],
426         mmio_test_app_bad_range_high_end[];
427 
TEST_F(apploader_user,MmioTest)428 TEST_F(apploader_user, MmioTest) {
429     uint32_t error;
430 
431     /* The allowed app should get loaded successfully */
432     error = load_test_app(_state->channel, mmio_test_app_allowed_start,
433                           mmio_test_app_allowed_end);
434     ASSERT_EQ(false, HasFailure());
435     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
436                             error == APPLOADER_ERR_ALREADY_EXISTS);
437 
438     /* The app with an unknown UUID should get rejected */
439     error = load_test_app(_state->channel, mmio_test_app_bad_uuid_start,
440                           mmio_test_app_bad_uuid_end);
441     ASSERT_EQ(false, HasFailure());
442     ASSERT_EQ(APPLOADER_ERR_LOADING_FAILED, error);
443 
444     /* The apps with mappings outside the allowed range should get rejected */
445     error = load_test_app(_state->channel, mmio_test_app_bad_range_low_start,
446                           mmio_test_app_bad_range_low_end);
447     ASSERT_EQ(false, HasFailure());
448     ASSERT_EQ(APPLOADER_ERR_LOADING_FAILED, error);
449 
450     error = load_test_app(_state->channel, mmio_test_app_bad_range_high_start,
451                           mmio_test_app_bad_range_high_end);
452     ASSERT_EQ(false, HasFailure());
453     ASSERT_EQ(APPLOADER_ERR_LOADING_FAILED, error);
454 
455 test_abort:;
456 }
457 
458 extern char encryption_test_app_encrypted_app_encryption_optional_start[],
459         encryption_test_app_encrypted_app_encryption_optional_end[];
460 extern char encryption_test_app_encrypted_app_encryption_required_start[],
461         encryption_test_app_encrypted_app_encryption_required_end[];
462 extern char encryption_test_app_unencrypted_app_encryption_optional_start[],
463         encryption_test_app_unencrypted_app_encryption_optional_end[];
464 extern char encryption_test_app_unencrypted_app_encryption_required_start[],
465         encryption_test_app_unencrypted_app_encryption_required_end[];
466 
TEST_F(apploader_user,AppEncryptionTest)467 TEST_F(apploader_user, AppEncryptionTest) {
468     uint32_t error;
469 
470     /* The encrypted app not requiring encryption should load successfully */
471     error = load_test_app(
472             _state->channel,
473             encryption_test_app_encrypted_app_encryption_optional_start,
474             encryption_test_app_encrypted_app_encryption_optional_end);
475     ASSERT_EQ(false, HasFailure());
476     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
477                             error == APPLOADER_ERR_ALREADY_EXISTS);
478 
479     /* The encrypted app requiring encryption should also load successfully */
480     error = load_test_app(
481             _state->channel,
482             encryption_test_app_encrypted_app_encryption_required_start,
483             encryption_test_app_encrypted_app_encryption_required_end);
484     ASSERT_EQ(false, HasFailure());
485     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
486                             error == APPLOADER_ERR_ALREADY_EXISTS);
487 
488     /* The unencrypted app not requiring encryption should load successfully */
489     error = load_test_app(
490             _state->channel,
491             encryption_test_app_unencrypted_app_encryption_optional_start,
492             encryption_test_app_unencrypted_app_encryption_optional_end);
493     ASSERT_EQ(false, HasFailure());
494     ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
495                             error == APPLOADER_ERR_ALREADY_EXISTS);
496 
497     /*
498      * The unencrypted app requiring encryption should fail to load if app
499      * loading is locked.
500      */
501     error = load_test_app(
502             _state->channel,
503             encryption_test_app_unencrypted_app_encryption_required_start,
504             encryption_test_app_unencrypted_app_encryption_required_end);
505     ASSERT_EQ(false, HasFailure());
506     if (system_state_app_loading_unlocked()) {
507         trusty_unittest_printf(
508                 "[  SKIPPED ] AppEncryptionTest - app loading is unlocked\n");
509         ASSERT_EQ(true, error == APPLOADER_NO_ERROR ||
510                                 error == APPLOADER_ERR_ALREADY_EXISTS);
511     } else {
512         ASSERT_EQ(error, APPLOADER_ERR_NOT_ENCRYPTED);
513     }
514 
515 test_abort:;
516 }
517 
518 typedef struct apploader_service {
519     handle_t channel;
520 } apploader_service_t;
521 
TEST_F_SETUP(apploader_service)522 TEST_F_SETUP(apploader_service) {
523     int rc;
524 
525     rc = connect(APPLOADER_SECURE_PORT, IPC_CONNECT_WAIT_FOR_PORT);
526     _state->channel = (handle_t)rc;
527     ASSERT_GE(_state->channel, 0);
528 
529 test_abort:;
530 }
531 
TEST_F_TEARDOWN(apploader_service)532 TEST_F_TEARDOWN(apploader_service) {
533     close(_state->channel);
534 }
535 
TEST_F(apploader_service,UnknownCmd)536 TEST_F(apploader_service, UnknownCmd) {
537     uint32_t error;
538     error = make_request(_state->channel, UNKNOWN_CMD, NULL, 0,
539                          INVALID_IPC_HANDLE, NULL, 0);
540     EXPECT_EQ(false, HasFailure());
541     EXPECT_EQ(error, APPLOADER_ERR_UNKNOWN_CMD);
542 }
543 
TEST_F(apploader_service,BadGetMemoryCmdMsgSize)544 TEST_F(apploader_service, BadGetMemoryCmdMsgSize) {
545     uint32_t error;
546     error = make_request(_state->channel, APPLOADER_SECURE_CMD_GET_MEMORY, NULL,
547                          0, INVALID_IPC_HANDLE, NULL, 0);
548     EXPECT_EQ(false, HasFailure());
549     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
550 }
551 
552 /* Make two GET_MEMORY requests */
TEST_F(apploader_service,DoubleGetMemory)553 TEST_F(apploader_service, DoubleGetMemory) {
554     handle_t handle1 = INVALID_IPC_HANDLE;
555     handle_t handle2 = INVALID_IPC_HANDLE;
556 
557     uint64_t page_size = getauxval(AT_PAGESZ);
558     handle1 = get_memory_handle_from_service(_state->channel, page_size);
559     ASSERT_EQ(false, HasFailure());
560     ASSERT_NE(handle1, INVALID_IPC_HANDLE);
561 
562     uint32_t error;
563     struct apploader_secure_get_memory_req req = {
564             .package_size = page_size,
565     };
566     error = make_request(_state->channel, APPLOADER_SECURE_CMD_GET_MEMORY, &req,
567                          sizeof(req), INVALID_IPC_HANDLE, &handle2, 1);
568     EXPECT_EQ(false, HasFailure());
569     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
570     EXPECT_EQ(handle2, INVALID_IPC_HANDLE);
571 
572 test_abort:
573     if (handle1 != INVALID_IPC_HANDLE) {
574         close(handle1);
575     }
576     if (handle2 != INVALID_IPC_HANDLE) {
577         close(handle2);
578     }
579 }
580 
TEST_F(apploader_service,BadGetMemoryCmdReqSize)581 TEST_F(apploader_service, BadGetMemoryCmdReqSize) {
582     uint32_t error;
583     struct apploader_secure_get_memory_req req = {
584             .package_size = 0,
585     };
586     error = make_request(_state->channel, APPLOADER_SECURE_CMD_GET_MEMORY, &req,
587                          1, INVALID_IPC_HANDLE, NULL, 0);
588     EXPECT_EQ(false, HasFailure());
589     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
590 
591 test_abort:;
592 }
593 
TEST_F(apploader_service,GetMemory)594 TEST_F(apploader_service, GetMemory) {
595     uint64_t page_size = getauxval(AT_PAGESZ);
596     void* buf = get_memory_buffer_from_service(_state->channel, page_size);
597     ASSERT_EQ(false, HasFailure());
598     ASSERT_NE(buf, NULL);
599 
600     uint32_t* p = buf;
601     memset(buf, 0x5a, page_size);
602     for (size_t i = 0; i < page_size / sizeof(uint32_t); i++, p++) {
603         ASSERT_EQ(*p, 0x5a5a5a5aU);
604     }
605 
606 test_abort:
607     if (buf) {
608         munmap(buf, page_size);
609     }
610 }
611 
TEST_F(apploader_service,BadLoadCmdMsgSize)612 TEST_F(apploader_service, BadLoadCmdMsgSize) {
613     uint32_t error;
614     error = make_request(_state->channel, APPLOADER_SECURE_CMD_LOAD_APPLICATION,
615                          NULL, 0, INVALID_IPC_HANDLE, NULL, 0);
616     EXPECT_EQ(false, HasFailure());
617     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
618 
619 test_abort:;
620 }
621 
TEST_F(apploader_service,BadLoadCmdReqSize)622 TEST_F(apploader_service, BadLoadCmdReqSize) {
623     uint32_t error;
624     struct apploader_secure_load_app_req req = {
625             .manifest_start = 0,
626             .manifest_end = 0,
627             .img_start = 0,
628             .img_end = 0,
629     };
630     error = make_request(_state->channel, APPLOADER_SECURE_CMD_LOAD_APPLICATION,
631                          &req, 1, INVALID_IPC_HANDLE, NULL, 0);
632     EXPECT_EQ(false, HasFailure());
633     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
634 
635 test_abort:;
636 }
637 
TEST_F(apploader_service,LoadWithoutGetMemory)638 TEST_F(apploader_service, LoadWithoutGetMemory) {
639     uint32_t error;
640     struct apploader_secure_load_app_req req = {
641             .manifest_start = 0,
642             .manifest_end = 0,
643             .img_start = 0,
644             .img_end = 0,
645     };
646     error = make_request(_state->channel, APPLOADER_SECURE_CMD_LOAD_APPLICATION,
647                          &req, sizeof(req), INVALID_IPC_HANDLE, NULL, 0);
648     EXPECT_EQ(false, HasFailure());
649     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
650 
651 test_abort:;
652 }
653 
TEST_F(apploader_service,BadLoadCmdOffsets)654 TEST_F(apploader_service, BadLoadCmdOffsets) {
655     uint64_t page_size = getauxval(AT_PAGESZ);
656     handle_t handle = INVALID_IPC_HANDLE;
657     handle = get_memory_handle_from_service(_state->channel, page_size);
658     ASSERT_EQ(false, HasFailure());
659     ASSERT_NE(handle, INVALID_IPC_HANDLE);
660 
661     close(handle);
662     handle = INVALID_IPC_HANDLE;
663 
664     uint32_t error;
665     struct apploader_secure_load_app_req req = {
666             .manifest_start = 0,
667             .manifest_end = 0,
668             .img_start = 0,
669             .img_end = 0,
670     };
671     error = make_request(_state->channel, APPLOADER_SECURE_CMD_LOAD_APPLICATION,
672                          &req, sizeof(req), handle, NULL, 0);
673     EXPECT_EQ(false, HasFailure());
674     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
675 
676 test_abort:
677     if (handle != INVALID_IPC_HANDLE) {
678         close(handle);
679     }
680 }
681 
TEST_F(apploader_service,BadLoadCmdImageAlignment)682 TEST_F(apploader_service, BadLoadCmdImageAlignment) {
683     uint64_t page_size = getauxval(AT_PAGESZ);
684     handle_t handle = INVALID_IPC_HANDLE;
685     handle = get_memory_handle_from_service(_state->channel, page_size);
686     ASSERT_EQ(false, HasFailure());
687     ASSERT_NE(handle, INVALID_IPC_HANDLE);
688 
689     close(handle);
690     handle = INVALID_IPC_HANDLE;
691 
692     uint32_t error;
693     struct apploader_secure_load_app_req req = {
694             .manifest_start = 0,
695             .manifest_end = 1,
696             .img_start = 2,
697             .img_end = 3,
698     };
699     error = make_request(_state->channel, APPLOADER_SECURE_CMD_LOAD_APPLICATION,
700                          &req, sizeof(req), INVALID_IPC_HANDLE, NULL, 0);
701     EXPECT_EQ(false, HasFailure());
702     EXPECT_EQ(error, APPLOADER_ERR_LOADING_FAILED);
703 
704 test_abort:
705     if (handle != INVALID_IPC_HANDLE) {
706         close(handle);
707     }
708 }
709 
710 /* Send a LOAD_APPLICATION command without closing the handle */
TEST_F(apploader_service,LoadCmdHoldHandle)711 TEST_F(apploader_service, LoadCmdHoldHandle) {
712     uint64_t page_size = getauxval(AT_PAGESZ);
713     size_t buf_size = 2 * page_size;
714     handle_t handle = INVALID_IPC_HANDLE;
715     handle = get_memory_handle_from_service(_state->channel, buf_size);
716     ASSERT_EQ(false, HasFailure());
717     ASSERT_NE(handle, INVALID_IPC_HANDLE);
718 
719     uint32_t error;
720     struct apploader_secure_load_app_req req = {
721             .manifest_start = page_size,
722             .manifest_end = buf_size,
723             .img_start = 0,
724             .img_end = page_size,
725     };
726     error = make_request(_state->channel, APPLOADER_SECURE_CMD_LOAD_APPLICATION,
727                          &req, sizeof(req), INVALID_IPC_HANDLE, NULL, 0);
728     EXPECT_EQ(false, HasFailure());
729     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
730 
731 test_abort:
732     if (handle != INVALID_IPC_HANDLE) {
733         close(handle);
734     }
735 }
736 
737 /* Send a LOAD_APPLICATION command without unmapping the memref */
TEST_F(apploader_service,LoadCmdHoldMapping)738 TEST_F(apploader_service, LoadCmdHoldMapping) {
739     uint64_t page_size = getauxval(AT_PAGESZ);
740     size_t buf_size = 2 * page_size;
741     void* buf = get_memory_buffer_from_service(_state->channel, buf_size);
742     ASSERT_EQ(false, HasFailure());
743     ASSERT_NE(buf, NULL);
744 
745     memset(buf, 0x5a, buf_size);
746 
747     uint32_t error;
748     struct apploader_secure_load_app_req req = {
749             .manifest_start = page_size,
750             .manifest_end = buf_size,
751             .img_start = 0,
752             .img_end = page_size,
753     };
754     error = make_request(_state->channel, APPLOADER_SECURE_CMD_LOAD_APPLICATION,
755                          &req, sizeof(req), INVALID_IPC_HANDLE, NULL, 0);
756     EXPECT_EQ(false, HasFailure());
757     EXPECT_EQ(error, APPLOADER_ERR_INVALID_CMD);
758 
759 test_abort:
760     if (buf) {
761         munmap(buf, buf_size);
762     }
763 }
764 
TEST_F(apploader_service,BadLoadCmdImageELFHeader)765 TEST_F(apploader_service, BadLoadCmdImageELFHeader) {
766     uint64_t page_size = getauxval(AT_PAGESZ);
767     size_t buf_size = 2 * page_size;
768     void* buf = get_memory_buffer_from_service(_state->channel, buf_size);
769     ASSERT_EQ(false, HasFailure());
770     ASSERT_NE(buf, NULL);
771 
772     /* Fill the image contents with 0x5a, so the ELF header check fails */
773     memset(buf, 0x5a, buf_size);
774     munmap(buf, buf_size);
775     buf = NULL;
776 
777     uint32_t error;
778     struct apploader_secure_load_app_req req = {
779             .manifest_start = page_size,
780             .manifest_end = buf_size,
781             .img_start = 0,
782             .img_end = page_size,
783     };
784     error = make_request(_state->channel, APPLOADER_SECURE_CMD_LOAD_APPLICATION,
785                          &req, sizeof(req), INVALID_IPC_HANDLE, NULL, 0);
786     EXPECT_EQ(false, HasFailure());
787     EXPECT_EQ(error, APPLOADER_ERR_LOADING_FAILED);
788 
789 test_abort:
790     if (buf) {
791         munmap(buf, buf_size);
792     }
793 }
794 
795 PORT_TEST(apploader, "com.android.trusty.apploader.test")
796