1 // Copyright 2021, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Android VirtualizationService
16 
17 mod aidl;
18 mod atom;
19 mod maintenance;
20 mod remote_provisioning;
21 mod rkpvm;
22 
23 use crate::aidl::{
24     is_remote_provisioning_hal_declared, remove_temporary_dir, VirtualizationServiceInternal,
25     TEMPORARY_DIRECTORY,
26 };
27 use android_logger::{Config, FilterBuilder};
28 use android_system_virtualizationmaintenance::aidl::android::system::virtualizationmaintenance;
29 use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal;
30 use anyhow::{bail, Context, Error, Result};
31 use binder::{register_lazy_service, BinderFeatures, ProcessState, ThreadState};
32 use log::{error, info, LevelFilter};
33 use std::fs::{create_dir, read_dir};
34 use std::os::unix::raw::{pid_t, uid_t};
35 use std::path::Path;
36 use virtualizationmaintenance::IVirtualizationMaintenance::BnVirtualizationMaintenance;
37 use virtualizationservice_internal::IVirtualizationServiceInternal::BnVirtualizationServiceInternal;
38 
39 const LOG_TAG: &str = "VirtualizationService";
40 pub(crate) const REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME: &str =
41     "android.hardware.security.keymint.IRemotelyProvisionedComponent/avf";
42 const INTERNAL_SERVICE_NAME: &str = "android.system.virtualizationservice";
43 const MAINTENANCE_SERVICE_NAME: &str = "android.system.virtualizationmaintenance";
44 
get_calling_pid() -> pid_t45 fn get_calling_pid() -> pid_t {
46     ThreadState::get_calling_pid()
47 }
48 
get_calling_uid() -> uid_t49 fn get_calling_uid() -> uid_t {
50     ThreadState::get_calling_uid()
51 }
52 
main()53 fn main() {
54     if let Err(e) = try_main() {
55         error!("failed with {e:?}");
56         std::process::exit(1);
57     }
58 }
59 
try_main() -> Result<()>60 fn try_main() -> Result<()> {
61     android_logger::init_once(
62         Config::default()
63             .with_tag(LOG_TAG)
64             .with_max_level(LevelFilter::Info)
65             .with_log_buffer(android_logger::LogId::System)
66             .with_filter(
67                 // Reduce logspam by silencing logs from the disk crate which don't provide much
68                 // information to us.
69                 FilterBuilder::new().parse("info,disk=off").build(),
70             ),
71     );
72 
73     clear_temporary_files().context("Failed to delete old temporary files")?;
74 
75     let common_dir_path = Path::new(TEMPORARY_DIRECTORY).join("common");
76     create_dir(common_dir_path).context("Failed to create common directory")?;
77 
78     ProcessState::start_thread_pool();
79 
80     // One instance of `VirtualizationServiceInternal` implements both the internal interface
81     // and (optionally) the maintenance interface.
82     let service = VirtualizationServiceInternal::init();
83     let internal_service =
84         BnVirtualizationServiceInternal::new_binder(service.clone(), BinderFeatures::default());
85     register(INTERNAL_SERVICE_NAME, internal_service)?;
86 
87     if is_remote_provisioning_hal_declared().unwrap_or(false) {
88         // The IRemotelyProvisionedComponent service is only supposed to be triggered by rkpd for
89         // RKP VM attestation.
90         let remote_provisioning_service = remote_provisioning::new_binder();
91         register(REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME, remote_provisioning_service)?;
92     }
93 
94     if cfg!(llpvm_changes) {
95         let maintenance_service =
96             BnVirtualizationMaintenance::new_binder(service.clone(), BinderFeatures::default());
97         register(MAINTENANCE_SERVICE_NAME, maintenance_service)?;
98     }
99 
100     ProcessState::join_thread_pool();
101     bail!("Thread pool unexpectedly ended");
102 }
103 
register<T: binder::FromIBinder + ?Sized>(name: &str, service: binder::Strong<T>) -> Result<()>104 fn register<T: binder::FromIBinder + ?Sized>(name: &str, service: binder::Strong<T>) -> Result<()> {
105     register_lazy_service(name, service.as_binder())
106         .with_context(|| format!("Failed to register {name}"))?;
107     info!("Registered Binder service {name}.");
108     Ok(())
109 }
110 
111 /// Remove any files under `TEMPORARY_DIRECTORY`.
clear_temporary_files() -> Result<(), Error>112 fn clear_temporary_files() -> Result<(), Error> {
113     for dir_entry in read_dir(TEMPORARY_DIRECTORY)? {
114         remove_temporary_dir(&dir_entry?.path())?
115     }
116     Ok(())
117 }
118