Merge "init: fix debuggable paths for recovery mode"
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index 8e8a91c..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,16 +0,0 @@
-Copyright (C) 2017 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--------------------------------------------------------------------
-
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index a52f719..04e1e4e 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -391,7 +391,7 @@
// There appears to be a bug in the kernel where our death causes SIGHUP to
// be sent to our process group if we exit while it has stopped jobs (e.g.
- // because of wait_for_gdb). Use setsid to create a new process group to
+ // because of wait_for_debugger). Use setsid to create a new process group to
// avoid hitting this.
setsid();
@@ -548,15 +548,17 @@
fork_exit_write.reset();
// Defer the message until later, for readability.
- bool wait_for_gdb = android::base::GetBoolProperty("debug.debuggerd.wait_for_gdb", false);
+ bool wait_for_debugger = android::base::GetBoolProperty(
+ "debug.debuggerd.wait_for_debugger",
+ android::base::GetBoolProperty("debug.debuggerd.wait_for_gdb", false));
if (siginfo.si_signo == BIONIC_SIGNAL_DEBUGGER) {
- wait_for_gdb = false;
+ wait_for_debugger = false;
}
// Detach from all of our attached threads before resuming.
for (const auto& [tid, thread] : thread_info) {
int resume_signal = thread.signo == BIONIC_SIGNAL_DEBUGGER ? 0 : thread.signo;
- if (wait_for_gdb) {
+ if (wait_for_debugger) {
resume_signal = 0;
if (tgkill(target_process, tid, SIGSTOP) != 0) {
PLOG(WARNING) << "failed to send SIGSTOP to " << tid;
@@ -641,12 +643,12 @@
}
}
- if (wait_for_gdb) {
+ if (wait_for_debugger) {
// Use ALOGI to line up with output from engrave_tombstone.
ALOGI(
"***********************************************************\n"
"* Process %d has been suspended while crashing.\n"
- "* To attach gdbserver and start gdb, run this on the host:\n"
+ "* To attach the debugger, run this on the host:\n"
"*\n"
"* gdbclient.py -p %d\n"
"*\n"
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index ab95768..de37a5b 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -69,7 +69,7 @@
#define ARCH_SUFFIX ""
#endif
-constexpr char kWaitForGdbKey[] = "debug.debuggerd.wait_for_gdb";
+constexpr char kWaitForDebuggerKey[] = "debug.debuggerd.wait_for_debugger";
#define TIMEOUT(seconds, expr) \
[&]() { \
@@ -157,7 +157,7 @@
class CrasherTest : public ::testing::Test {
public:
pid_t crasher_pid = -1;
- bool previous_wait_for_gdb;
+ bool previous_wait_for_debugger;
unique_fd crasher_pipe;
unique_fd intercept_fd;
@@ -178,8 +178,13 @@
};
CrasherTest::CrasherTest() {
- previous_wait_for_gdb = android::base::GetBoolProperty(kWaitForGdbKey, false);
- android::base::SetProperty(kWaitForGdbKey, "0");
+ previous_wait_for_debugger = android::base::GetBoolProperty(kWaitForDebuggerKey, false);
+ android::base::SetProperty(kWaitForDebuggerKey, "0");
+
+ // Clear the old property too, just in case someone's been using it
+ // on this device. (We only document the new name, but we still support
+ // the old name so we don't break anyone's existing setups.)
+ android::base::SetProperty("debug.debuggerd.wait_for_gdb", "0");
}
CrasherTest::~CrasherTest() {
@@ -189,7 +194,7 @@
TEMP_FAILURE_RETRY(waitpid(crasher_pid, &status, WUNTRACED));
}
- android::base::SetProperty(kWaitForGdbKey, previous_wait_for_gdb ? "1" : "0");
+ android::base::SetProperty(kWaitForDebuggerKey, previous_wait_for_debugger ? "1" : "0");
}
void CrasherTest::StartIntercept(unique_fd* output_fd, DebuggerdDumpType intercept_type) {
@@ -734,9 +739,9 @@
AssertDeath(SIGABRT);
}
-TEST_F(CrasherTest, wait_for_gdb) {
- if (!android::base::SetProperty(kWaitForGdbKey, "1")) {
- FAIL() << "failed to enable wait_for_gdb";
+TEST_F(CrasherTest, wait_for_debugger) {
+ if (!android::base::SetProperty(kWaitForDebuggerKey, "1")) {
+ FAIL() << "failed to enable wait_for_debugger";
}
sleep(1);
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index ca809e4..b607397 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -274,7 +274,7 @@
// There appears to be a bug in the kernel where our death causes SIGHUP to
// be sent to our process group if we exit while it has stopped jobs (e.g.
- // because of wait_for_gdb). Use setsid to create a new process group to
+ // because of wait_for_debugger). Use setsid to create a new process group to
// avoid hitting this.
setsid();
@@ -600,7 +600,7 @@
// starting to dump right before our death.
pthread_mutex_unlock(&crash_mutex);
} else {
- // Resend the signal, so that either gdb or the parent's waitpid sees it.
+ // Resend the signal, so that either the debugger or the parent's waitpid sees it.
resend_signal(info);
}
}
diff --git a/libstats/pull_lazy/Android.bp b/libstats/pull_lazy/Android.bp
index b1d098b..65dce26 100644
--- a/libstats/pull_lazy/Android.bp
+++ b/libstats/pull_lazy/Android.bp
@@ -1,6 +1,10 @@
// Lazy loading version of libstatspull that can be used by code
// that is running before the statsd APEX is mounted and
// libstatspull.so is available.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libstatspull_lazy",
header_libs: [
@@ -41,4 +45,4 @@
suffix: "32",
},
},
-}
\ No newline at end of file
+}
diff --git a/libstats/socket_lazy/Android.bp b/libstats/socket_lazy/Android.bp
index ad6b4e0..b2cd7b2 100644
--- a/libstats/socket_lazy/Android.bp
+++ b/libstats/socket_lazy/Android.bp
@@ -1,6 +1,10 @@
// Lazy loading version of libstatssocket that can be used by code
// that is running before the statsd APEX is mounted and
// libstatssocket.so is available.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libstatssocket_lazy",
header_libs: [
@@ -37,4 +41,4 @@
suffix: "32",
},
},
-}
\ No newline at end of file
+}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 6b8868b..11b3da7 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -884,12 +884,9 @@
wait_for_prop apexd.status activated
perform_apex_config
- # Define and export *CLASSPATH variables
- mkdir /data/system/environ 0700 system system
- # Must start before 'odsign', as odsign depends on *CLASSPATH variables
- exec_start derive_classpath
- load_exports /data/system/environ/classpath
- rm /data/system/environ/classpath
+ # Export *CLASSPATH variables from /etc/classpath
+ # TODO(b/180105615): export from the generated file instead.
+ load_exports /etc/classpath
# Special-case /data/media/obb per b/64566063
mkdir /data/media 0770 media_rw media_rw encryption=None
@@ -905,7 +902,6 @@
# Start the on-device signing daemon, and wait for it to finish, to ensure
# ART artifacts are generated if needed.
- # Must start after 'derive_classpath' to have *CLASSPATH variables set.
exec_start odsign
# After apexes are mounted, tell keymaster early boot has ended, so it will
diff --git a/trusty/utils/acvp/Android.bp b/trusty/utils/acvp/Android.bp
new file mode 100644
index 0000000..b851e39
--- /dev/null
+++ b/trusty/utils/acvp/Android.bp
@@ -0,0 +1,40 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at //
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+ name: "trusty_acvp_modulewrapper",
+ vendor: true,
+
+ srcs: [
+ "trusty_modulewrapper.cpp",
+ ],
+ static_libs: [
+ "libacvp_modulewrapper",
+ ],
+ shared_libs: [
+ "libbase",
+ "libc",
+ "libdmabufheap",
+ "liblog",
+ "libtrusty",
+ "libssl",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+}
diff --git a/trusty/utils/acvp/acvp_ipc.h b/trusty/utils/acvp/acvp_ipc.h
new file mode 100644
index 0000000..8b48ae3
--- /dev/null
+++ b/trusty/utils/acvp/acvp_ipc.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ACVP_PORT "com.android.trusty.acvp"
+
+/*
+ * Maximum number of arguments
+ */
+#define ACVP_MAX_NUM_ARGUMENTS 8
+
+/*
+ * Maximum length of an algorithm name
+ */
+#define ACVP_MAX_NAME_LENGTH 30
+
+/*
+ * Maximum length of an ACVP request message
+ */
+#define ACVP_MAX_MESSAGE_LENGTH sizeof(struct acvp_req)
+
+/*
+ * Minimum length of the shared memory buffer
+ *
+ * This must be at least as long as the longest reply from the ACVP service
+ * (currently the reply from getConfig()).
+ */
+#define ACVP_MIN_SHARED_MEMORY 16384
+
+/**
+ * acvp_req - Request for the Trusty ACVP app
+ * @num_args: Number of acvp_arg structures following this struct
+ * @buffer_size: Total size of shared memory buffer
+ * @lengths: Length of each argument in the shared memory buffer
+ *
+ * @num_args copies of the acvp_arg struct follow this structure.
+ */
+struct acvp_req {
+ uint32_t num_args;
+ uint32_t buffer_size;
+ uint32_t lengths[ACVP_MAX_NUM_ARGUMENTS];
+};
+
+/**
+ * acvp_resp - Response to a ACVP request
+ *
+ * @num_spans: Number of response sections
+ * @lengths: Length of each response section
+ */
+struct acvp_resp {
+ uint32_t num_spans;
+ uint32_t lengths[ACVP_MAX_NUM_ARGUMENTS];
+};
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/trusty/utils/acvp/trusty_modulewrapper.cpp b/trusty/utils/acvp/trusty_modulewrapper.cpp
new file mode 100644
index 0000000..70ffb52
--- /dev/null
+++ b/trusty/utils/acvp/trusty_modulewrapper.cpp
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "TrustyAcvpModulewrapper"
+
+#include <BufferAllocator/BufferAllocator.h>
+#include <android-base/file.h>
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+#include <errno.h>
+#include <log/log.h>
+#include <modulewrapper.h>
+#include <openssl/span.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <trusty/tipc.h>
+#include <unistd.h>
+#include <iostream>
+
+#include "acvp_ipc.h"
+
+constexpr const char kTrustyDeviceName[] = "/dev/trusty-ipc-dev0";
+
+using android::base::ErrnoError;
+using android::base::Error;
+using android::base::Result;
+using android::base::unique_fd;
+using android::base::WriteFully;
+
+static inline size_t AlignUpToPage(size_t size) {
+ return (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+}
+
+namespace {
+
+class ModuleWrapper {
+ private:
+ static const char* kAcvpPort_;
+ static const char* kTrustyDeviceName_;
+
+ public:
+ ModuleWrapper();
+ ~ModuleWrapper();
+
+ Result<void> SendMessage(bssl::Span<const bssl::Span<const uint8_t>>);
+
+ Result<void> ForwardResponse();
+
+ private:
+ // Connection to the Trusty ACVP service
+ int tipc_fd_ = -1;
+
+ // Shared memory DMA buf
+ unique_fd dmabuf_fd_;
+
+ // Size of shared memory mapping
+ size_t shm_size_ = 0;
+
+ // Shared memory mapping
+ uint8_t* shm_buffer_ = nullptr;
+};
+
+} // namespace
+
+const char* ModuleWrapper::kAcvpPort_ = ACVP_PORT;
+const char* ModuleWrapper::kTrustyDeviceName_ = kTrustyDeviceName;
+
+ModuleWrapper::ModuleWrapper() {
+ tipc_fd_ = tipc_connect(kTrustyDeviceName_, kAcvpPort_);
+ if (tipc_fd_ < 0) {
+ fprintf(stderr, "Failed to connect to Trusty ACVP test app: %s\n", strerror(-tipc_fd_));
+ }
+}
+
+ModuleWrapper::~ModuleWrapper() {
+ if (tipc_fd_ >= 0) {
+ tipc_close(tipc_fd_);
+ }
+
+ if (shm_buffer_) {
+ munmap(shm_buffer_, shm_size_);
+ }
+}
+
+Result<void> ModuleWrapper::SendMessage(bssl::Span<const bssl::Span<const uint8_t>> args) {
+ assert(args.size() < ACVP_MAX_NUM_ARGUMENTS);
+ assert(args[0].size() < ACVP_MAX_NAME_LENGTH);
+
+ struct acvp_req request;
+ request.num_args = args.size();
+
+ size_t total_args_size = 0;
+ for (auto arg : args) {
+ total_args_size += arg.size();
+ }
+
+ shm_size_ = ACVP_MIN_SHARED_MEMORY;
+ if (total_args_size > shm_size_) {
+ shm_size_ = AlignUpToPage(total_args_size);
+ }
+ request.buffer_size = shm_size_;
+
+ struct iovec iov = {
+ .iov_base = &request,
+ .iov_len = sizeof(struct acvp_req),
+ };
+
+ BufferAllocator alloc;
+ dmabuf_fd_.reset(alloc.Alloc(kDmabufSystemHeapName, shm_size_));
+ if (!dmabuf_fd_.ok()) {
+ return ErrnoError() << "Error creating dmabuf";
+ }
+
+ shm_buffer_ = (uint8_t*)mmap(0, shm_size_, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd_, 0);
+ if (shm_buffer_ == MAP_FAILED) {
+ return ErrnoError() << "Failed to map shared memory dmabuf";
+ }
+
+ size_t cur_offset = 0;
+ for (int i = 0; i < args.size(); ++i) {
+ request.lengths[i] = args[i].size();
+ memcpy(shm_buffer_ + cur_offset, args[i].data(), args[i].size());
+ cur_offset += args[i].size();
+ }
+
+ struct trusty_shm shm = {
+ .fd = dmabuf_fd_.get(),
+ .transfer = TRUSTY_SHARE,
+ };
+
+ int rc = tipc_send(tipc_fd_, &iov, 1, &shm, 1);
+ if (rc != sizeof(struct acvp_req)) {
+ return ErrnoError() << "Failed to send request to Trusty ACVP service";
+ }
+
+ return {};
+}
+
+Result<void> ModuleWrapper::ForwardResponse() {
+ struct acvp_resp resp;
+ int bytes_read = read(tipc_fd_, &resp, sizeof(struct acvp_resp));
+ if (bytes_read < 0) {
+ return ErrnoError() << "Failed to read response from Trusty ACVP service";
+ }
+
+ if (bytes_read != sizeof(struct acvp_resp)) {
+ return Error() << "Trusty ACVP response overflowed expected size";
+ }
+
+ size_t total_args_size = 0;
+ for (size_t i = 0; i < resp.num_spans; i++) {
+ total_args_size += resp.lengths[i];
+ }
+
+ iovec iovs[2];
+ iovs[0].iov_base = &resp;
+ iovs[0].iov_len = sizeof(uint32_t) * (1 + resp.num_spans);
+
+ iovs[1].iov_base = shm_buffer_;
+ iovs[1].iov_len = total_args_size;
+
+ size_t iov_done = 0;
+ while (iov_done < 2) {
+ ssize_t r;
+ do {
+ r = writev(STDOUT_FILENO, &iovs[iov_done], 2 - iov_done);
+ } while (r == -1 && errno == EINTR);
+
+ if (r <= 0) {
+ return Error() << "Failed to write ACVP response to standard out";
+ }
+
+ size_t written = r;
+ for (size_t i = iov_done; i < 2 && written > 0; i++) {
+ iovec& iov = iovs[i];
+
+ size_t done = written;
+ if (done > iov.iov_len) {
+ done = iov.iov_len;
+ }
+
+ iov.iov_base = reinterpret_cast<uint8_t*>(iov.iov_base) + done;
+ iov.iov_len -= done;
+ written -= done;
+
+ if (iov.iov_len == 0) {
+ iov_done++;
+ }
+ }
+
+ assert(written == 0);
+ }
+
+ return {};
+}
+
+int main() {
+ for (;;) {
+ auto buffer = bssl::acvp::RequestBuffer::New();
+ auto args = bssl::acvp::ParseArgsFromFd(STDIN_FILENO, buffer.get());
+ if (args.empty()) {
+ ALOGE("Could not parse arguments\n");
+ return EXIT_FAILURE;
+ }
+
+ ModuleWrapper wrapper;
+ auto res = wrapper.SendMessage(args);
+ if (!res.ok()) {
+ std::cerr << res.error() << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ res = wrapper.ForwardResponse();
+ if (!res.ok()) {
+ std::cerr << res.error() << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ return EXIT_SUCCESS;
+};