blob: c0a8c0e0c84e1fafaeff2ddb0f8b5b071b6742c4 [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);
Alan Stokes65bbb912022-11-23 09:39:34 +000079 AVmPayload_getVmInstanceSecret(identifier, sizeof(identifier), out->data(),
80 out->size());
Andrew Scull2e6ab792022-01-30 16:04:08 +000081 return ndk::ScopedAStatus::ok();
82 }
Andrew Scull1f6ca352022-02-20 22:51:12 +000083
84 ndk::ScopedAStatus insecurelyExposeAttestationCdi(std::vector<uint8_t>* out) override {
Alan Stokes65bbb912022-11-23 09:39:34 +000085 size_t cdi_size = AVmPayload_getDiceAttestationCdi(nullptr, 0);
Andrew Scull655e98e2022-10-10 22:24:58 +000086 out->resize(cdi_size);
Alan Stokes65bbb912022-11-23 09:39:34 +000087 AVmPayload_getDiceAttestationCdi(out->data(), out->size());
Andrew Scull1f6ca352022-02-20 22:51:12 +000088 return ndk::ScopedAStatus::ok();
89 }
Andrew Scull61892082022-02-21 00:07:25 +000090
91 ndk::ScopedAStatus getBcc(std::vector<uint8_t>* out) override {
Alan Stokes65bbb912022-11-23 09:39:34 +000092 size_t bcc_size = AVmPayload_getDiceAttestationChain(nullptr, 0);
Andrew Scull655e98e2022-10-10 22:24:58 +000093 out->resize(bcc_size);
Alan Stokes65bbb912022-11-23 09:39:34 +000094 AVmPayload_getDiceAttestationChain(out->data(), out->size());
Andrew Scull61892082022-02-21 00:07:25 +000095 return ndk::ScopedAStatus::ok();
96 }
Alice Wang6bbb6da2022-10-26 12:44:06 +000097
98 ndk::ScopedAStatus getApkContentsPath(std::string* out) override {
99 const char* path_c = AVmPayload_getApkContentsPath();
100 if (path_c == nullptr) {
101 return ndk::ScopedAStatus::
102 fromServiceSpecificErrorWithMessage(0, "Failed to get APK contents path");
103 }
104 std::string path(path_c);
105 *out = path;
106 return ndk::ScopedAStatus::ok();
107 }
Alan Stokes78d24702022-11-21 15:28:31 +0000108
109 ndk::ScopedAStatus getEncryptedStoragePath(std::string* out) override {
110 const char* path_c = AVmPayload_getEncryptedStoragePath();
111 if (path_c == nullptr) {
112 out->clear();
113 } else {
114 *out = path_c;
115 }
116 return ndk::ScopedAStatus::ok();
117 }
Inseob Kim06a64d62021-09-07 21:21:45 +0900118 };
119 auto testService = ndk::SharedRefBase::make<TestService>();
120
Alan Stokes65bbb912022-11-23 09:39:34 +0000121 auto callback = []([[maybe_unused]] void* param) { AVmPayload_notifyPayloadReady(); };
Alan Stokese0945ad2022-11-24 13:29:57 +0000122 AVmPayload_runVsockRpcServer(testService->asBinder().get(), testService->SERVICE_PORT, callback,
123 nullptr);
Inseob Kim06a64d62021-09-07 21:21:45 +0900124
125 return {};
126}
127
Inseob Kimdb319702022-01-20 13:12:43 +0900128Result<void> verify_apk() {
129 const char* path = "/mnt/extra-apk/0/assets/build_manifest.pb";
130
131 std::string str;
132 if (!android::base::ReadFileToString(path, &str)) {
133 return ErrnoError() << "failed to read build_manifest.pb";
134 }
135
136 if (!android::security::fsverity::FSVerityDigests().ParseFromString(str)) {
137 return Error() << "invalid build_manifest.pb";
138 }
139
140 return {};
141}
142
Andrew Scull66616612021-06-17 16:41:03 +0000143} // Anonymous namespace
144
Alan Stokes52d3c722022-10-04 17:27:13 +0100145extern "C" int AVmPayload_main() {
Inseob Kim06a64d62021-09-07 21:21:45 +0900146 // disable buffering to communicate seamlessly
147 setvbuf(stdin, nullptr, _IONBF, 0);
148 setvbuf(stdout, nullptr, _IONBF, 0);
149 setvbuf(stderr, nullptr, _IONBF, 0);
150
Alan Stokes52d3c722022-10-04 17:27:13 +0100151 printf("Hello Microdroid");
Jiyong Parkfe5b28e2021-06-24 00:19:02 +0900152 testlib_sub();
Jiyong Park40699612021-05-24 16:55:06 +0900153 printf("\n");
Jiyong Park23934392021-06-16 01:59:10 +0900154
Inseob Kimdb319702022-01-20 13:12:43 +0900155 // Extra apks may be missing; this is not a fatal error
156 report_test("extra_apk", verify_apk());
157
Jiyong Park23934392021-06-16 01:59:10 +0900158 __system_property_set("debug.microdroid.app.run", "true");
Andrew Sculledbe75e2021-07-06 10:44:31 +0000159
Inseob Kim06a64d62021-09-07 21:21:45 +0900160 if (auto res = start_test_service(); res.ok()) {
161 return 0;
162 } else {
Alan Stokesb62de262022-05-12 17:11:53 +0100163 std::cerr << "starting service failed: " << res.error() << "\n";
Inseob Kim06a64d62021-09-07 21:21:45 +0900164 return 1;
165 }
Jiyong Parka7266ac2021-05-17 21:57:24 +0900166}