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