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