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