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 //! Implementation of the AIDL interface of the VirtualizationService.
16 
17 use crate::atom::{forward_vm_booted_atom, forward_vm_creation_atom, forward_vm_exited_atom};
18 use crate::maintenance;
19 use crate::remote_provisioning;
20 use crate::rkpvm::{generate_ecdsa_p256_key_pair, request_attestation};
21 use crate::{get_calling_pid, get_calling_uid, REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME};
22 use android_os_permissions_aidl::aidl::android::os::IPermissionController;
23 use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon;
24 use android_system_virtualizationmaintenance::aidl::android::system::virtualizationmaintenance;
25 use android_system_virtualizationservice::aidl::android::system::virtualizationservice;
26 use android_system_virtualizationservice_internal as android_vs_internal;
27 use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice;
28 use android_vs_internal::aidl::android::system::virtualizationservice_internal;
29 use anyhow::{anyhow, ensure, Context, Result};
30 use avflog::LogResult;
31 use binder::{
32     self, wait_for_interface, BinderFeatures, ExceptionCode, Interface, IntoBinderResult,
33     LazyServiceGuard, ParcelFileDescriptor, Status, Strong,
34 };
35 use lazy_static::lazy_static;
36 use libc::VMADDR_CID_HOST;
37 use log::{error, info, warn};
38 use nix::unistd::{chown, Uid};
39 use openssl::x509::X509;
40 use rand::Fill;
41 use rkpd_client::get_rkpd_attestation_key;
42 use rustutils::{
43     system_properties,
44     users::{multiuser_get_app_id, multiuser_get_user_id},
45 };
46 use serde::Deserialize;
47 use service_vm_comm::Response;
48 use std::collections::{HashMap, HashSet};
49 use std::fs::{self, create_dir, remove_dir_all, remove_file, set_permissions, File, Permissions};
50 use std::io::{Read, Write};
51 use std::os::unix::fs::PermissionsExt;
52 use std::os::unix::raw::{pid_t, uid_t};
53 use std::path::{Path, PathBuf};
54 use std::sync::{Arc, Condvar, Mutex, Weak};
55 use tombstoned_client::{DebuggerdDumpType, TombstonedConnection};
56 use virtualizationcommon::Certificate::Certificate;
57 use virtualizationmaintenance::{
58     IVirtualizationMaintenance::IVirtualizationMaintenance,
59     IVirtualizationReconciliationCallback::IVirtualizationReconciliationCallback,
60 };
61 use virtualizationservice::{
62     AssignableDevice::AssignableDevice, VirtualMachineDebugInfo::VirtualMachineDebugInfo,
63 };
64 use virtualizationservice_internal::{
65     AtomVmBooted::AtomVmBooted,
66     AtomVmCreationRequested::AtomVmCreationRequested,
67     AtomVmExited::AtomVmExited,
68     IBoundDevice::IBoundDevice,
69     IGlobalVmContext::{BnGlobalVmContext, IGlobalVmContext},
70     IVfioHandler::VfioDev::VfioDev,
71     IVfioHandler::{BpVfioHandler, IVfioHandler},
72     IVirtualizationServiceInternal::IVirtualizationServiceInternal,
73     IVmnic::{BpVmnic, IVmnic},
74 };
75 use virtualmachineservice::IVirtualMachineService::VM_TOMBSTONES_SERVICE_PORT;
76 use vsock::{VsockListener, VsockStream};
77 
78 /// The unique ID of a VM used (together with a port number) for vsock communication.
79 pub type Cid = u32;
80 
81 /// Directory in which to write disk image files used while running VMs.
82 pub const TEMPORARY_DIRECTORY: &str = "/data/misc/virtualizationservice";
83 
84 /// The first CID to assign to a guest VM managed by the VirtualizationService. CIDs lower than this
85 /// are reserved for the host or other usage.
86 const GUEST_CID_MIN: Cid = 2048;
87 const GUEST_CID_MAX: Cid = 65535;
88 
89 const SYSPROP_LAST_CID: &str = "virtualizationservice.state.last_cid";
90 
91 const CHUNK_RECV_MAX_LEN: usize = 1024;
92 
93 /// The fake certificate is used for testing only when a client VM requests attestation in test
94 /// mode, it is a single certificate extracted on an unregistered device for testing.
95 /// Here is the snapshot of the certificate:
96 ///
97 /// ```
98 /// Certificate:
99 /// Data:
100 /// Version: 3 (0x2)
101 /// Serial Number:
102 ///     59:ae:50:98:95:e1:34:25:f1:21:93:c0:4c:e5:24:66
103 /// Signature Algorithm: ecdsa-with-SHA256
104 /// Issuer: CN = Droid Unregistered Device CA, O = Google Test LLC
105 /// Validity
106 ///     Not Before: Feb  5 14:39:39 2024 GMT
107 ///     Not After : Feb 14 14:39:39 2024 GMT
108 /// Subject: CN = 59ae509895e13425f12193c04ce52466, O = TEE
109 /// Subject Public Key Info:
110 ///     Public Key Algorithm: id-ecPublicKey
111 ///         Public-Key: (256 bit)
112 ///         pub:
113 ///             04:30:32:cd:95:12:b0:71:8b:b7:14:44:26:58:d5:
114 ///             82:8c:25:55:2c:6d:ef:98:e3:4f:88:d0:74:82:09:
115 ///             3e:8d:6c:f0:f2:18:d5:83:0e:0d:f2:ce:c5:15:38:
116 ///             e5:6a:e6:4d:4d:95:15:b7:24:e7:cb:4b:63:42:21:
117 ///             bc:36:c6:0a:d8
118 ///         ASN1 OID: prime256v1
119 ///         NIST CURVE: P-256
120 /// X509v3 extensions:
121 ///  ...
122 /// ```
123 const FAKE_CERTIFICATE_FOR_TESTING: &[u8] = &[
124     0x30, 0x82, 0x01, 0xee, 0x30, 0x82, 0x01, 0x94, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x59,
125     0xae, 0x50, 0x98, 0x95, 0xe1, 0x34, 0x25, 0xf1, 0x21, 0x93, 0xc0, 0x4c, 0xe5, 0x24, 0x66, 0x30,
126     0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x41, 0x31, 0x25, 0x30,
127     0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c, 0x44, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x55, 0x6e,
128     0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63,
129     0x65, 0x20, 0x43, 0x41, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f, 0x47,
130     0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x4c, 0x4c, 0x43, 0x30, 0x1e,
131     0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x30, 0x35, 0x31, 0x34, 0x33, 0x39, 0x33, 0x39, 0x5a, 0x17,
132     0x0d, 0x32, 0x34, 0x30, 0x32, 0x31, 0x34, 0x31, 0x34, 0x33, 0x39, 0x33, 0x39, 0x5a, 0x30, 0x39,
133     0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x35, 0x39, 0x61, 0x65, 0x35,
134     0x30, 0x39, 0x38, 0x39, 0x35, 0x65, 0x31, 0x33, 0x34, 0x32, 0x35, 0x66, 0x31, 0x32, 0x31, 0x39,
135     0x33, 0x63, 0x30, 0x34, 0x63, 0x65, 0x35, 0x32, 0x34, 0x36, 0x36, 0x31, 0x0c, 0x30, 0x0a, 0x06,
136     0x03, 0x55, 0x04, 0x0a, 0x13, 0x03, 0x54, 0x45, 0x45, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a,
137     0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
138     0x03, 0x42, 0x00, 0x04, 0x30, 0x32, 0xcd, 0x95, 0x12, 0xb0, 0x71, 0x8b, 0xb7, 0x14, 0x44, 0x26,
139     0x58, 0xd5, 0x82, 0x8c, 0x25, 0x55, 0x2c, 0x6d, 0xef, 0x98, 0xe3, 0x4f, 0x88, 0xd0, 0x74, 0x82,
140     0x09, 0x3e, 0x8d, 0x6c, 0xf0, 0xf2, 0x18, 0xd5, 0x83, 0x0e, 0x0d, 0xf2, 0xce, 0xc5, 0x15, 0x38,
141     0xe5, 0x6a, 0xe6, 0x4d, 0x4d, 0x95, 0x15, 0xb7, 0x24, 0xe7, 0xcb, 0x4b, 0x63, 0x42, 0x21, 0xbc,
142     0x36, 0xc6, 0x0a, 0xd8, 0xa3, 0x76, 0x30, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
143     0x16, 0x04, 0x14, 0x39, 0x81, 0x41, 0x0a, 0xb9, 0xf3, 0xf4, 0x5b, 0x75, 0x97, 0x4a, 0x46, 0xd6,
144     0x30, 0x9e, 0x1d, 0x7a, 0x3b, 0xec, 0xa8, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
145     0x30, 0x16, 0x80, 0x14, 0x82, 0xbd, 0x00, 0xde, 0xcb, 0xc5, 0xe7, 0x72, 0x87, 0x3d, 0x1c, 0x0a,
146     0x1e, 0x78, 0x4f, 0xf5, 0xd3, 0xc1, 0x3e, 0xb8, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
147     0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
148     0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x11, 0x06, 0x0a, 0x2b, 0x06, 0x01,
149     0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x1e, 0x04, 0x03, 0xa1, 0x01, 0x08, 0x30, 0x0a, 0x06, 0x08,
150     0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00,
151     0xae, 0xd8, 0x40, 0x9e, 0x37, 0x3e, 0x5c, 0x9c, 0xe2, 0x93, 0x3d, 0x8c, 0xf7, 0x05, 0x10, 0xe7,
152     0xd1, 0x2b, 0x87, 0x8a, 0xee, 0xd6, 0x1e, 0x6c, 0x3b, 0xd2, 0x91, 0x3e, 0xa5, 0xdf, 0x91, 0x20,
153     0x02, 0x20, 0x7f, 0x0f, 0x29, 0x54, 0x60, 0x80, 0x07, 0x50, 0x5f, 0x56, 0x6b, 0x9f, 0xe0, 0x94,
154     0xb4, 0x3f, 0x3b, 0x0f, 0x61, 0xa0, 0x33, 0x40, 0xe6, 0x1a, 0x42, 0xda, 0x4b, 0xa4, 0xfd, 0x92,
155     0xb9, 0x0f,
156 ];
157 
158 lazy_static! {
159     static ref FAKE_PROVISIONED_KEY_BLOB_FOR_TESTING: Mutex<Option<Vec<u8>>> = Mutex::new(None);
160     static ref VFIO_SERVICE: Strong<dyn IVfioHandler> =
161         wait_for_interface(<BpVfioHandler as IVfioHandler>::get_descriptor())
162             .expect("Could not connect to VfioHandler");
163     static ref NETWORK_SERVICE: Strong<dyn IVmnic> =
164         wait_for_interface(<BpVmnic as IVmnic>::get_descriptor())
165             .expect("Could not connect to Vmnic");
166 }
167 
is_valid_guest_cid(cid: Cid) -> bool168 fn is_valid_guest_cid(cid: Cid) -> bool {
169     (GUEST_CID_MIN..=GUEST_CID_MAX).contains(&cid)
170 }
171 
172 /// Singleton service for allocating globally-unique VM resources, such as the CID, and running
173 /// singleton servers, like tombstone receiver.
174 #[derive(Clone)]
175 pub struct VirtualizationServiceInternal {
176     state: Arc<Mutex<GlobalState>>,
177     display_service_set: Arc<Condvar>,
178 }
179 
180 impl VirtualizationServiceInternal {
init() -> VirtualizationServiceInternal181     pub fn init() -> VirtualizationServiceInternal {
182         let service = VirtualizationServiceInternal {
183             state: Arc::new(Mutex::new(GlobalState::new())),
184             display_service_set: Arc::new(Condvar::new()),
185         };
186 
187         std::thread::spawn(|| {
188             if let Err(e) = handle_stream_connection_tombstoned() {
189                 warn!("Error receiving tombstone from guest or writing them. Error: {:?}", e);
190             }
191         });
192 
193         service
194     }
195 }
196 
197 impl Interface for VirtualizationServiceInternal {}
198 
199 impl IVirtualizationServiceInternal for VirtualizationServiceInternal {
setDisplayService( &self, ibinder: &binder::SpIBinder, ) -> std::result::Result<(), binder::Status>200     fn setDisplayService(
201         &self,
202         ibinder: &binder::SpIBinder,
203     ) -> std::result::Result<(), binder::Status> {
204         check_manage_access()?;
205         check_use_custom_virtual_machine()?;
206         let state = &mut *self.state.lock().unwrap();
207         state.display_service = Some(ibinder.clone());
208         self.display_service_set.notify_all();
209         Ok(())
210     }
211 
clearDisplayService(&self) -> std::result::Result<(), binder::Status>212     fn clearDisplayService(&self) -> std::result::Result<(), binder::Status> {
213         check_manage_access()?;
214         check_use_custom_virtual_machine()?;
215         let state = &mut *self.state.lock().unwrap();
216         state.display_service = None;
217         self.display_service_set.notify_all();
218         Ok(())
219     }
220 
waitDisplayService(&self) -> std::result::Result<binder::SpIBinder, binder::Status>221     fn waitDisplayService(&self) -> std::result::Result<binder::SpIBinder, binder::Status> {
222         check_manage_access()?;
223         check_use_custom_virtual_machine()?;
224         let state = self
225             .display_service_set
226             .wait_while(self.state.lock().unwrap(), |state| state.display_service.is_none())
227             .unwrap();
228         Ok((state.display_service)
229             .as_ref()
230             .cloned()
231             .expect("Display service cannot be None in this context"))
232     }
removeMemlockRlimit(&self) -> binder::Result<()>233     fn removeMemlockRlimit(&self) -> binder::Result<()> {
234         let pid = get_calling_pid();
235         let lim = libc::rlimit { rlim_cur: libc::RLIM_INFINITY, rlim_max: libc::RLIM_INFINITY };
236 
237         // SAFETY: borrowing the new limit struct only
238         let ret = unsafe { libc::prlimit(pid, libc::RLIMIT_MEMLOCK, &lim, std::ptr::null_mut()) };
239 
240         match ret {
241             0 => Ok(()),
242             -1 => Err(std::io::Error::last_os_error().into()),
243             n => Err(anyhow!("Unexpected return value from prlimit(): {n}")),
244         }
245         .or_binder_exception(ExceptionCode::ILLEGAL_STATE)
246     }
247 
allocateGlobalVmContext( &self, requester_debug_pid: i32, ) -> binder::Result<Strong<dyn IGlobalVmContext>>248     fn allocateGlobalVmContext(
249         &self,
250         requester_debug_pid: i32,
251     ) -> binder::Result<Strong<dyn IGlobalVmContext>> {
252         check_manage_access()?;
253 
254         let requester_uid = get_calling_uid();
255         let requester_debug_pid = requester_debug_pid as pid_t;
256         let state = &mut *self.state.lock().unwrap();
257         state
258             .allocate_vm_context(requester_uid, requester_debug_pid)
259             .or_binder_exception(ExceptionCode::ILLEGAL_STATE)
260     }
261 
atomVmBooted(&self, atom: &AtomVmBooted) -> Result<(), Status>262     fn atomVmBooted(&self, atom: &AtomVmBooted) -> Result<(), Status> {
263         forward_vm_booted_atom(atom);
264         Ok(())
265     }
266 
atomVmCreationRequested(&self, atom: &AtomVmCreationRequested) -> Result<(), Status>267     fn atomVmCreationRequested(&self, atom: &AtomVmCreationRequested) -> Result<(), Status> {
268         forward_vm_creation_atom(atom);
269         Ok(())
270     }
271 
atomVmExited(&self, atom: &AtomVmExited) -> Result<(), Status>272     fn atomVmExited(&self, atom: &AtomVmExited) -> Result<(), Status> {
273         forward_vm_exited_atom(atom);
274         Ok(())
275     }
276 
debugListVms(&self) -> binder::Result<Vec<VirtualMachineDebugInfo>>277     fn debugListVms(&self) -> binder::Result<Vec<VirtualMachineDebugInfo>> {
278         check_debug_access()?;
279 
280         let state = &mut *self.state.lock().unwrap();
281         let cids = state
282             .held_contexts
283             .iter()
284             .filter_map(|(_, inst)| Weak::upgrade(inst))
285             .map(|vm| VirtualMachineDebugInfo {
286                 cid: vm.cid as i32,
287                 temporaryDirectory: vm.get_temp_dir().to_string_lossy().to_string(),
288                 requesterUid: vm.requester_uid as i32,
289                 requesterPid: vm.requester_debug_pid,
290             })
291             .collect();
292         Ok(cids)
293     }
294 
enableTestAttestation(&self) -> binder::Result<()>295     fn enableTestAttestation(&self) -> binder::Result<()> {
296         check_manage_access()?;
297         check_use_custom_virtual_machine()?;
298         if !cfg!(remote_attestation) {
299             return Err(Status::new_exception_str(
300                 ExceptionCode::UNSUPPORTED_OPERATION,
301                 Some(
302                     "enableTestAttestation is not supported with the remote_attestation \
303                      feature disabled",
304                 ),
305             ))
306             .with_log();
307         }
308         let res = generate_ecdsa_p256_key_pair()
309             .context("Failed to generate ECDSA P-256 key pair for testing")
310             .with_log()
311             .or_service_specific_exception(-1)?;
312         // Wait until the service VM shuts down, so that the Service VM will be restarted when
313         // the key generated in the current session will be used for attestation.
314         // This ensures that different Service VM sessions have the same KEK for the key blob.
315         service_vm_manager::wait_until_service_vm_shuts_down()
316             .context("Failed to wait until the service VM shuts down")
317             .with_log()
318             .or_service_specific_exception(-1)?;
319         match res {
320             Response::GenerateEcdsaP256KeyPair(key_pair) => {
321                 FAKE_PROVISIONED_KEY_BLOB_FOR_TESTING
322                     .lock()
323                     .unwrap()
324                     .replace(key_pair.key_blob.to_vec());
325                 Ok(())
326             }
327             _ => Err(remote_provisioning::to_service_specific_error(res)),
328         }
329         .with_log()
330     }
331 
requestAttestation( &self, csr: &[u8], requester_uid: i32, test_mode: bool, ) -> binder::Result<Vec<Certificate>>332     fn requestAttestation(
333         &self,
334         csr: &[u8],
335         requester_uid: i32,
336         test_mode: bool,
337     ) -> binder::Result<Vec<Certificate>> {
338         check_manage_access()?;
339         if !cfg!(remote_attestation) {
340             return Err(Status::new_exception_str(
341                 ExceptionCode::UNSUPPORTED_OPERATION,
342                 Some(
343                     "requestAttestation is not supported with the remote_attestation feature \
344                      disabled",
345                 ),
346             ))
347             .with_log();
348         }
349         if !is_remote_provisioning_hal_declared()? {
350             return Err(Status::new_exception_str(
351                 ExceptionCode::UNSUPPORTED_OPERATION,
352                 Some("AVF remotely provisioned component service is not declared"),
353             ))
354             .with_log();
355         }
356         remote_provisioning::check_remote_attestation_is_supported()?;
357         info!("Received csr. Requestting attestation...");
358         let (key_blob, certificate_chain) = if test_mode {
359             check_use_custom_virtual_machine()?;
360             info!("Using the fake key blob for testing...");
361             (
362                 FAKE_PROVISIONED_KEY_BLOB_FOR_TESTING
363                     .lock()
364                     .unwrap()
365                     .clone()
366                     .ok_or_else(|| anyhow!("No key blob for testing"))
367                     .with_log()
368                     .or_service_specific_exception(-1)?,
369                 FAKE_CERTIFICATE_FOR_TESTING.to_vec(),
370             )
371         } else {
372             info!("Retrieving the remotely provisioned keys from RKPD...");
373             let attestation_key = get_rkpd_attestation_key(
374                 REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME,
375                 requester_uid as u32,
376             )
377             .context("Failed to retrieve the remotely provisioned keys")
378             .with_log()
379             .or_service_specific_exception(-1)?;
380             (attestation_key.keyBlob, attestation_key.encodedCertChain)
381         };
382         let mut certificate_chain = split_x509_certificate_chain(&certificate_chain)
383             .context("Failed to split the remotely provisioned certificate chain")
384             .with_log()
385             .or_service_specific_exception(-1)?;
386         if certificate_chain.is_empty() {
387             return Err(Status::new_service_specific_error_str(
388                 -1,
389                 Some("The certificate chain should contain at least 1 certificate"),
390             ))
391             .with_log();
392         }
393         let certificate = request_attestation(
394             csr.to_vec(),
395             key_blob,
396             certificate_chain[0].encodedCertificate.clone(),
397         )
398         .context("Failed to request attestation")
399         .with_log()
400         .or_service_specific_exception(-1)?;
401         certificate_chain.insert(0, Certificate { encodedCertificate: certificate });
402 
403         Ok(certificate_chain)
404     }
405 
isRemoteAttestationSupported(&self) -> binder::Result<bool>406     fn isRemoteAttestationSupported(&self) -> binder::Result<bool> {
407         Ok(is_remote_provisioning_hal_declared()?
408             && remote_provisioning::is_remote_attestation_supported())
409     }
410 
getAssignableDevices(&self) -> binder::Result<Vec<AssignableDevice>>411     fn getAssignableDevices(&self) -> binder::Result<Vec<AssignableDevice>> {
412         check_use_custom_virtual_machine()?;
413 
414         Ok(get_assignable_devices()?
415             .device
416             .into_iter()
417             .map(|x| AssignableDevice { node: x.sysfs_path, dtbo_label: x.dtbo_label })
418             .collect::<Vec<_>>())
419     }
420 
bindDevicesToVfioDriver( &self, devices: &[String], ) -> binder::Result<Vec<Strong<dyn IBoundDevice>>>421     fn bindDevicesToVfioDriver(
422         &self,
423         devices: &[String],
424     ) -> binder::Result<Vec<Strong<dyn IBoundDevice>>> {
425         check_use_custom_virtual_machine()?;
426 
427         let devices = get_assignable_devices()?
428             .device
429             .into_iter()
430             .filter_map(|x| {
431                 if devices.contains(&x.sysfs_path) {
432                     Some(VfioDev { sysfsPath: x.sysfs_path, dtboLabel: x.dtbo_label })
433                 } else {
434                     warn!("device {} is not assignable", x.sysfs_path);
435                     None
436                 }
437             })
438             .collect::<Vec<VfioDev>>();
439 
440         VFIO_SERVICE.bindDevicesToVfioDriver(devices.as_slice())
441     }
442 
getDtboFile(&self) -> binder::Result<ParcelFileDescriptor>443     fn getDtboFile(&self) -> binder::Result<ParcelFileDescriptor> {
444         check_use_custom_virtual_machine()?;
445 
446         let state = &mut *self.state.lock().unwrap();
447         let file = state.get_dtbo_file().or_service_specific_exception(-1)?;
448         Ok(ParcelFileDescriptor::new(file))
449     }
450 
allocateInstanceId(&self) -> binder::Result<[u8; 64]>451     fn allocateInstanceId(&self) -> binder::Result<[u8; 64]> {
452         let mut id = [0u8; 64];
453         id.try_fill(&mut rand::thread_rng())
454             .context("Failed to allocate instance_id")
455             .or_service_specific_exception(-1)?;
456         let uid = get_calling_uid();
457         info!("Allocated a VM's instance_id: {:?}..., for uid: {:?}", &hex::encode(id)[..8], uid);
458         let state = &mut *self.state.lock().unwrap();
459         if let Some(sk_state) = &mut state.sk_state {
460             let user_id = multiuser_get_user_id(uid);
461             let app_id = multiuser_get_app_id(uid);
462             info!("Recording possible existence of state for (user_id={user_id}, app_id={app_id})");
463             if let Err(e) = sk_state.add_id(&id, user_id, app_id) {
464                 error!("Failed to record the instance_id: {e:?}");
465             }
466         }
467 
468         Ok(id)
469     }
470 
removeVmInstance(&self, instance_id: &[u8; 64]) -> binder::Result<()>471     fn removeVmInstance(&self, instance_id: &[u8; 64]) -> binder::Result<()> {
472         let state = &mut *self.state.lock().unwrap();
473         if let Some(sk_state) = &mut state.sk_state {
474             let uid = get_calling_uid();
475             info!(
476                 "Removing a VM's instance_id: {:?}, for uid: {:?}",
477                 hex::encode(instance_id),
478                 uid
479             );
480 
481             let user_id = multiuser_get_user_id(uid);
482             let app_id = multiuser_get_app_id(uid);
483             sk_state.delete_id(instance_id, user_id, app_id);
484         } else {
485             info!("ignoring removeVmInstance() as no ISecretkeeper");
486         }
487         Ok(())
488     }
489 
claimVmInstance(&self, instance_id: &[u8; 64]) -> binder::Result<()>490     fn claimVmInstance(&self, instance_id: &[u8; 64]) -> binder::Result<()> {
491         let state = &mut *self.state.lock().unwrap();
492         if let Some(sk_state) = &mut state.sk_state {
493             let uid = get_calling_uid();
494             info!(
495                 "Claiming a VM's instance_id: {:?}, for uid: {:?}",
496                 hex::encode(instance_id),
497                 uid
498             );
499 
500             let user_id = multiuser_get_user_id(uid);
501             let app_id = multiuser_get_app_id(uid);
502             info!("Recording possible new owner of state for (user_id={user_id}, app_id={app_id})");
503             if let Err(e) = sk_state.add_id(instance_id, user_id, app_id) {
504                 error!("Failed to update the instance_id owner: {e:?}");
505             }
506         } else {
507             info!("ignoring claimVmInstance() as no ISecretkeeper");
508         }
509         Ok(())
510     }
511 
createTapInterface(&self, iface_name_suffix: &str) -> binder::Result<ParcelFileDescriptor>512     fn createTapInterface(&self, iface_name_suffix: &str) -> binder::Result<ParcelFileDescriptor> {
513         check_internet_permission()?;
514         check_use_custom_virtual_machine()?;
515         if !cfg!(network) {
516             return Err(Status::new_exception_str(
517                 ExceptionCode::UNSUPPORTED_OPERATION,
518                 Some("createTapInterface is not supported with the network feature disabled"),
519             ))
520             .with_log();
521         }
522         NETWORK_SERVICE.createTapInterface(iface_name_suffix)
523     }
524 
deleteTapInterface(&self, tap_fd: &ParcelFileDescriptor) -> binder::Result<()>525     fn deleteTapInterface(&self, tap_fd: &ParcelFileDescriptor) -> binder::Result<()> {
526         check_internet_permission()?;
527         check_use_custom_virtual_machine()?;
528         if !cfg!(network) {
529             return Err(Status::new_exception_str(
530                 ExceptionCode::UNSUPPORTED_OPERATION,
531                 Some("deleteTapInterface is not supported with the network feature disabled"),
532             ))
533             .with_log();
534         }
535         NETWORK_SERVICE.deleteTapInterface(tap_fd)
536     }
537 }
538 
539 impl IVirtualizationMaintenance for VirtualizationServiceInternal {
appRemoved(&self, user_id: i32, app_id: i32) -> binder::Result<()>540     fn appRemoved(&self, user_id: i32, app_id: i32) -> binder::Result<()> {
541         let state = &mut *self.state.lock().unwrap();
542         if let Some(sk_state) = &mut state.sk_state {
543             info!("packageRemoved(user_id={user_id}, app_id={app_id})");
544             sk_state.delete_ids_for_app(user_id, app_id).or_service_specific_exception(-1)?;
545         } else {
546             info!("ignoring packageRemoved(user_id={user_id}, app_id={app_id})");
547         }
548         Ok(())
549     }
550 
userRemoved(&self, user_id: i32) -> binder::Result<()>551     fn userRemoved(&self, user_id: i32) -> binder::Result<()> {
552         let state = &mut *self.state.lock().unwrap();
553         if let Some(sk_state) = &mut state.sk_state {
554             info!("userRemoved({user_id})");
555             sk_state.delete_ids_for_user(user_id).or_service_specific_exception(-1)?;
556         } else {
557             info!("ignoring userRemoved(user_id={user_id})");
558         }
559         Ok(())
560     }
561 
performReconciliation( &self, callback: &Strong<dyn IVirtualizationReconciliationCallback>, ) -> binder::Result<()>562     fn performReconciliation(
563         &self,
564         callback: &Strong<dyn IVirtualizationReconciliationCallback>,
565     ) -> binder::Result<()> {
566         let state = &mut *self.state.lock().unwrap();
567         if let Some(sk_state) = &mut state.sk_state {
568             info!("performReconciliation()");
569             sk_state.reconcile(callback).or_service_specific_exception(-1)?;
570         } else {
571             info!("ignoring performReconciliation()");
572         }
573         Ok(())
574     }
575 }
576 
577 #[derive(Debug, Deserialize)]
578 struct Device {
579     dtbo_label: String,
580     sysfs_path: String,
581 }
582 
583 #[derive(Debug, Default, Deserialize)]
584 struct Devices {
585     device: Vec<Device>,
586 }
587 
get_assignable_devices() -> binder::Result<Devices>588 fn get_assignable_devices() -> binder::Result<Devices> {
589     let xml_path = Path::new("/vendor/etc/avf/assignable_devices.xml");
590     if !xml_path.exists() {
591         return Ok(Devices { ..Default::default() });
592     }
593 
594     let xml = fs::read(xml_path)
595         .context("Failed to read assignable_devices.xml")
596         .with_log()
597         .or_service_specific_exception(-1)?;
598 
599     let xml = String::from_utf8(xml)
600         .context("assignable_devices.xml is not a valid UTF-8 file")
601         .with_log()
602         .or_service_specific_exception(-1)?;
603 
604     let mut devices: Devices = serde_xml_rs::from_str(&xml)
605         .context("can't parse assignable_devices.xml")
606         .with_log()
607         .or_service_specific_exception(-1)?;
608 
609     let mut device_set = HashSet::new();
610     devices.device.retain(move |device| {
611         if device_set.contains(&device.sysfs_path) {
612             warn!("duplicated assignable device {device:?}; ignoring...");
613             return false;
614         }
615 
616         if !Path::new(&device.sysfs_path).exists() {
617             warn!("assignable device {device:?} doesn't exist; ignoring...");
618             return false;
619         }
620 
621         device_set.insert(device.sysfs_path.clone());
622         true
623     });
624     Ok(devices)
625 }
626 
split_x509_certificate_chain(mut cert_chain: &[u8]) -> Result<Vec<Certificate>>627 fn split_x509_certificate_chain(mut cert_chain: &[u8]) -> Result<Vec<Certificate>> {
628     let mut out = Vec::new();
629     while !cert_chain.is_empty() {
630         let cert = X509::from_der(cert_chain)?;
631         let end = cert.to_der()?.len();
632         out.push(Certificate { encodedCertificate: cert_chain[..end].to_vec() });
633         cert_chain = &cert_chain[end..];
634     }
635     Ok(out)
636 }
637 
638 #[derive(Debug, Default)]
639 struct GlobalVmInstance {
640     /// The unique CID assigned to the VM for vsock communication.
641     cid: Cid,
642     /// UID of the client who requested this VM instance.
643     requester_uid: uid_t,
644     /// PID of the client who requested this VM instance.
645     requester_debug_pid: pid_t,
646 }
647 
648 impl GlobalVmInstance {
get_temp_dir(&self) -> PathBuf649     fn get_temp_dir(&self) -> PathBuf {
650         let cid = self.cid;
651         format!("{TEMPORARY_DIRECTORY}/{cid}").into()
652     }
653 }
654 
655 /// The mutable state of the VirtualizationServiceInternal. There should only be one instance
656 /// of this struct.
657 struct GlobalState {
658     /// VM contexts currently allocated to running VMs. A CID is never recycled as long
659     /// as there is a strong reference held by a GlobalVmContext.
660     held_contexts: HashMap<Cid, Weak<GlobalVmInstance>>,
661 
662     /// Cached read-only FD of VM DTBO file. Also serves as a lock for creating the file.
663     dtbo_file: Mutex<Option<File>>,
664 
665     /// State relating to secrets held by (optional) Secretkeeper instance on behalf of VMs.
666     sk_state: Option<maintenance::State>,
667 
668     display_service: Option<binder::SpIBinder>,
669 }
670 
671 impl GlobalState {
new() -> Self672     fn new() -> Self {
673         Self {
674             held_contexts: HashMap::new(),
675             dtbo_file: Mutex::new(None),
676             sk_state: maintenance::State::new(),
677             display_service: None,
678         }
679     }
680 
681     /// Get the next available CID, or an error if we have run out. The last CID used is stored in
682     /// a system property so that restart of virtualizationservice doesn't reuse CID while the host
683     /// Android is up.
get_next_available_cid(&mut self) -> Result<Cid>684     fn get_next_available_cid(&mut self) -> Result<Cid> {
685         // Start trying to find a CID from the last used CID + 1. This ensures
686         // that we do not eagerly recycle CIDs. It makes debugging easier but
687         // also means that retrying to allocate a CID, eg. because it is
688         // erroneously occupied by a process, will not recycle the same CID.
689         let last_cid_prop =
690             system_properties::read(SYSPROP_LAST_CID)?.and_then(|val| match val.parse::<Cid>() {
691                 Ok(num) => {
692                     if is_valid_guest_cid(num) {
693                         Some(num)
694                     } else {
695                         error!("Invalid value '{}' of property '{}'", num, SYSPROP_LAST_CID);
696                         None
697                     }
698                 }
699                 Err(_) => {
700                     error!("Invalid value '{}' of property '{}'", val, SYSPROP_LAST_CID);
701                     None
702                 }
703             });
704 
705         let first_cid = if let Some(last_cid) = last_cid_prop {
706             if last_cid == GUEST_CID_MAX {
707                 GUEST_CID_MIN
708             } else {
709                 last_cid + 1
710             }
711         } else {
712             GUEST_CID_MIN
713         };
714 
715         let cid = self
716             .find_available_cid(first_cid..=GUEST_CID_MAX)
717             .or_else(|| self.find_available_cid(GUEST_CID_MIN..first_cid))
718             .ok_or_else(|| anyhow!("Could not find an available CID."))?;
719 
720         system_properties::write(SYSPROP_LAST_CID, &format!("{}", cid))?;
721         Ok(cid)
722     }
723 
find_available_cid<I>(&self, mut range: I) -> Option<Cid> where I: Iterator<Item = Cid>,724     fn find_available_cid<I>(&self, mut range: I) -> Option<Cid>
725     where
726         I: Iterator<Item = Cid>,
727     {
728         range.find(|cid| !self.held_contexts.contains_key(cid))
729     }
730 
allocate_vm_context( &mut self, requester_uid: uid_t, requester_debug_pid: pid_t, ) -> Result<Strong<dyn IGlobalVmContext>>731     fn allocate_vm_context(
732         &mut self,
733         requester_uid: uid_t,
734         requester_debug_pid: pid_t,
735     ) -> Result<Strong<dyn IGlobalVmContext>> {
736         // Garbage collect unused VM contexts.
737         self.held_contexts.retain(|_, instance| instance.strong_count() > 0);
738 
739         let cid = self.get_next_available_cid()?;
740         let instance = Arc::new(GlobalVmInstance { cid, requester_uid, requester_debug_pid });
741         create_temporary_directory(&instance.get_temp_dir(), Some(requester_uid))?;
742 
743         self.held_contexts.insert(cid, Arc::downgrade(&instance));
744         let binder = GlobalVmContext { instance, ..Default::default() };
745         Ok(BnGlobalVmContext::new_binder(binder, BinderFeatures::default()))
746     }
747 
get_dtbo_file(&mut self) -> Result<File>748     fn get_dtbo_file(&mut self) -> Result<File> {
749         let mut file = self.dtbo_file.lock().unwrap();
750 
751         let fd = if let Some(ref_fd) = &*file {
752             ref_fd.try_clone()?
753         } else {
754             let path = get_or_create_common_dir()?.join("vm.dtbo");
755             if path.exists() {
756                 // All temporary files are deleted when the service is started.
757                 // If the file exists but the FD is not cached, the file is
758                 // likely corrupted.
759                 remove_file(&path).context("Failed to clone cached VM DTBO file descriptor")?;
760             }
761 
762             // Open a write-only file descriptor for vfio_handler.
763             let write_fd = File::create(&path).context("Failed to create VM DTBO file")?;
764             VFIO_SERVICE.writeVmDtbo(&ParcelFileDescriptor::new(write_fd))?;
765 
766             // Open read-only. This FD will be cached and returned to clients.
767             let read_fd = File::open(&path).context("Failed to open VM DTBO file")?;
768             let read_fd_clone =
769                 read_fd.try_clone().context("Failed to clone VM DTBO file descriptor")?;
770             *file = Some(read_fd);
771             read_fd_clone
772         };
773 
774         Ok(fd)
775     }
776 }
777 
create_temporary_directory(path: &PathBuf, requester_uid: Option<uid_t>) -> Result<()>778 fn create_temporary_directory(path: &PathBuf, requester_uid: Option<uid_t>) -> Result<()> {
779     // Directory may exist if previous attempt to create it had failed.
780     // Delete it before trying again.
781     if path.as_path().exists() {
782         remove_temporary_dir(path).unwrap_or_else(|e| {
783             warn!("Could not delete temporary directory {:?}: {}", path, e);
784         });
785     }
786     // Create directory.
787     create_dir(path).with_context(|| format!("Could not create temporary directory {:?}", path))?;
788     // If provided, change ownership to client's UID but system's GID, and permissions 0700.
789     // If the chown() fails, this will leave behind an empty directory that will get removed
790     // at the next attempt, or if virtualizationservice is restarted.
791     if let Some(uid) = requester_uid {
792         chown(path, Some(Uid::from_raw(uid)), None).with_context(|| {
793             format!("Could not set ownership of temporary directory {:?}", path)
794         })?;
795     }
796     Ok(())
797 }
798 
799 /// Removes a directory owned by a different user by first changing its owner back
800 /// to VirtualizationService.
remove_temporary_dir(path: &PathBuf) -> Result<()>801 pub fn remove_temporary_dir(path: &PathBuf) -> Result<()> {
802     ensure!(path.as_path().is_dir(), "Path {:?} is not a directory", path);
803     chown(path, Some(Uid::current()), None)?;
804     set_permissions(path, Permissions::from_mode(0o700))?;
805     remove_dir_all(path)?;
806     Ok(())
807 }
808 
get_or_create_common_dir() -> Result<PathBuf>809 fn get_or_create_common_dir() -> Result<PathBuf> {
810     let path = Path::new(TEMPORARY_DIRECTORY).join("common");
811     if !path.exists() {
812         create_temporary_directory(&path, None)?;
813     }
814     Ok(path)
815 }
816 
817 /// Implementation of the AIDL `IGlobalVmContext` interface.
818 #[derive(Debug, Default)]
819 struct GlobalVmContext {
820     /// Strong reference to the context's instance data structure.
821     instance: Arc<GlobalVmInstance>,
822     /// Keeps our service process running as long as this VM context exists.
823     #[allow(dead_code)]
824     lazy_service_guard: LazyServiceGuard,
825 }
826 
827 impl Interface for GlobalVmContext {}
828 
829 impl IGlobalVmContext for GlobalVmContext {
getCid(&self) -> binder::Result<i32>830     fn getCid(&self) -> binder::Result<i32> {
831         Ok(self.instance.cid as i32)
832     }
833 
getTemporaryDirectory(&self) -> binder::Result<String>834     fn getTemporaryDirectory(&self) -> binder::Result<String> {
835         Ok(self.instance.get_temp_dir().to_string_lossy().to_string())
836     }
837 }
838 
handle_stream_connection_tombstoned() -> Result<()>839 fn handle_stream_connection_tombstoned() -> Result<()> {
840     // Should not listen for tombstones on a guest VM's port.
841     assert!(!is_valid_guest_cid(VM_TOMBSTONES_SERVICE_PORT as Cid));
842     let listener =
843         VsockListener::bind_with_cid_port(VMADDR_CID_HOST, VM_TOMBSTONES_SERVICE_PORT as Cid)?;
844     for incoming_stream in listener.incoming() {
845         let mut incoming_stream = match incoming_stream {
846             Err(e) => {
847                 warn!("invalid incoming connection: {:?}", e);
848                 continue;
849             }
850             Ok(s) => s,
851         };
852         std::thread::spawn(move || {
853             if let Err(e) = handle_tombstone(&mut incoming_stream) {
854                 error!("Failed to write tombstone- {:?}", e);
855             }
856         });
857     }
858     Ok(())
859 }
860 
handle_tombstone(stream: &mut VsockStream) -> Result<()>861 fn handle_tombstone(stream: &mut VsockStream) -> Result<()> {
862     if let Ok(addr) = stream.peer_addr() {
863         info!("Vsock Stream connected to cid={} for tombstones", addr.cid());
864     }
865     let tb_connection =
866         TombstonedConnection::connect(std::process::id() as i32, DebuggerdDumpType::Tombstone)
867             .context("Failed to connect to tombstoned")?;
868     let mut text_output = tb_connection
869         .text_output
870         .as_ref()
871         .ok_or_else(|| anyhow!("Could not get file to write the tombstones on"))?;
872     let mut num_bytes_read = 0;
873     loop {
874         let mut chunk_recv = [0; CHUNK_RECV_MAX_LEN];
875         let n = stream
876             .read(&mut chunk_recv)
877             .context("Failed to read tombstone data from Vsock stream")?;
878         if n == 0 {
879             break;
880         }
881         num_bytes_read += n;
882         text_output.write_all(&chunk_recv[0..n]).context("Failed to write guests tombstones")?;
883     }
884     info!("Received {} bytes from guest & wrote to tombstone file", num_bytes_read);
885     tb_connection.notify_completion()?;
886     Ok(())
887 }
888 
889 /// Returns true if the AVF remotely provisioned component service is declared in the
890 /// VINTF manifest.
is_remote_provisioning_hal_declared() -> binder::Result<bool>891 pub(crate) fn is_remote_provisioning_hal_declared() -> binder::Result<bool> {
892     Ok(binder::is_declared(REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME)?)
893 }
894 
895 /// Checks whether the caller has a specific permission
check_permission(perm: &str) -> binder::Result<()>896 fn check_permission(perm: &str) -> binder::Result<()> {
897     let calling_pid = get_calling_pid();
898     let calling_uid = get_calling_uid();
899     // Root can do anything
900     if calling_uid == 0 {
901         return Ok(());
902     }
903     let perm_svc: Strong<dyn IPermissionController::IPermissionController> =
904         binder::wait_for_interface("permission")?;
905     if perm_svc.checkPermission(perm, calling_pid, calling_uid as i32)? {
906         Ok(())
907     } else {
908         Err(anyhow!("does not have the {} permission", perm))
909             .or_binder_exception(ExceptionCode::SECURITY)
910     }
911 }
912 
913 /// Check whether the caller of the current Binder method is allowed to call debug methods.
check_debug_access() -> binder::Result<()>914 fn check_debug_access() -> binder::Result<()> {
915     check_permission("android.permission.DEBUG_VIRTUAL_MACHINE")
916 }
917 
918 /// Check whether the caller of the current Binder method is allowed to manage VMs
check_manage_access() -> binder::Result<()>919 fn check_manage_access() -> binder::Result<()> {
920     check_permission("android.permission.MANAGE_VIRTUAL_MACHINE")
921 }
922 
923 /// Check whether the caller of the current Binder method is allowed to use custom VMs
check_use_custom_virtual_machine() -> binder::Result<()>924 fn check_use_custom_virtual_machine() -> binder::Result<()> {
925     check_permission("android.permission.USE_CUSTOM_VIRTUAL_MACHINE")
926 }
927 
928 /// Check whether the caller of the current Binder method is allowed to create socket and
929 /// establish connection between the VM and the Internet.
check_internet_permission() -> binder::Result<()>930 fn check_internet_permission() -> binder::Result<()> {
931     check_permission("android.permission.INTERNET")
932 }
933 
934 #[cfg(test)]
935 mod tests {
936     use super::*;
937 
938     const TEST_RKP_CERT_CHAIN_PATH: &str = "testdata/rkp_cert_chain.der";
939 
940     #[test]
splitting_x509_certificate_chain_succeeds() -> Result<()>941     fn splitting_x509_certificate_chain_succeeds() -> Result<()> {
942         let bytes = fs::read(TEST_RKP_CERT_CHAIN_PATH)?;
943         let cert_chain = split_x509_certificate_chain(&bytes)?;
944 
945         assert_eq!(4, cert_chain.len());
946         for cert in cert_chain {
947             let x509_cert = X509::from_der(&cert.encodedCertificate)?;
948             assert_eq!(x509_cert.to_der()?.len(), cert.encodedCertificate.len());
949         }
950         Ok(())
951     }
952 }
953