1 /*
2  * Copyright 2024 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 
17 //! A VM payload that exists to allow testing of the Rust wrapper for the VM payload APIs.
18 
19 use anyhow::Result;
20 use com_android_microdroid_testservice::{
21     aidl::com::android::microdroid::testservice::{
22         IAppCallback::IAppCallback,
23         ITestService::{BnTestService, ITestService, PORT},
24     },
25     binder::{BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Status, Strong},
26 };
27 use cstr::cstr;
28 use log::{error, info};
29 use std::panic;
30 use std::process::exit;
31 use std::string::String;
32 use std::vec::Vec;
33 
34 vm_payload::main!(main);
35 
36 // Entry point of the Service VM client.
main()37 fn main() {
38     android_logger::init_once(
39         android_logger::Config::default()
40             .with_tag("microdroid_testlib_rust")
41             .with_max_level(log::LevelFilter::Debug),
42     );
43     // Redirect panic messages to logcat.
44     panic::set_hook(Box::new(|panic_info| {
45         error!("{panic_info}");
46     }));
47     if let Err(e) = try_main() {
48         error!("failed with {:?}", e);
49         exit(1);
50     }
51 }
52 
try_main() -> Result<()>53 fn try_main() -> Result<()> {
54     info!("Welcome to the Rust test binary");
55 
56     vm_payload::run_single_vsock_service(TestService::new_binder(), PORT.try_into()?)
57 }
58 
59 struct TestService {}
60 
61 impl Interface for TestService {}
62 
63 impl TestService {
new_binder() -> Strong<dyn ITestService>64     fn new_binder() -> Strong<dyn ITestService> {
65         BnTestService::new_binder(TestService {}, BinderFeatures::default())
66     }
67 }
68 
69 impl ITestService for TestService {
quit(&self) -> BinderResult<()>70     fn quit(&self) -> BinderResult<()> {
71         exit(0)
72     }
73 
addInteger(&self, a: i32, b: i32) -> BinderResult<i32>74     fn addInteger(&self, a: i32, b: i32) -> BinderResult<i32> {
75         a.checked_add(b).ok_or_else(|| Status::new_exception(ExceptionCode::ILLEGAL_ARGUMENT, None))
76     }
77 
getApkContentsPath(&self) -> BinderResult<String>78     fn getApkContentsPath(&self) -> BinderResult<String> {
79         Ok(vm_payload::apk_contents_path().to_string_lossy().to_string())
80     }
81 
getEncryptedStoragePath(&self) -> BinderResult<String>82     fn getEncryptedStoragePath(&self) -> BinderResult<String> {
83         Ok(vm_payload::encrypted_storage_path()
84             .map(|p| p.to_string_lossy().to_string())
85             .unwrap_or("".to_string()))
86     }
87 
insecurelyExposeVmInstanceSecret(&self) -> BinderResult<Vec<u8>>88     fn insecurelyExposeVmInstanceSecret(&self) -> BinderResult<Vec<u8>> {
89         let mut secret = vec![0u8; 32];
90         vm_payload::get_vm_instance_secret(b"identifier", secret.as_mut_slice());
91         Ok(secret)
92     }
93 
94     // Everything below here is unimplemented. Implementations may be added as needed.
95 
readProperty(&self, _: &str) -> BinderResult<String>96     fn readProperty(&self, _: &str) -> BinderResult<String> {
97         unimplemented()
98     }
insecurelyExposeAttestationCdi(&self) -> BinderResult<Vec<u8>>99     fn insecurelyExposeAttestationCdi(&self) -> BinderResult<Vec<u8>> {
100         unimplemented()
101     }
getBcc(&self) -> BinderResult<Vec<u8>>102     fn getBcc(&self) -> BinderResult<Vec<u8>> {
103         unimplemented()
104     }
runEchoReverseServer(&self) -> BinderResult<()>105     fn runEchoReverseServer(&self) -> BinderResult<()> {
106         unimplemented()
107     }
getEffectiveCapabilities(&self) -> BinderResult<Vec<String>>108     fn getEffectiveCapabilities(&self) -> BinderResult<Vec<String>> {
109         unimplemented()
110     }
getUid(&self) -> BinderResult<i32>111     fn getUid(&self) -> BinderResult<i32> {
112         unimplemented()
113     }
writeToFile(&self, _: &str, _: &str) -> BinderResult<()>114     fn writeToFile(&self, _: &str, _: &str) -> BinderResult<()> {
115         unimplemented()
116     }
readFromFile(&self, _: &str) -> BinderResult<String>117     fn readFromFile(&self, _: &str) -> BinderResult<String> {
118         unimplemented()
119     }
getFilePermissions(&self, _: &str) -> BinderResult<i32>120     fn getFilePermissions(&self, _: &str) -> BinderResult<i32> {
121         unimplemented()
122     }
getMountFlags(&self, _: &str) -> BinderResult<i32>123     fn getMountFlags(&self, _: &str) -> BinderResult<i32> {
124         unimplemented()
125     }
getPageSize(&self) -> BinderResult<i32>126     fn getPageSize(&self) -> BinderResult<i32> {
127         unimplemented()
128     }
requestCallback(&self, _: &Strong<dyn IAppCallback + 'static>) -> BinderResult<()>129     fn requestCallback(&self, _: &Strong<dyn IAppCallback + 'static>) -> BinderResult<()> {
130         unimplemented()
131     }
readLineFromConsole(&self) -> BinderResult<String>132     fn readLineFromConsole(&self) -> BinderResult<String> {
133         unimplemented()
134     }
135 }
136 
unimplemented<T>() -> BinderResult<T>137 fn unimplemented<T>() -> BinderResult<T> {
138     let message = cstr!("Got a call to an unimplemented ITestService method in testbinary.rs");
139     error!("{message:?}");
140     Err(Status::new_exception(ExceptionCode::UNSUPPORTED_OPERATION, Some(message)))
141 }
142