blob: 8fe47954856f8c4b705bb0b49ce2777ce0bdbd57 [file] [log] [blame]
Victor Hsieh272aa242021-02-01 14:19:20 -08001/*
2 * Copyright (C) 2021 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
Victor Hsieh51789de2021-08-06 16:50:49 -070017//! compsvc is a service to run compilation tasks in a PVM upon request. It is able to set up
Victor Hsiehebb1d902021-08-06 13:00:18 -070018//! file descriptors backed by authfs (via authfs_service) and pass the file descriptors to the
Victor Hsieh51789de2021-08-06 16:50:49 -070019//! actual compiler.
Victor Hsieh272aa242021-02-01 14:19:20 -080020
Victor Hsieha64194b2021-08-06 17:43:36 -070021use anyhow::Result;
Victor Hsieh6e340382021-08-13 12:18:02 -070022use log::{debug, warn};
Victor Hsieha64194b2021-08-06 17:43:36 -070023use std::ffi::CString;
Victor Hsieh51789de2021-08-06 16:50:49 -070024use std::path::PathBuf;
Victor Hsieh272aa242021-02-01 14:19:20 -080025
Victor Hsieh6e340382021-08-13 12:18:02 -070026use crate::compilation::{compile, CompilerOutput};
Victor Hsieh23f73592021-08-06 18:08:24 -070027use crate::compos_key_service::CompOsKeyService;
Victor Hsieh51789de2021-08-06 16:50:49 -070028use authfs_aidl_interface::aidl::com::android::virt::fs::IAuthFsService::IAuthFsService;
Victor Hsieh23f73592021-08-06 18:08:24 -070029use compos_aidl_interface::aidl::com::android::compos::{
30 CompOsKeyData::CompOsKeyData,
31 ICompOsService::{BnCompOsService, ICompOsService},
32 Metadata::Metadata,
Victor Hsieh272aa242021-02-01 14:19:20 -080033};
Victor Hsieh272aa242021-02-01 14:19:20 -080034use compos_aidl_interface::binder::{
Victor Hsieh51789de2021-08-06 16:50:49 -070035 BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Status, Strong,
Victor Hsieh272aa242021-02-01 14:19:20 -080036};
37
Victor Hsiehebb1d902021-08-06 13:00:18 -070038const AUTHFS_SERVICE_NAME: &str = "authfs_service";
Victor Hsieh51789de2021-08-06 16:50:49 -070039const DEX2OAT_PATH: &str = "/apex/com.android.art/bin/dex2oat64";
Alan Stokes9e2c5d52021-07-21 11:29:10 +010040
Victor Hsieha64194b2021-08-06 17:43:36 -070041/// Constructs a binder object that implements ICompOsService.
Victor Hsieh23f73592021-08-06 18:08:24 -070042pub fn new_binder(rpc_binder: bool) -> Result<Strong<dyn ICompOsService>> {
43 let service = CompOsService {
44 dex2oat_path: PathBuf::from(DEX2OAT_PATH),
45 key_service: CompOsKeyService::new(rpc_binder)?,
46 };
Victor Hsieha64194b2021-08-06 17:43:36 -070047 Ok(BnCompOsService::new_binder(service, BinderFeatures::default()))
Alan Stokes9e2c5d52021-07-21 11:29:10 +010048}
49
Victor Hsieha64194b2021-08-06 17:43:36 -070050struct CompOsService {
Victor Hsieh51789de2021-08-06 16:50:49 -070051 dex2oat_path: PathBuf,
Victor Hsieha64194b2021-08-06 17:43:36 -070052 key_service: CompOsKeyService,
Victor Hsieh272aa242021-02-01 14:19:20 -080053}
54
Victor Hsieha64194b2021-08-06 17:43:36 -070055impl Interface for CompOsService {}
Victor Hsieh272aa242021-02-01 14:19:20 -080056
Victor Hsieha64194b2021-08-06 17:43:36 -070057impl ICompOsService for CompOsService {
Victor Hsieh272aa242021-02-01 14:19:20 -080058 fn execute(&self, args: &[String], metadata: &Metadata) -> BinderResult<i8> {
Victor Hsieh51789de2021-08-06 16:50:49 -070059 let authfs_service = get_authfs_service()?;
Victor Hsieh6e340382021-08-13 12:18:02 -070060 let output = compile(&self.dex2oat_path, args, authfs_service, metadata).map_err(|e| {
Victor Hsieh51789de2021-08-06 16:50:49 -070061 new_binder_exception(
62 ExceptionCode::SERVICE_SPECIFIC,
63 format!("Compilation failed: {}", e),
64 )
Victor Hsieh6e340382021-08-13 12:18:02 -070065 })?;
66 match output {
67 CompilerOutput::Digests { oat, vdex, image } => {
68 // TODO(b/161471326): Sign the output on succeed.
69 debug!("oat fs-verity digest: {:02x?}", oat);
70 debug!("vdex fs-verity digest: {:02x?}", vdex);
71 debug!("image fs-verity digest: {:02x?}", image);
72 Ok(0)
73 }
74 CompilerOutput::ExitCode(exit_code) => Ok(exit_code),
75 }
Victor Hsieh272aa242021-02-01 14:19:20 -080076 }
Victor Hsieh23f73592021-08-06 18:08:24 -070077
78 fn generateSigningKey(&self) -> BinderResult<CompOsKeyData> {
79 self.key_service
80 .do_generate()
81 .map_err(|e| new_binder_exception(ExceptionCode::ILLEGAL_STATE, e.to_string()))
82 }
83
84 fn verifySigningKey(&self, key_blob: &[u8], public_key: &[u8]) -> BinderResult<bool> {
85 Ok(if let Err(e) = self.key_service.do_verify(key_blob, public_key) {
86 warn!("Signing key verification failed: {}", e.to_string());
87 false
88 } else {
89 true
90 })
91 }
92
93 fn sign(&self, key_blob: &[u8], data: &[u8]) -> BinderResult<Vec<u8>> {
94 self.key_service
95 .do_sign(key_blob, data)
96 .map_err(|e| new_binder_exception(ExceptionCode::ILLEGAL_STATE, e.to_string()))
97 }
Victor Hsieh272aa242021-02-01 14:19:20 -080098}
Victor Hsiehebb1d902021-08-06 13:00:18 -070099
100fn get_authfs_service() -> BinderResult<Strong<dyn IAuthFsService>> {
101 Ok(authfs_aidl_interface::binder::get_interface(AUTHFS_SERVICE_NAME)?)
102}
103
Victor Hsiehebb1d902021-08-06 13:00:18 -0700104fn new_binder_exception<T: AsRef<str>>(exception: ExceptionCode, message: T) -> Status {
105 Status::new_exception(exception, CString::new(message.as_ref()).as_deref().ok())
106}