blob: 60e77a782a7c2862dcd2d379d7c973277abcaa27 [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
Alan Stokes126fd512021-12-16 15:00:01 +000021use anyhow::{Context, Result};
Alan Stokes3189af02021-09-30 17:51:19 +010022use binder_common::new_binder_exception;
Alan Stokes126fd512021-12-16 15:00:01 +000023use compos_common::binder::to_binder_result;
Victor Hsieh9ed27182021-08-25 15:52:42 -070024use log::warn;
25use std::default::Default;
Victor Hsieh51789de2021-08-06 16:50:49 -070026use std::path::PathBuf;
Alan Stokes183d7d32021-12-08 16:10:45 +000027use std::sync::RwLock;
Victor Hsieh272aa242021-02-01 14:19:20 -080028
Victor Hsieh616f8222022-01-14 13:06:32 -080029use crate::compilation::{odrefresh, OdrefreshContext};
Alan Stokes46a1dff2021-12-14 10:56:05 +000030use crate::compos_key_service::{CompOsKeyService, Signer};
Alan Stokes71cc11e2022-01-17 10:39:05 +000031use crate::dice::Dice;
Victor Hsieh51789de2021-08-06 16:50:49 -070032use authfs_aidl_interface::aidl::com::android::virt::fs::IAuthFsService::IAuthFsService;
Victor Hsieh23f73592021-08-06 18:08:24 -070033use compos_aidl_interface::aidl::com::android::compos::{
34 CompOsKeyData::CompOsKeyData,
35 ICompOsService::{BnCompOsService, ICompOsService},
Victor Hsieh272aa242021-02-01 14:19:20 -080036};
Victor Hsieh272aa242021-02-01 14:19:20 -080037use compos_aidl_interface::binder::{
Alan Stokes3189af02021-09-30 17:51:19 +010038 BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Strong,
Victor Hsieh272aa242021-02-01 14:19:20 -080039};
Alan Stokes46a1dff2021-12-14 10:56:05 +000040use compos_common::odrefresh::ODREFRESH_PATH;
Victor Hsieh272aa242021-02-01 14:19:20 -080041
Victor Hsiehebb1d902021-08-06 13:00:18 -070042const AUTHFS_SERVICE_NAME: &str = "authfs_service";
Alan Stokes9e2c5d52021-07-21 11:29:10 +010043
Victor Hsieha64194b2021-08-06 17:43:36 -070044/// Constructs a binder object that implements ICompOsService.
Victor Hsieh9ebf7ee2021-09-03 16:14:14 -070045pub fn new_binder() -> Result<Strong<dyn ICompOsService>> {
Victor Hsieh23f73592021-08-06 18:08:24 -070046 let service = CompOsService {
Victor Hsiehf9968692021-11-18 11:34:39 -080047 odrefresh_path: PathBuf::from(ODREFRESH_PATH),
Victor Hsieh9ebf7ee2021-09-03 16:14:14 -070048 key_service: CompOsKeyService::new()?,
Alan Stokesc33d2922022-01-18 14:17:00 +000049 dice: Dice::new()?,
Alan Stokes183d7d32021-12-08 16:10:45 +000050 key_blob: RwLock::new(Vec::new()),
Victor Hsieh23f73592021-08-06 18:08:24 -070051 };
Victor Hsieha64194b2021-08-06 17:43:36 -070052 Ok(BnCompOsService::new_binder(service, BinderFeatures::default()))
Alan Stokes9e2c5d52021-07-21 11:29:10 +010053}
54
Victor Hsieha64194b2021-08-06 17:43:36 -070055struct CompOsService {
Victor Hsiehf9968692021-11-18 11:34:39 -080056 odrefresh_path: PathBuf,
Victor Hsieha64194b2021-08-06 17:43:36 -070057 key_service: CompOsKeyService,
Alan Stokesc33d2922022-01-18 14:17:00 +000058 dice: Dice,
Alan Stokes183d7d32021-12-08 16:10:45 +000059 key_blob: RwLock<Vec<u8>>,
Victor Hsieh272aa242021-02-01 14:19:20 -080060}
61
Victor Hsieh9ed27182021-08-25 15:52:42 -070062impl CompOsService {
Alan Stokes46a1dff2021-12-14 10:56:05 +000063 fn new_signer(&self) -> BinderResult<Signer> {
64 let key = &*self.key_blob.read().unwrap();
65 if key.is_empty() {
66 Err(new_binder_exception(ExceptionCode::ILLEGAL_STATE, "Key is not initialized"))
67 } else {
68 Ok(self.key_service.new_signer(key))
69 }
Victor Hsieh9ed27182021-08-25 15:52:42 -070070 }
Alan Stokes71cc11e2022-01-17 10:39:05 +000071
72 fn get_boot_certificate_chain(&self) -> Result<Vec<u8>> {
Alan Stokesc33d2922022-01-18 14:17:00 +000073 self.dice.get_boot_certificate_chain()
Alan Stokes71cc11e2022-01-17 10:39:05 +000074 }
Victor Hsieh9ed27182021-08-25 15:52:42 -070075}
76
Victor Hsieha64194b2021-08-06 17:43:36 -070077impl Interface for CompOsService {}
Victor Hsieh272aa242021-02-01 14:19:20 -080078
Victor Hsieha64194b2021-08-06 17:43:36 -070079impl ICompOsService for CompOsService {
Victor Hsieh8fd03f02021-08-24 17:23:01 -070080 fn initializeSigningKey(&self, key_blob: &[u8]) -> BinderResult<()> {
81 let mut w = self.key_blob.write().unwrap();
82 if w.is_empty() {
83 *w = Vec::from(key_blob);
84 Ok(())
85 } else {
86 Err(new_binder_exception(ExceptionCode::ILLEGAL_STATE, "Cannot re-initialize the key"))
87 }
88 }
89
Victor Hsiehf9968692021-11-18 11:34:39 -080090 fn odrefresh(
91 &self,
92 system_dir_fd: i32,
93 output_dir_fd: i32,
Alan Stokes9646db92021-12-14 13:22:33 +000094 staging_dir_fd: i32,
95 target_dir_name: &str,
Victor Hsiehf9968692021-11-18 11:34:39 -080096 zygote_arch: &str,
Victor Hsieh9bfbc5f2021-12-16 11:45:10 -080097 system_server_compiler_filter: &str,
Alan Stokes9646db92021-12-14 13:22:33 +000098 ) -> BinderResult<i8> {
Alan Stokes126fd512021-12-16 15:00:01 +000099 let context = to_binder_result(OdrefreshContext::new(
Victor Hsiehf9968692021-11-18 11:34:39 -0800100 system_dir_fd,
101 output_dir_fd,
Alan Stokes9646db92021-12-14 13:22:33 +0000102 staging_dir_fd,
Alan Stokes46a1dff2021-12-14 10:56:05 +0000103 target_dir_name,
Victor Hsiehf9968692021-11-18 11:34:39 -0800104 zygote_arch,
Victor Hsieh9bfbc5f2021-12-16 11:45:10 -0800105 system_server_compiler_filter,
Alan Stokes126fd512021-12-16 15:00:01 +0000106 ))?;
Alan Stokes46a1dff2021-12-14 10:56:05 +0000107
108 let authfs_service = get_authfs_service()?;
Alan Stokes126fd512021-12-16 15:00:01 +0000109 let exit_code = to_binder_result(
110 odrefresh(&self.odrefresh_path, context, authfs_service, self.new_signer()?)
111 .context("odrefresh failed"),
112 )?;
Alan Stokes46a1dff2021-12-14 10:56:05 +0000113 Ok(exit_code as i8)
Victor Hsiehf9968692021-11-18 11:34:39 -0800114 }
115
Victor Hsieh23f73592021-08-06 18:08:24 -0700116 fn generateSigningKey(&self) -> BinderResult<CompOsKeyData> {
Alan Stokes126fd512021-12-16 15:00:01 +0000117 to_binder_result(self.key_service.generate())
Victor Hsieh23f73592021-08-06 18:08:24 -0700118 }
119
120 fn verifySigningKey(&self, key_blob: &[u8], public_key: &[u8]) -> BinderResult<bool> {
Alan Stokes183d7d32021-12-08 16:10:45 +0000121 Ok(if let Err(e) = self.key_service.verify(key_blob, public_key) {
Alan Stokes126fd512021-12-16 15:00:01 +0000122 warn!("Signing key verification failed: {:?}", e);
Victor Hsieh23f73592021-08-06 18:08:24 -0700123 false
124 } else {
125 true
126 })
127 }
Alan Stokes71cc11e2022-01-17 10:39:05 +0000128
129 fn getBootCertificateChain(&self) -> BinderResult<Vec<u8>> {
130 to_binder_result(self.get_boot_certificate_chain())
131 }
Victor Hsieh272aa242021-02-01 14:19:20 -0800132}
Victor Hsiehebb1d902021-08-06 13:00:18 -0700133
134fn get_authfs_service() -> BinderResult<Strong<dyn IAuthFsService>> {
135 Ok(authfs_aidl_interface::binder::get_interface(AUTHFS_SERVICE_NAME)?)
136}