blob: 48942dc2b3192930d75b8f99ed50bcad1c76c42c [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>
Alan Stokesd4ea5a82022-11-10 12:17:42 +000031#include <vm_payload_restricted.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090032
Inseob Kim691df6a2022-01-20 12:54:30 +090033#include <string>
Jiyong Parka7266ac2021-05-17 21:57:24 +090034
Inseob Kim06a64d62021-09-07 21:21:45 +090035using android::base::ErrnoError;
Andrew Scull11cf0902021-06-22 12:08:10 +000036using android::base::Error;
37using android::base::Result;
Andrew Scull66616612021-06-17 16:41:03 +000038
Jiyong Parkfe5b28e2021-06-24 00:19:02 +090039extern void testlib_sub();
40
Andrew Scull66616612021-06-17 16:41:03 +000041namespace {
42
Andrew Scull11cf0902021-06-22 12:08:10 +000043template <typename T>
Andrew Sculledbe75e2021-07-06 10:44:31 +000044Result<T> report_test(std::string name, Result<T> result) {
Andrew Scull11cf0902021-06-22 12:08:10 +000045 auto property = "debug.microdroid.test." + name;
46 std::stringstream outcome;
47 if (result.ok()) {
48 outcome << "PASS";
49 } else {
50 outcome << "FAIL: " << result.error();
Inseob Kimdb319702022-01-20 13:12:43 +090051 // Pollute stderr with the error in case the property is truncated.
52 std::cerr << "[" << name << "] test failed: " << result.error() << "\n";
Andrew Scull11cf0902021-06-22 12:08:10 +000053 }
54 __system_property_set(property.c_str(), outcome.str().c_str());
Andrew Sculledbe75e2021-07-06 10:44:31 +000055 return result;
Andrew Scull66616612021-06-17 16:41:03 +000056}
57
Inseob Kim06a64d62021-09-07 21:21:45 +090058Result<void> start_test_service() {
59 class TestService : public aidl::com::android::microdroid::testservice::BnTestService {
60 ndk::ScopedAStatus addInteger(int32_t a, int32_t b, int32_t* out) override {
61 *out = a + b;
62 return ndk::ScopedAStatus::ok();
63 }
Inseob Kim691df6a2022-01-20 12:54:30 +090064
65 ndk::ScopedAStatus readProperty(const std::string& prop, std::string* out) override {
66 *out = android::base::GetProperty(prop, "");
67 if (out->empty()) {
68 std::string msg = "cannot find property " + prop;
69 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC,
70 msg.c_str());
71 }
72
73 return ndk::ScopedAStatus::ok();
74 }
Andrew Scull2e6ab792022-01-30 16:04:08 +000075
Andrew Scull102067a2022-10-07 00:34:40 +000076 ndk::ScopedAStatus insecurelyExposeVmInstanceSecret(std::vector<uint8_t>* out) override {
77 const uint8_t identifier[] = {1, 2, 3, 4};
Andrew Scull655e98e2022-10-10 22:24:58 +000078 out->resize(32);
79 if (!AVmPayload_getVmInstanceSecret(identifier, sizeof(identifier), out->data(),
80 out->size())) {
Andrew Scull2e6ab792022-01-30 16:04:08 +000081 return ndk::ScopedAStatus::
Alan Stokesd4ea5a82022-11-10 12:17:42 +000082 fromServiceSpecificErrorWithMessage(0, "Failed to get VM instance secret");
Andrew Scull2e6ab792022-01-30 16:04:08 +000083 }
Andrew Scull2e6ab792022-01-30 16:04:08 +000084 return ndk::ScopedAStatus::ok();
85 }
Andrew Scull1f6ca352022-02-20 22:51:12 +000086
87 ndk::ScopedAStatus insecurelyExposeAttestationCdi(std::vector<uint8_t>* out) override {
Andrew Scull655e98e2022-10-10 22:24:58 +000088 size_t cdi_size;
89 if (!AVmPayload_getDiceAttestationCdi(nullptr, 0, &cdi_size)) {
90 return ndk::ScopedAStatus::
91 fromServiceSpecificErrorWithMessage(0, "Failed to measure attestation cdi");
92 }
93 out->resize(cdi_size);
94 if (!AVmPayload_getDiceAttestationCdi(out->data(), out->size(), &cdi_size)) {
Andrew Scull1f6ca352022-02-20 22:51:12 +000095 return ndk::ScopedAStatus::
Andrew Sculle4b02852022-10-06 18:53:56 +000096 fromServiceSpecificErrorWithMessage(0, "Failed to get attestation cdi");
Andrew Scull1f6ca352022-02-20 22:51:12 +000097 }
Andrew Scull1f6ca352022-02-20 22:51:12 +000098 return ndk::ScopedAStatus::ok();
99 }
Andrew Scull61892082022-02-21 00:07:25 +0000100
101 ndk::ScopedAStatus getBcc(std::vector<uint8_t>* out) override {
Andrew Scull655e98e2022-10-10 22:24:58 +0000102 size_t bcc_size;
103 if (!AVmPayload_getDiceAttestationChain(nullptr, 0, &bcc_size)) {
104 return ndk::ScopedAStatus::
105 fromServiceSpecificErrorWithMessage(0,
106 "Failed to measure attestation chain");
107 }
108 out->resize(bcc_size);
109 if (!AVmPayload_getDiceAttestationChain(out->data(), out->size(), &bcc_size)) {
Andrew Scull61892082022-02-21 00:07:25 +0000110 return ndk::ScopedAStatus::
Andrew Sculle4b02852022-10-06 18:53:56 +0000111 fromServiceSpecificErrorWithMessage(0, "Failed to get attestation chain");
Andrew Scull61892082022-02-21 00:07:25 +0000112 }
Andrew Scull61892082022-02-21 00:07:25 +0000113 return ndk::ScopedAStatus::ok();
114 }
Alice Wang6bbb6da2022-10-26 12:44:06 +0000115
116 ndk::ScopedAStatus getApkContentsPath(std::string* out) override {
117 const char* path_c = AVmPayload_getApkContentsPath();
118 if (path_c == nullptr) {
119 return ndk::ScopedAStatus::
120 fromServiceSpecificErrorWithMessage(0, "Failed to get APK contents path");
121 }
122 std::string path(path_c);
123 *out = path;
124 return ndk::ScopedAStatus::ok();
125 }
Inseob Kim06a64d62021-09-07 21:21:45 +0900126 };
127 auto testService = ndk::SharedRefBase::make<TestService>();
128
129 auto callback = []([[maybe_unused]] void* param) {
Andrew Scull655e98e2022-10-10 22:24:58 +0000130 if (!AVmPayload_notifyPayloadReady()) {
Alice Wangfb46ee12022-09-30 13:08:52 +0000131 std::cerr << "failed to notify payload ready to virtualizationservice" << std::endl;
Alan Stokesb62de262022-05-12 17:11:53 +0100132 abort();
Inseob Kim06a64d62021-09-07 21:21:45 +0900133 }
134 };
Alice Wang2be64f32022-10-13 14:37:35 +0000135 if (!AVmPayload_runVsockRpcServer(testService->asBinder().get(), testService->SERVICE_PORT,
136 callback, nullptr)) {
Inseob Kim06a64d62021-09-07 21:21:45 +0900137 return Error() << "RPC Server failed to run";
138 }
139
140 return {};
141}
142
Inseob Kimdb319702022-01-20 13:12:43 +0900143Result<void> verify_apk() {
144 const char* path = "/mnt/extra-apk/0/assets/build_manifest.pb";
145
146 std::string str;
147 if (!android::base::ReadFileToString(path, &str)) {
148 return ErrnoError() << "failed to read build_manifest.pb";
149 }
150
151 if (!android::security::fsverity::FSVerityDigests().ParseFromString(str)) {
152 return Error() << "invalid build_manifest.pb";
153 }
154
155 return {};
156}
157
Andrew Scull66616612021-06-17 16:41:03 +0000158} // Anonymous namespace
159
Alan Stokes52d3c722022-10-04 17:27:13 +0100160extern "C" int AVmPayload_main() {
Inseob Kim06a64d62021-09-07 21:21:45 +0900161 // disable buffering to communicate seamlessly
162 setvbuf(stdin, nullptr, _IONBF, 0);
163 setvbuf(stdout, nullptr, _IONBF, 0);
164 setvbuf(stderr, nullptr, _IONBF, 0);
165
Alan Stokes52d3c722022-10-04 17:27:13 +0100166 printf("Hello Microdroid");
Jiyong Parkfe5b28e2021-06-24 00:19:02 +0900167 testlib_sub();
Jiyong Park40699612021-05-24 16:55:06 +0900168 printf("\n");
Jiyong Park23934392021-06-16 01:59:10 +0900169
Inseob Kimdb319702022-01-20 13:12:43 +0900170 // Extra apks may be missing; this is not a fatal error
171 report_test("extra_apk", verify_apk());
172
Jiyong Park23934392021-06-16 01:59:10 +0900173 __system_property_set("debug.microdroid.app.run", "true");
Andrew Sculledbe75e2021-07-06 10:44:31 +0000174
Inseob Kim06a64d62021-09-07 21:21:45 +0900175 if (auto res = start_test_service(); res.ok()) {
176 return 0;
177 } else {
Alan Stokesb62de262022-05-12 17:11:53 +0100178 std::cerr << "starting service failed: " << res.error() << "\n";
Inseob Kim06a64d62021-09-07 21:21:45 +0900179 return 1;
180 }
Jiyong Parka7266ac2021-05-17 21:57:24 +0900181}