blob: d810e3c9d20bcb86e0de25f83f186c8bcf11e87f [file] [log] [blame]
Jiyong Parka7266ac2021-05-17 21:57:24 +09001/*
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 */
Inseob Kim06a64d62021-09-07 21:21:45 +090016#include <aidl/com/android/microdroid/testservice/BnTestService.h>
Inseob Kimdb319702022-01-20 13:12:43 +090017#include <android-base/file.h>
Inseob Kim691df6a2022-01-20 12:54:30 +090018#include <android-base/properties.h>
Andrew Scull11cf0902021-06-22 12:08:10 +000019#include <android-base/result.h>
Andrew Scull66616612021-06-17 16:41:03 +000020#include <android/binder_auto_utils.h>
21#include <android/binder_manager.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090022#include <fcntl.h>
Inseob Kimdb319702022-01-20 13:12:43 +090023#include <fsverity_digests.pb.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090024#include <linux/vm_sockets.h>
25#include <stdint.h>
Jiyong Parka7266ac2021-05-17 21:57:24 +090026#include <stdio.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090027#include <sys/ioctl.h>
Jiyong Park23934392021-06-16 01:59:10 +090028#include <sys/system_properties.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090029#include <unistd.h>
Alan Stokes52d3c722022-10-04 17:27:13 +010030#include <vm_main.h>
Andrew Sculle4b02852022-10-06 18:53:56 +000031#include <vm_payload.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090032
33#include <binder_rpc_unstable.hpp>
Inseob Kim691df6a2022-01-20 12:54:30 +090034#include <string>
Jiyong Parka7266ac2021-05-17 21:57:24 +090035
Inseob Kim06a64d62021-09-07 21:21:45 +090036using android::base::ErrnoError;
Andrew Scull11cf0902021-06-22 12:08:10 +000037using android::base::Error;
38using android::base::Result;
Andrew Scull66616612021-06-17 16:41:03 +000039
Jiyong Parkfe5b28e2021-06-24 00:19:02 +090040extern void testlib_sub();
41
Andrew Scull66616612021-06-17 16:41:03 +000042namespace {
43
Andrew Scull11cf0902021-06-22 12:08:10 +000044template <typename T>
Andrew Sculledbe75e2021-07-06 10:44:31 +000045Result<T> report_test(std::string name, Result<T> result) {
Andrew Scull11cf0902021-06-22 12:08:10 +000046 auto property = "debug.microdroid.test." + name;
47 std::stringstream outcome;
48 if (result.ok()) {
49 outcome << "PASS";
50 } else {
51 outcome << "FAIL: " << result.error();
Inseob Kimdb319702022-01-20 13:12:43 +090052 // Pollute stderr with the error in case the property is truncated.
53 std::cerr << "[" << name << "] test failed: " << result.error() << "\n";
Andrew Scull11cf0902021-06-22 12:08:10 +000054 }
55 __system_property_set(property.c_str(), outcome.str().c_str());
Andrew Sculledbe75e2021-07-06 10:44:31 +000056 return result;
Andrew Scull66616612021-06-17 16:41:03 +000057}
58
Inseob Kim06a64d62021-09-07 21:21:45 +090059Result<void> start_test_service() {
60 class TestService : public aidl::com::android::microdroid::testservice::BnTestService {
61 ndk::ScopedAStatus addInteger(int32_t a, int32_t b, int32_t* out) override {
62 *out = a + b;
63 return ndk::ScopedAStatus::ok();
64 }
Inseob Kim691df6a2022-01-20 12:54:30 +090065
66 ndk::ScopedAStatus readProperty(const std::string& prop, std::string* out) override {
67 *out = android::base::GetProperty(prop, "");
68 if (out->empty()) {
69 std::string msg = "cannot find property " + prop;
70 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC,
71 msg.c_str());
72 }
73
74 return ndk::ScopedAStatus::ok();
75 }
Andrew Scull2e6ab792022-01-30 16:04:08 +000076
Andrew Scull102067a2022-10-07 00:34:40 +000077 ndk::ScopedAStatus insecurelyExposeVmInstanceSecret(std::vector<uint8_t>* out) override {
78 const uint8_t identifier[] = {1, 2, 3, 4};
Andrew Scull655e98e2022-10-10 22:24:58 +000079 out->resize(32);
80 if (!AVmPayload_getVmInstanceSecret(identifier, sizeof(identifier), out->data(),
81 out->size())) {
Andrew Scull2e6ab792022-01-30 16:04:08 +000082 return ndk::ScopedAStatus::
Andrew Scull102067a2022-10-07 00:34:40 +000083 fromServiceSpecificErrorWithMessage(0, "Failed to VM instance secret");
Andrew Scull2e6ab792022-01-30 16:04:08 +000084 }
Andrew Scull2e6ab792022-01-30 16:04:08 +000085 return ndk::ScopedAStatus::ok();
86 }
Andrew Scull1f6ca352022-02-20 22:51:12 +000087
88 ndk::ScopedAStatus insecurelyExposeAttestationCdi(std::vector<uint8_t>* out) override {
Andrew Scull655e98e2022-10-10 22:24:58 +000089 size_t cdi_size;
90 if (!AVmPayload_getDiceAttestationCdi(nullptr, 0, &cdi_size)) {
91 return ndk::ScopedAStatus::
92 fromServiceSpecificErrorWithMessage(0, "Failed to measure attestation cdi");
93 }
94 out->resize(cdi_size);
95 if (!AVmPayload_getDiceAttestationCdi(out->data(), out->size(), &cdi_size)) {
Andrew Scull1f6ca352022-02-20 22:51:12 +000096 return ndk::ScopedAStatus::
Andrew Sculle4b02852022-10-06 18:53:56 +000097 fromServiceSpecificErrorWithMessage(0, "Failed to get attestation cdi");
Andrew Scull1f6ca352022-02-20 22:51:12 +000098 }
Andrew Scull1f6ca352022-02-20 22:51:12 +000099 return ndk::ScopedAStatus::ok();
100 }
Andrew Scull61892082022-02-21 00:07:25 +0000101
102 ndk::ScopedAStatus getBcc(std::vector<uint8_t>* out) override {
Andrew Scull655e98e2022-10-10 22:24:58 +0000103 size_t bcc_size;
104 if (!AVmPayload_getDiceAttestationChain(nullptr, 0, &bcc_size)) {
105 return ndk::ScopedAStatus::
106 fromServiceSpecificErrorWithMessage(0,
107 "Failed to measure attestation chain");
108 }
109 out->resize(bcc_size);
110 if (!AVmPayload_getDiceAttestationChain(out->data(), out->size(), &bcc_size)) {
Andrew Scull61892082022-02-21 00:07:25 +0000111 return ndk::ScopedAStatus::
Andrew Sculle4b02852022-10-06 18:53:56 +0000112 fromServiceSpecificErrorWithMessage(0, "Failed to get attestation chain");
Andrew Scull61892082022-02-21 00:07:25 +0000113 }
Andrew Scull61892082022-02-21 00:07:25 +0000114 return ndk::ScopedAStatus::ok();
115 }
Inseob Kim06a64d62021-09-07 21:21:45 +0900116 };
117 auto testService = ndk::SharedRefBase::make<TestService>();
118
119 auto callback = []([[maybe_unused]] void* param) {
Andrew Scull655e98e2022-10-10 22:24:58 +0000120 if (!AVmPayload_notifyPayloadReady()) {
Alice Wangfb46ee12022-09-30 13:08:52 +0000121 std::cerr << "failed to notify payload ready to virtualizationservice" << std::endl;
Alan Stokesb62de262022-05-12 17:11:53 +0100122 abort();
Inseob Kim06a64d62021-09-07 21:21:45 +0900123 }
124 };
Inseob Kim06a64d62021-09-07 21:21:45 +0900125 if (!RunRpcServerCallback(testService->asBinder().get(), testService->SERVICE_PORT, callback,
126 nullptr)) {
127 return Error() << "RPC Server failed to run";
128 }
129
130 return {};
131}
132
Inseob Kimdb319702022-01-20 13:12:43 +0900133Result<void> verify_apk() {
134 const char* path = "/mnt/extra-apk/0/assets/build_manifest.pb";
135
136 std::string str;
137 if (!android::base::ReadFileToString(path, &str)) {
138 return ErrnoError() << "failed to read build_manifest.pb";
139 }
140
141 if (!android::security::fsverity::FSVerityDigests().ParseFromString(str)) {
142 return Error() << "invalid build_manifest.pb";
143 }
144
145 return {};
146}
147
Andrew Scull66616612021-06-17 16:41:03 +0000148} // Anonymous namespace
149
Alan Stokes52d3c722022-10-04 17:27:13 +0100150extern "C" int AVmPayload_main() {
Inseob Kim06a64d62021-09-07 21:21:45 +0900151 // disable buffering to communicate seamlessly
152 setvbuf(stdin, nullptr, _IONBF, 0);
153 setvbuf(stdout, nullptr, _IONBF, 0);
154 setvbuf(stderr, nullptr, _IONBF, 0);
155
Alan Stokes52d3c722022-10-04 17:27:13 +0100156 printf("Hello Microdroid");
Jiyong Parkfe5b28e2021-06-24 00:19:02 +0900157 testlib_sub();
Jiyong Park40699612021-05-24 16:55:06 +0900158 printf("\n");
Jiyong Park23934392021-06-16 01:59:10 +0900159
Inseob Kimdb319702022-01-20 13:12:43 +0900160 // Extra apks may be missing; this is not a fatal error
161 report_test("extra_apk", verify_apk());
162
Jiyong Park23934392021-06-16 01:59:10 +0900163 __system_property_set("debug.microdroid.app.run", "true");
Andrew Sculledbe75e2021-07-06 10:44:31 +0000164
Inseob Kim06a64d62021-09-07 21:21:45 +0900165 if (auto res = start_test_service(); res.ok()) {
166 return 0;
167 } else {
Alan Stokesb62de262022-05-12 17:11:53 +0100168 std::cerr << "starting service failed: " << res.error() << "\n";
Inseob Kim06a64d62021-09-07 21:21:45 +0900169 return 1;
170 }
Jiyong Parka7266ac2021-05-17 21:57:24 +0900171}