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