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