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 #define TLOG_TAG "apploader"
18
19 #include <apploader/package.h>
20 #include <assert.h>
21 #include <endian.h>
22 #include <interface/apploader/apploader.h>
23 #include <interface/apploader/apploader_secure.h>
24 #include <inttypes.h>
25 #include <lib/app_manifest/app_manifest.h>
26 #include <lib/apploader_policy_engine/apploader_policy_engine.h>
27 #include <lib/system_state/system_state.h>
28 #include <lib/tipc/tipc.h>
29 #include <lib/tipc/tipc_srv.h>
30 #include <lk/err_ptr.h>
31 #include <lk/macros.h>
32 #include <stddef.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sys/auxv.h>
37 #include <sys/mman.h>
38 #include <trusty_log.h>
39
40 #include "app_manifest_parser.h"
41 #include "app_version.h"
42
43 struct apploader_req {
44 struct apploader_header hdr;
45 union {
46 struct apploader_load_app_req load_app_req;
47 };
48 } __PACKED;
49
50 /*
51 * Common structure covering all possible apploader messages, only used to
52 * determine the maximum message size
53 */
54 union apploader_longest_msg {
55 struct apploader_req req;
56 struct apploader_resp resp;
57 } __PACKED;
58
59 static struct tipc_port_acl apploader_port_acl = {
60 #ifdef APPLOADER_ALLOW_NS_CONNECT
61 .flags = IPC_PORT_ALLOW_TA_CONNECT | IPC_PORT_ALLOW_NS_CONNECT,
62 #else
63 .flags = IPC_PORT_ALLOW_TA_CONNECT,
64 #endif
65 .uuid_num = 0,
66 .uuids = NULL,
67 .extra_data = NULL,
68 };
69
70 static struct tipc_port apploader_port = {
71 .name = APPLOADER_PORT,
72 .msg_max_size = sizeof(union apploader_longest_msg),
73 .msg_queue_len = 1,
74 .acl = &apploader_port_acl,
75 .priv = NULL,
76 };
77
apploader_translate_error(int rc)78 static int apploader_translate_error(int rc) {
79 if (rc > 0) {
80 return APPLOADER_ERR_INTERNAL;
81 }
82
83 switch (rc) {
84 case ERR_NO_MEMORY:
85 return APPLOADER_ERR_NO_MEMORY;
86 case ERR_ALREADY_EXISTS:
87 return APPLOADER_ERR_ALREADY_EXISTS;
88 default:
89 TLOGW("Unrecognized error (%d)\n", rc);
90 return APPLOADER_ERR_INTERNAL;
91 }
92 }
93
apploader_send_response(handle_t chan,uint32_t cmd,uint32_t error)94 static int apploader_send_response(handle_t chan,
95 uint32_t cmd,
96 uint32_t error) {
97 struct apploader_resp resp = {
98 .hdr =
99 {
100 .cmd = cmd | APPLOADER_RESP_BIT,
101 },
102 .error = error,
103 };
104 int rc = tipc_send1(chan, &resp, sizeof(resp));
105 if (rc < 0) {
106 return rc;
107 }
108
109 if ((size_t)rc != sizeof(resp)) {
110 TLOGE("Failed to send message (%d). Expected to send %zu bytes.\n", rc,
111 sizeof(resp));
112 return ERR_BAD_LEN;
113 }
114 return NO_ERROR;
115 }
116
apploader_read(handle_t chan,size_t min_sz,void * buf,size_t buf_sz,handle_t * handles,uint32_t * num_handles)117 static int apploader_read(handle_t chan,
118 size_t min_sz,
119 void* buf,
120 size_t buf_sz,
121 handle_t* handles,
122 uint32_t* num_handles) {
123 int rc;
124 ipc_msg_info_t msg_inf;
125 rc = get_msg(chan, &msg_inf);
126 if (rc != NO_ERROR) {
127 TLOGE("Failed to get message (%d)\n", rc);
128 return rc;
129 }
130
131 if (msg_inf.len < min_sz || msg_inf.len > buf_sz) {
132 TLOGE("Message is too short or too long (%zd)\n", msg_inf.len);
133 rc = ERR_BAD_LEN;
134 goto err;
135 }
136
137 uint32_t max_num_handles = num_handles ? *num_handles : 0;
138 if (msg_inf.num_handles > max_num_handles) {
139 TLOGE("Message has too many handles (%" PRIu32 ")\n",
140 msg_inf.num_handles);
141 rc = ERR_TOO_BIG;
142 goto err;
143 }
144
145 struct iovec iov = {
146 .iov_base = buf,
147 .iov_len = buf_sz,
148 };
149 ipc_msg_t ipc_msg = {
150 .iov = &iov,
151 .num_iov = 1,
152 .handles = handles,
153 .num_handles = msg_inf.num_handles,
154 };
155 rc = read_msg(chan, msg_inf.id, 0, &ipc_msg);
156 assert(rc < 0 || (size_t)rc == msg_inf.len);
157
158 if (rc >= 0 && num_handles) {
159 *num_handles = msg_inf.num_handles;
160 }
161
162 err:
163 put_msg(chan, msg_inf.id);
164 return rc;
165 }
166
apploader_send_secure_get_memory_command(handle_t secure_chan,size_t aligned_size,handle_t * secure_mem_handle)167 static uint32_t apploader_send_secure_get_memory_command(
168 handle_t secure_chan,
169 size_t aligned_size,
170 handle_t* secure_mem_handle) {
171 assert(secure_mem_handle);
172
173 struct apploader_secure_header hdr = {
174 .cmd = APPLOADER_SECURE_CMD_GET_MEMORY,
175 };
176 struct apploader_secure_get_memory_req get_memory_req = {
177 .package_size = aligned_size,
178 };
179 int rc = tipc_send2(secure_chan, &hdr, sizeof(hdr), &get_memory_req,
180 sizeof(get_memory_req));
181 if ((size_t)rc != sizeof(hdr) + sizeof(get_memory_req)) {
182 TLOGE("Failed to send get_memory message (%d)\n", rc);
183 return apploader_translate_error(rc);
184 }
185
186 uevent_t event = UEVENT_INITIAL_VALUE(event);
187 rc = wait(secure_chan, &event, INFINITE_TIME);
188 if (rc != NO_ERROR || !(event.event & IPC_HANDLE_POLL_MSG)) {
189 TLOGE("Failed to wait for response (%d)\n", rc);
190 return apploader_translate_error(rc);
191 }
192
193 uint32_t num_handles = 1;
194 struct apploader_secure_resp resp;
195 rc = apploader_read(secure_chan, sizeof(resp), &resp, sizeof(resp),
196 secure_mem_handle, &num_handles);
197 if (rc < 0) {
198 TLOGE("Failed to read response (%d)\n", rc);
199 return apploader_translate_error(rc);
200 }
201
202 if (resp.hdr.cmd !=
203 (APPLOADER_SECURE_CMD_GET_MEMORY | APPLOADER_SECURE_RESP_BIT)) {
204 TLOGE("Invalid command in response (%u)\n", resp.hdr.cmd);
205 return APPLOADER_ERR_INTERNAL;
206 }
207
208 if (resp.error != APPLOADER_NO_ERROR) {
209 TLOGE("Received error from service (%" PRIu32 ")\n", resp.error);
210 return resp.error;
211 }
212
213 if (num_handles != 1) {
214 TLOGE("Expected 1 handle, got %" PRIu32 "\n", num_handles);
215 return APPLOADER_ERR_INTERNAL;
216 }
217
218 return APPLOADER_NO_ERROR;
219 }
220
apploader_send_secure_load_command(handle_t secure_chan,ptrdiff_t elf_offset,ptrdiff_t manifest_offset,struct apploader_package_metadata * pkg_meta)221 static uint32_t apploader_send_secure_load_command(
222 handle_t secure_chan,
223 ptrdiff_t elf_offset,
224 ptrdiff_t manifest_offset,
225 struct apploader_package_metadata* pkg_meta) {
226 struct apploader_secure_header hdr = {
227 .cmd = APPLOADER_SECURE_CMD_LOAD_APPLICATION,
228 };
229 struct apploader_secure_load_app_req req = {
230 .manifest_start = manifest_offset,
231 .manifest_end = manifest_offset + pkg_meta->manifest_size,
232 .img_start = elf_offset,
233 .img_end = elf_offset + pkg_meta->elf_size,
234 };
235 int rc = tipc_send2(secure_chan, &hdr, sizeof(hdr), &req, sizeof(req));
236 if (rc != sizeof(hdr) + sizeof(req)) {
237 TLOGE("Failed to send message (%d). Expected to send %zu bytes.\n", rc,
238 sizeof(hdr) + sizeof(req));
239 return apploader_translate_error(rc);
240 }
241
242 uevent_t event = UEVENT_INITIAL_VALUE(event);
243 rc = wait(secure_chan, &event, INFINITE_TIME);
244 if (rc != NO_ERROR || !(event.event & IPC_HANDLE_POLL_MSG)) {
245 TLOGE("Failed to wait for response (%d)\n", rc);
246 return apploader_translate_error(rc);
247 }
248
249 struct apploader_secure_resp resp;
250 rc = tipc_recv1(secure_chan, sizeof(resp), &resp, sizeof(resp));
251 if ((size_t)rc != sizeof(resp)) {
252 TLOGE("Failed to read response for load application command\n");
253 return apploader_translate_error(rc);
254 }
255
256 if (resp.hdr.cmd !=
257 (APPLOADER_SECURE_CMD_LOAD_APPLICATION | APPLOADER_SECURE_RESP_BIT)) {
258 TLOGE("Invalid command in response (%u)\n", resp.hdr.cmd);
259 return APPLOADER_ERR_INTERNAL;
260 }
261
262 if (resp.error != APPLOADER_NO_ERROR) {
263 TLOGE("Received error from service (%" PRIu32 ")\n", resp.error);
264 return resp.error;
265 }
266
267 return APPLOADER_NO_ERROR;
268 }
269
apploader_copy_package(handle_t req_handle,handle_t secure_chan,uint64_t package_size,uint64_t aligned_size,uint8_t ** out_package)270 static uint32_t apploader_copy_package(handle_t req_handle,
271 handle_t secure_chan,
272 uint64_t package_size,
273 uint64_t aligned_size,
274 uint8_t** out_package) {
275 uint32_t resp_error;
276
277 handle_t secure_mem_handle;
278 uint32_t get_memory_error = apploader_send_secure_get_memory_command(
279 secure_chan, aligned_size, &secure_mem_handle);
280 if (get_memory_error != APPLOADER_NO_ERROR) {
281 TLOGE("Failed to get memory from service (%" PRIu32 ")\n",
282 get_memory_error);
283 resp_error = get_memory_error;
284 goto err_send_get_memory;
285 }
286
287 if (secure_mem_handle == INVALID_IPC_HANDLE) {
288 TLOGE("Received invalid handle from service\n");
289 resp_error = APPLOADER_ERR_INTERNAL;
290 goto err_invalid_secure_mem_handle;
291 }
292
293 void* req_package = mmap(NULL, aligned_size, PROT_READ, 0, req_handle, 0);
294 if (req_package == MAP_FAILED) {
295 TLOGE("Failed to map the request handle\n");
296 resp_error = APPLOADER_ERR_NO_MEMORY;
297 goto err_req_mmap;
298 }
299
300 void* resp_package = mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, 0,
301 secure_mem_handle, 0);
302 if (resp_package == MAP_FAILED) {
303 TLOGE("Failed to map the handle from service\n");
304 resp_error = APPLOADER_ERR_NO_MEMORY;
305 goto err_resp_mmap;
306 }
307
308 assert(out_package);
309 assert(package_size <= aligned_size);
310 memcpy(resp_package, req_package, package_size);
311 memset(resp_package + package_size, 0, aligned_size - package_size);
312 *out_package = resp_package;
313 resp_error = APPLOADER_NO_ERROR;
314
315 err_resp_mmap:;
316 int rc = munmap(req_package, aligned_size);
317 if (rc != NO_ERROR) {
318 TLOGW("munmap() failed: %d\n", rc);
319 }
320 err_req_mmap:
321 close(secure_mem_handle);
322 err_invalid_secure_mem_handle:
323 err_send_get_memory:
324 return resp_error;
325 }
326
apploader_relocate_package(uint8_t * package,struct apploader_package_metadata * pkg_meta)327 static bool apploader_relocate_package(
328 uint8_t* package,
329 struct apploader_package_metadata* pkg_meta) {
330 if (pkg_meta->elf_start > pkg_meta->manifest_start) {
331 /*
332 * For now, we only support input files where the ELF precedes
333 * the manifest. The current file format follows this rule.
334 */
335 return false;
336 }
337
338 uint64_t unaligned_elf_size = pkg_meta->elf_size;
339 uint64_t page_size = getauxval(AT_PAGESZ);
340 /* ELF comes first, move it to offset 0 */
341 memmove(package, pkg_meta->elf_start, unaligned_elf_size);
342 pkg_meta->elf_start = package;
343 pkg_meta->elf_size = round_up(unaligned_elf_size, page_size);
344
345 if (pkg_meta->elf_size > unaligned_elf_size) {
346 /*
347 * There is a gap between ELF and manifest, zero it because it will
348 * probably be used for .bss
349 */
350 memset(package + unaligned_elf_size, 0,
351 pkg_meta->elf_size - unaligned_elf_size);
352 }
353
354 /*
355 * Then move the manifest just after; the manifest starts
356 * on the page immediately after the ELF file (elf_size is page-aligned
357 * by the round_up call above), so the two never share a page
358 */
359 uint8_t* new_manifest_start = package + pkg_meta->elf_size;
360 memmove(new_manifest_start, pkg_meta->manifest_start,
361 pkg_meta->manifest_size);
362 pkg_meta->manifest_start = new_manifest_start;
363
364 return true;
365 }
366
apploader_handle_cmd_load_app(handle_t chan,struct apploader_load_app_req * req,handle_t req_handle)367 static int apploader_handle_cmd_load_app(handle_t chan,
368 struct apploader_load_app_req* req,
369 handle_t req_handle) {
370 uint32_t resp_error;
371
372 if (req_handle == INVALID_IPC_HANDLE) {
373 TLOGE("Received invalid request handle\n");
374 resp_error = APPLOADER_ERR_INVALID_CMD;
375 goto err_invalid_req_handle;
376 }
377
378 uint64_t page_size = getauxval(AT_PAGESZ);
379 uint64_t aligned_size = round_up(req->package_size, page_size);
380 TLOGD("Loading %" PRIu64 " bytes package, %" PRIu64 " aligned\n",
381 req->package_size, aligned_size);
382
383 handle_t secure_chan;
384 int rc = tipc_connect(&secure_chan, APPLOADER_SECURE_PORT);
385 if (rc < 0) {
386 TLOGE("Failed to connect to service (%d)\n", rc);
387 resp_error = apploader_translate_error(rc);
388 goto err_connect_secure;
389 }
390
391 uint32_t copy_error;
392 uint8_t* package;
393 copy_error = apploader_copy_package(
394 req_handle, secure_chan, req->package_size, aligned_size, &package);
395 if (copy_error != APPLOADER_NO_ERROR) {
396 TLOGE("Failed to copy package from client\n");
397 resp_error = copy_error;
398 goto err_copy_package;
399 }
400
401 struct apploader_package_metadata pkg_meta = {0};
402 if (!apploader_parse_package_metadata(package, req->package_size,
403 &pkg_meta)) {
404 TLOGE("Failed to parse application package\n");
405 resp_error = APPLOADER_ERR_VERIFICATION_FAILED;
406 goto err_no_load;
407 }
408
409 if (!pkg_meta.manifest_start || !pkg_meta.manifest_size) {
410 TLOGE("Could not find manifest in application package\n");
411 resp_error = APPLOADER_ERR_VERIFICATION_FAILED;
412 goto err_no_load;
413 }
414
415 if (!pkg_meta.elf_start || !pkg_meta.elf_size) {
416 TLOGE("Could not find ELF image in application package\n");
417 resp_error = APPLOADER_ERR_VERIFICATION_FAILED;
418 goto err_no_load;
419 }
420
421 struct apploader_policy_data ap_data = {
422 .public_key = pkg_meta.public_key,
423 .public_key_size = pkg_meta.public_key_size,
424 .force_store_min_version = false};
425
426 if (!apploader_parse_manifest_from_metadata(&pkg_meta,
427 &ap_data.manifest_extracts)) {
428 TLOGE("Unable to extract manifest fields\n");
429 resp_error = APPLOADER_ERR_VERIFICATION_FAILED;
430 goto err_no_load;
431 }
432
433 if (!apploader_read_app_version(&ap_data.manifest_extracts.uuid,
434 &ap_data.app_stored_version)) {
435 TLOGE("Failed to read application version from storage\n");
436 resp_error = APPLOADER_ERR_INTERNAL;
437 goto err_no_load;
438 }
439
440 /* Prevent rollback - we can normally never load a lower version app */
441 if (ap_data.manifest_extracts.version < ap_data.app_stored_version &&
442 !system_state_app_loading_skip_version_check()) {
443 TLOGE("Application package version (%" PRIu32
444 ") is lower than storage version (%" PRIu32 ")\n",
445 ap_data.manifest_extracts.version, ap_data.app_stored_version);
446 resp_error = APPLOADER_ERR_INVALID_VERSION;
447 goto err_no_load;
448 }
449
450 if (ap_data.manifest_extracts.requires_encryption &&
451 !pkg_meta.elf_is_cose_encrypt && !system_state_app_loading_unlocked()) {
452 TLOGE("Failed to meet application encryption requirement\n");
453 resp_error = APPLOADER_ERR_NOT_ENCRYPTED;
454 goto err_no_load;
455 }
456
457 /* Validate with the policy engine - note it may modify ap_data */
458 if (!apploader_policy_engine_validate(&ap_data)) {
459 TLOGE("App loading denied by policy engine\n");
460 resp_error = APPLOADER_ERR_POLICY_VIOLATION;
461 goto err_no_load;
462 }
463
464 if (!apploader_relocate_package(package, &pkg_meta)) {
465 TLOGE("Failed to relocate package contents in memory\n");
466 resp_error = APPLOADER_ERR_VERIFICATION_FAILED;
467 goto err_no_load;
468 }
469
470 const uint32_t min_version = ap_data.manifest_extracts.min_version;
471 const uint32_t storage_version = ap_data.app_stored_version;
472
473 /* Update the loadable app version only if needed - reduce writes */
474 if (min_version != storage_version &&
475 (min_version > storage_version || ap_data.force_store_min_version)) {
476 if (!system_state_app_loading_skip_version_check() &&
477 !system_state_app_loading_skip_version_update()) {
478 if (!apploader_write_app_version(&ap_data.manifest_extracts.uuid,
479 min_version)) {
480 TLOGE("Failed to update app version\n");
481 resp_error = APPLOADER_ERR_INTERNAL;
482 goto err_no_load;
483 }
484 }
485 }
486
487 ptrdiff_t elf_offset = pkg_meta.elf_start - package;
488 ptrdiff_t manifest_offset = pkg_meta.manifest_start - package;
489 rc = munmap(package, aligned_size);
490 if (rc != NO_ERROR) {
491 TLOGW("munmap() failed: %d\n", rc);
492 }
493
494 package = NULL;
495
496 /* Validate the relocated offsets */
497 assert(elf_offset >= 0);
498 assert(elf_offset + pkg_meta.elf_size <= aligned_size);
499 assert(manifest_offset >= 0);
500 assert(manifest_offset + pkg_meta.manifest_size <= aligned_size);
501
502 /* Finalize the loading by sending a LOAD_APPLICATION request */
503 resp_error = apploader_send_secure_load_command(secure_chan, elf_offset,
504 manifest_offset, &pkg_meta);
505 if (resp_error != APPLOADER_NO_ERROR) {
506 TLOGE("Failed to load application (%" PRIu32 ")\n", resp_error);
507 }
508
509 err_no_load:
510 if (pkg_meta.public_key) {
511 apploader_policy_engine_put_key(pkg_meta.public_key);
512 }
513
514 if (package) {
515 rc = munmap(package, aligned_size);
516 if (rc != NO_ERROR) {
517 TLOGW("munmap() failed: %d\n", rc);
518 }
519 }
520 err_copy_package:
521 close(secure_chan);
522 err_connect_secure:
523 err_invalid_req_handle:
524 return apploader_send_response(chan, APPLOADER_CMD_LOAD_APPLICATION,
525 resp_error);
526 }
527
apploader_on_message(const struct tipc_port * port,handle_t chan,void * ctx)528 static int apploader_on_message(const struct tipc_port* port,
529 handle_t chan,
530 void* ctx) {
531 assert(port == &apploader_port);
532 assert(ctx == NULL);
533 int rc;
534 handle_t handle = INVALID_IPC_HANDLE;
535 uint32_t num_handles = 1;
536 struct apploader_req req;
537 rc = apploader_read(chan, sizeof(req.hdr), &req, sizeof(req), &handle,
538 &num_handles);
539 if (rc < 0) {
540 TLOGE("Failed to read request (%d)\n", rc);
541 return rc;
542 }
543
544 TLOGD("Command: 0x%x\n", req.hdr.cmd);
545
546 size_t cmd_len;
547 switch (req.hdr.cmd) {
548 case APPLOADER_CMD_LOAD_APPLICATION:
549 /* Check the message length */
550 cmd_len = sizeof(req.hdr) + sizeof(req.load_app_req);
551 if (rc != (int)cmd_len) {
552 TLOGE("Expected to read %zu bytes, got %d.\n", cmd_len, rc);
553 rc = apploader_send_response(chan, req.hdr.cmd,
554 APPLOADER_ERR_INVALID_CMD);
555 break;
556 }
557
558 if (num_handles != 1) {
559 TLOGE("Expected 1 handle, got %" PRIu32 "\n", num_handles);
560 rc = apploader_send_response(chan, req.hdr.cmd,
561 APPLOADER_ERR_INVALID_CMD);
562 break;
563 }
564
565 rc = apploader_handle_cmd_load_app(chan, &req.load_app_req, handle);
566 break;
567
568 default:
569 TLOGE("Received unknown apploader command: %" PRIu32 "\n", req.hdr.cmd);
570 rc = apploader_send_response(chan, req.hdr.cmd,
571 APPLOADER_ERR_UNKNOWN_CMD);
572 break;
573 }
574
575 if (rc < 0) {
576 TLOGE("Failed to run command (%d)\n", rc);
577 }
578
579 if (handle != INVALID_IPC_HANDLE) {
580 close(handle);
581 }
582
583 return rc;
584 }
585
586 static struct tipc_srv_ops apploader_ops = {
587 .on_message = apploader_on_message,
588 };
589
main(void)590 int main(void) {
591 struct tipc_hset* hset = tipc_hset_create();
592
593 if (IS_ERR(hset)) {
594 return PTR_ERR(hset);
595 }
596
597 int rc = tipc_add_service(hset, &apploader_port, 1, 1, &apploader_ops);
598 if (rc < 0) {
599 return rc;
600 }
601
602 rc = tipc_run_event_loop(hset);
603 printf("app loader going down: (%d)\n", rc);
604 return rc;
605 }
606