Merge "init: Support booting off GSIs installed to non-userdata block devices."
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index 6960345..9791769 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -312,7 +312,7 @@
std::string android_dir = user_dir + OS_PATH_SEPARATOR + ".android";
struct stat buf;
if (stat(android_dir.c_str(), &buf) == -1) {
- if (adb_mkdir(android_dir.c_str(), 0750) == -1) {
+ if (adb_mkdir(android_dir, 0750) == -1) {
PLOG(FATAL) << "Cannot mkdir '" << android_dir << "'";
}
}
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp
index 72ca59a..a6be203 100644
--- a/adb/bugreport_test.cpp
+++ b/adb/bugreport_test.cpp
@@ -136,7 +136,7 @@
void ExpectBugreportzVersion(const std::string& version) {
EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _))
- .WillOnce(DoAll(WithArg<2>(WriteOnStderr(version.c_str())),
+ .WillOnce(DoAll(WithArg<2>(WriteOnStderr(version)),
WithArg<2>(ReturnCallbackDone(0))));
}
diff --git a/adb/client/auth.cpp b/adb/client/auth.cpp
index bcb829b..3eee426 100644
--- a/adb/client/auth.cpp
+++ b/adb/client/auth.cpp
@@ -416,7 +416,7 @@
#endif
for (const std::string& path : key_paths) {
- load_keys(path.c_str());
+ load_keys(path);
}
}
diff --git a/adb/client/file_sync_client.cpp b/adb/client/file_sync_client.cpp
index 7e470e1..5d10238 100644
--- a/adb/client/file_sync_client.cpp
+++ b/adb/client/file_sync_client.cpp
@@ -1012,7 +1012,7 @@
dst_dir.append(android::base::Basename(src_path));
}
- success &= copy_local_dir_remote(sc, src_path, dst_dir.c_str(), sync, false);
+ success &= copy_local_dir_remote(sc, src_path, dst_dir, sync, false);
continue;
} else if (!should_push_file(st.st_mode)) {
sc.Warning("skipping special file '%s' (mode = 0o%o)", src_path, st.st_mode);
@@ -1128,7 +1128,7 @@
// Recursively build the list of files to copy.
sc.Printf("pull: building file list...");
std::vector<copyinfo> file_list;
- if (!remote_build_list(sc, &file_list, rpath.c_str(), lpath.c_str())) {
+ if (!remote_build_list(sc, &file_list, rpath, lpath)) {
return false;
}
@@ -1240,7 +1240,7 @@
dst_dir.append(android::base::Basename(src_path));
}
- success &= copy_remote_dir_local(sc, src_path, dst_dir.c_str(), copy_attrs);
+ success &= copy_remote_dir_local(sc, src_path, dst_dir, copy_attrs);
continue;
} else if (!should_pull_file(src_st.st_mode)) {
sc.Warning("skipping special file '%s' (mode = 0o%o)", src_path, src_st.st_mode);
diff --git a/adb/daemon/file_sync_service.cpp b/adb/daemon/file_sync_service.cpp
index 29bd798..e82a51f 100644
--- a/adb/daemon/file_sync_service.cpp
+++ b/adb/daemon/file_sync_service.cpp
@@ -422,7 +422,7 @@
bool result;
uint32_t timestamp;
if (S_ISLNK(mode)) {
- result = handle_send_link(s, path.c_str(), ×tamp, buffer);
+ result = handle_send_link(s, path, ×tamp, buffer);
} else {
// Copy user permission bits to "group" and "other" permissions.
mode &= 0777;
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index b42236e..8a50003 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -267,7 +267,7 @@
adb_thread_setname("UsbFfs-monitor");
bool bound = false;
- bool started = false;
+ bool enabled = false;
bool running = true;
while (running) {
adb_pollfd pfd[2] = {
@@ -298,16 +298,32 @@
switch (event.type) {
case FUNCTIONFS_BIND:
CHECK(!bound) << "received FUNCTIONFS_BIND while already bound?";
+ CHECK(!enabled) << "received FUNCTIONFS_BIND while already enabled?";
bound = true;
+
break;
case FUNCTIONFS_ENABLE:
- CHECK(!started) << "received FUNCTIONFS_ENABLE while already running?";
- started = true;
+ CHECK(bound) << "received FUNCTIONFS_ENABLE while not bound?";
+ CHECK(!enabled) << "received FUNCTIONFS_ENABLE while already enabled?";
+ enabled = true;
+
StartWorker();
break;
case FUNCTIONFS_DISABLE:
+ CHECK(bound) << "received FUNCTIONFS_DISABLE while not bound?";
+ CHECK(enabled) << "received FUNCTIONFS_DISABLE while not enabled?";
+ enabled = false;
+
+ running = false;
+ break;
+
+ case FUNCTIONFS_UNBIND:
+ CHECK(!enabled) << "received FUNCTIONFS_UNBIND while still enabled?";
+ CHECK(bound) << "received FUNCTIONFS_UNBIND when not bound?";
+ bound = false;
+
running = false;
break;
}
@@ -339,7 +355,7 @@
LOG(FATAL) << "hit EOF on eventfd";
}
- WaitForEvents();
+ ReadEvents();
}
});
}
@@ -389,7 +405,7 @@
return block;
}
- void WaitForEvents() {
+ void ReadEvents() {
static constexpr size_t kMaxEvents = kUsbReadQueueDepth + kUsbWriteQueueDepth;
struct io_event events[kMaxEvents];
struct timespec timeout = {.tv_sec = 0, .tv_nsec = 0};
@@ -552,6 +568,8 @@
LOG(VERBOSE) << "submitting write_request " << static_cast<void*>(iocbs[i]);
}
+ writes_submitted_ += writes_to_submit;
+
int rc = io_submit(aio_context_.get(), writes_to_submit, iocbs);
if (rc == -1) {
HandleError(StringPrintf("failed to submit write requests: %s", strerror(errno)));
@@ -560,8 +578,6 @@
LOG(FATAL) << "failed to submit all writes: wanted to submit " << writes_to_submit
<< ", actually submitted " << rc;
}
-
- writes_submitted_ += rc;
}
void HandleError(const std::string& error) {
diff --git a/adb/services.cpp b/adb/services.cpp
index 80f9f79..cf346ba 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -188,7 +188,7 @@
if (!strncmp(host.c_str(), "emu:", 4)) {
connect_emulator(host.c_str() + 4, &response);
} else {
- connect_device(host.c_str(), &response);
+ connect_device(host, &response);
}
// Send response for emulator and device
diff --git a/base/file.cpp b/base/file.cpp
index 2f4a517..adc8984 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -385,7 +385,12 @@
bool Realpath(const std::string& path, std::string* result) {
result->clear();
- char* realpath_buf = realpath(path.c_str(), nullptr);
+ // realpath may exit with EINTR. Retry if so.
+ char* realpath_buf = nullptr;
+ do {
+ realpath_buf = realpath(path.c_str(), nullptr);
+ } while (realpath_buf == nullptr && errno == EINTR);
+
if (realpath_buf == nullptr) {
return false;
}
diff --git a/base/include/android-base/strings.h b/base/include/android-base/strings.h
index fc5c1ce..8e9716f 100644
--- a/base/include/android-base/strings.h
+++ b/base/include/android-base/strings.h
@@ -56,23 +56,17 @@
extern template std::string Join(const std::vector<const char*>&, const std::string&);
// Tests whether 's' starts with 'prefix'.
-// TODO: string_view
-bool StartsWith(const std::string& s, const char* prefix);
-bool StartsWithIgnoreCase(const std::string& s, const char* prefix);
-bool StartsWith(const std::string& s, const std::string& prefix);
-bool StartsWithIgnoreCase(const std::string& s, const std::string& prefix);
-bool StartsWith(const std::string& s, char prefix);
+bool StartsWith(std::string_view s, std::string_view prefix);
+bool StartsWith(std::string_view s, char prefix);
+bool StartsWithIgnoreCase(std::string_view s, std::string_view prefix);
// Tests whether 's' ends with 'suffix'.
-// TODO: string_view
-bool EndsWith(const std::string& s, const char* suffix);
-bool EndsWithIgnoreCase(const std::string& s, const char* suffix);
-bool EndsWith(const std::string& s, const std::string& suffix);
-bool EndsWithIgnoreCase(const std::string& s, const std::string& suffix);
-bool EndsWith(const std::string& s, char suffix);
+bool EndsWith(std::string_view s, std::string_view suffix);
+bool EndsWith(std::string_view s, char suffix);
+bool EndsWithIgnoreCase(std::string_view s, std::string_view suffix);
// Tests whether 'lhs' equals 'rhs', ignoring case.
-bool EqualsIgnoreCase(const std::string& lhs, const std::string& rhs);
+bool EqualsIgnoreCase(std::string_view lhs, std::string_view rhs);
} // namespace base
} // namespace android
diff --git a/base/strings.cpp b/base/strings.cpp
index 2d6eef0..bb3167e 100644
--- a/base/strings.cpp
+++ b/base/strings.cpp
@@ -87,58 +87,33 @@
template std::string Join(const std::vector<std::string>&, const std::string&);
template std::string Join(const std::vector<const char*>&, const std::string&);
-bool StartsWith(const std::string& s, const char* prefix) {
- return strncmp(s.c_str(), prefix, strlen(prefix)) == 0;
+bool StartsWith(std::string_view s, std::string_view prefix) {
+ return s.substr(0, prefix.size()) == prefix;
}
-bool StartsWith(const std::string& s, const std::string& prefix) {
- return strncmp(s.c_str(), prefix.c_str(), prefix.size()) == 0;
+bool StartsWith(std::string_view s, char prefix) {
+ return !s.empty() && s.front() == prefix;
}
-bool StartsWith(const std::string& s, char prefix) {
- return *s.c_str() == prefix; // Use c_str() to guarantee there is at least a '\0'.
+bool StartsWithIgnoreCase(std::string_view s, std::string_view prefix) {
+ return s.size() >= prefix.size() && strncasecmp(s.data(), prefix.data(), prefix.size()) == 0;
}
-bool StartsWithIgnoreCase(const std::string& s, const char* prefix) {
- return strncasecmp(s.c_str(), prefix, strlen(prefix)) == 0;
+bool EndsWith(std::string_view s, std::string_view suffix) {
+ return s.size() >= suffix.size() && s.substr(s.size() - suffix.size(), suffix.size()) == suffix;
}
-bool StartsWithIgnoreCase(const std::string& s, const std::string& prefix) {
- return strncasecmp(s.c_str(), prefix.c_str(), prefix.size()) == 0;
+bool EndsWith(std::string_view s, char suffix) {
+ return !s.empty() && s.back() == suffix;
}
-static bool EndsWith(const std::string& s, const char* suffix, size_t suffix_length,
- bool case_sensitive) {
- size_t string_length = s.size();
- if (suffix_length > string_length) {
- return false;
- }
- size_t offset = string_length - suffix_length;
- return (case_sensitive ? strncmp : strncasecmp)(s.c_str() + offset, suffix, suffix_length) == 0;
+bool EndsWithIgnoreCase(std::string_view s, std::string_view suffix) {
+ return s.size() >= suffix.size() &&
+ strncasecmp(s.data() + (s.size() - suffix.size()), suffix.data(), suffix.size()) == 0;
}
-bool EndsWith(const std::string& s, const char* suffix) {
- return EndsWith(s, suffix, strlen(suffix), true);
-}
-
-bool EndsWith(const std::string& s, const std::string& suffix) {
- return EndsWith(s, suffix.c_str(), suffix.size(), true);
-}
-
-bool EndsWith(const std::string& s, char suffix) {
- return EndsWith(s, &suffix, 1, true);
-}
-
-bool EndsWithIgnoreCase(const std::string& s, const char* suffix) {
- return EndsWith(s, suffix, strlen(suffix), false);
-}
-
-bool EndsWithIgnoreCase(const std::string& s, const std::string& suffix) {
- return EndsWith(s, suffix.c_str(), suffix.size(), false);
-}
-
-bool EqualsIgnoreCase(const std::string& lhs, const std::string& rhs) {
- return strcasecmp(lhs.c_str(), rhs.c_str()) == 0;
+bool EqualsIgnoreCase(std::string_view lhs, std::string_view rhs) {
+ return lhs.size() == rhs.size() && strncasecmp(lhs.data(), rhs.data(), lhs.size()) == 0;
}
} // namespace base
diff --git a/debuggerd/libdebuggerd/backtrace.cpp b/debuggerd/libdebuggerd/backtrace.cpp
index 753ebcb..94fcfb2 100644
--- a/debuggerd/libdebuggerd/backtrace.cpp
+++ b/debuggerd/libdebuggerd/backtrace.cpp
@@ -74,6 +74,7 @@
return;
}
+ unwinder->SetDisplayBuildID(true);
for (size_t i = 0; i < unwinder->NumFrames(); i++) {
_LOG(&log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(i).c_str());
}
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index c08afda..47a7a8f 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -371,6 +371,7 @@
}
void dump_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
+ unwinder->SetDisplayBuildID(true);
for (size_t i = 0; i < unwinder->NumFrames(); i++) {
_LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(i).c_str());
}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 4cdd8bc..827db96 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1805,7 +1805,7 @@
auto format = [&](const std::string& partition) {
fb_perform_format(partition, 0, type_override, size_override, "");
};
- do_for_partitions(partition.c_str(), slot_override, format, true);
+ do_for_partitions(partition, slot_override, format, true);
} else if (command == "signature") {
std::string filename = next_arg(&args);
std::vector<char> data;
@@ -1876,7 +1876,7 @@
}
do_flash(partition.c_str(), fname.c_str());
};
- do_for_partitions(pname.c_str(), slot_override, flash, true);
+ do_for_partitions(pname, slot_override, flash, true);
} else if (command == "flash:raw") {
std::string partition = next_arg(&args);
std::string kernel = next_arg(&args);
diff --git a/fastboot/fuzzy_fastboot/fixtures.cpp b/fastboot/fuzzy_fastboot/fixtures.cpp
index eb043ce..c23da01 100644
--- a/fastboot/fuzzy_fastboot/fixtures.cpp
+++ b/fastboot/fuzzy_fastboot/fixtures.cpp
@@ -130,10 +130,14 @@
ASSERT_EQ(device_path, cb_scratch); // The path can not change
}
fb = std::unique_ptr<FastBootDriver>(new FastBootDriver(transport.get(), {}, true));
+ // No error checking since non-A/B devices may not support the command
+ fb->GetVar("current-slot", &initial_slot);
}
void FastBootTest::TearDown() {
EXPECT_TRUE(UsbStillAvailible()) << USB_PORT_GONE;
+ // No error checking since non-A/B devices may not support the command
+ fb->SetActive(initial_slot);
TearDownSerial();
@@ -232,6 +236,7 @@
std::string FastBootTest::device_path = "";
std::string FastBootTest::cb_scratch = "";
+std::string FastBootTest::initial_slot = "";
int FastBootTest::serial_port = 0;
template <bool UNLOCKED>
diff --git a/fastboot/fuzzy_fastboot/fixtures.h b/fastboot/fuzzy_fastboot/fixtures.h
index 9c955ea..7c8d54d 100644
--- a/fastboot/fuzzy_fastboot/fixtures.h
+++ b/fastboot/fuzzy_fastboot/fixtures.h
@@ -70,6 +70,7 @@
// This is an annoying hack
static std::string cb_scratch;
static std::string device_path;
+ static std::string initial_slot;
};
template <bool UNLOCKED>
diff --git a/fs_mgr/libdm/Android.mk b/fs_mgr/libdm/Android.mk
new file mode 100644
index 0000000..6aedc25
--- /dev/null
+++ b/fs_mgr/libdm/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2018 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsKernelLibdmTest
+-include test/vts/tools/build/Android.host_config.mk
diff --git a/fs_mgr/libdm/AndroidTest.xml b/fs_mgr/libdm/AndroidTest.xml
new file mode 100644
index 0000000..b4e0c23
--- /dev/null
+++ b/fs_mgr/libdm/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Config for VTS VtsKernelLibdmTest">
+ <option name="config-descriptor:metadata" key="plan" value="vts-kernel" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+ <option name="abort-on-push-failure" value="false"/>
+ <option name="push-group" value="HostDrivenTest.push"/>
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+ <option name="test-module-name" value="VtsKernelLibdmTest"/>
+ <option name="binary-test-source" value="_32bit::DATA/nativetest/libdm_test/libdm_test" />
+ <option name="binary-test-source" value="_64bit::DATA/nativetest64/libdm_test/libdm_test" />
+ <option name="binary-test-type" value="gtest"/>
+ <option name="test-timeout" value="1m"/>
+ <option name="precondition-first-api-level" value="29" />
+ </test>
+</configuration>
+
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index 355b7a1..7039994 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -43,6 +43,11 @@
windows: {
enabled: true,
},
+ android: {
+ shared_libs: [
+ "libcutils",
+ ],
+ },
},
export_include_dirs: ["include"],
}
diff --git a/fs_mgr/liblp/Android.mk b/fs_mgr/liblp/Android.mk
new file mode 100644
index 0000000..7f7f891
--- /dev/null
+++ b/fs_mgr/liblp/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2018 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsKernelLiblpTest
+-include test/vts/tools/build/Android.host_config.mk
diff --git a/fs_mgr/liblp/AndroidTest.xml b/fs_mgr/liblp/AndroidTest.xml
new file mode 100644
index 0000000..007a302
--- /dev/null
+++ b/fs_mgr/liblp/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Config for VTS VtsKernelLiblpTest">
+ <option name="config-descriptor:metadata" key="plan" value="vts-kernel" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+ <option name="abort-on-push-failure" value="false"/>
+ <option name="push-group" value="HostDrivenTest.push"/>
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+ <option name="test-module-name" value="VtsKernelLiblpTest"/>
+ <option name="binary-test-source" value="_32bit::DATA/nativetest/liblp_test/liblp_test" />
+ <option name="binary-test-source" value="_64bit::DATA/nativetest64/liblp_test/liblp_test" />
+ <option name="binary-test-type" value="gtest"/>
+ <option name="test-timeout" value="1m"/>
+ <option name="precondition-first-api-level" value="29" />
+ </test>
+</configuration>
+
diff --git a/fs_mgr/liblp/images.cpp b/fs_mgr/liblp/images.cpp
index 5a498f9..56b5353 100644
--- a/fs_mgr/liblp/images.cpp
+++ b/fs_mgr/liblp/images.cpp
@@ -68,7 +68,7 @@
}
std::unique_ptr<LpMetadata> ReadFromImageFile(const std::string& image_file) {
- unique_fd fd(open(image_file.c_str(), O_RDONLY | O_CLOEXEC));
+ unique_fd fd = GetControlFileOrOpen(image_file.c_str(), O_RDONLY | O_CLOEXEC);
if (fd < 0) {
PERROR << __PRETTY_FUNCTION__ << " open failed: " << image_file;
return nullptr;
@@ -408,7 +408,7 @@
}
int SparseBuilder::OpenImageFile(const std::string& file) {
- android::base::unique_fd source_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
+ android::base::unique_fd source_fd = GetControlFileOrOpen(file.c_str(), O_RDONLY | O_CLOEXEC);
if (source_fd < 0) {
PERROR << "open image file failed: " << file;
return -1;
diff --git a/fs_mgr/liblp/partition_opener.cpp b/fs_mgr/liblp/partition_opener.cpp
index 898f241..bb8ec9c 100644
--- a/fs_mgr/liblp/partition_opener.cpp
+++ b/fs_mgr/liblp/partition_opener.cpp
@@ -45,7 +45,7 @@
bool GetBlockDeviceInfo(const std::string& block_device, BlockDeviceInfo* device_info) {
#if defined(__linux__)
- unique_fd fd(open(block_device.c_str(), O_RDONLY));
+ unique_fd fd = GetControlFileOrOpen(block_device.c_str(), O_RDONLY);
if (fd < 0) {
PERROR << __PRETTY_FUNCTION__ << "open '" << block_device << "' failed";
return false;
@@ -85,7 +85,7 @@
unique_fd PartitionOpener::Open(const std::string& partition_name, int flags) const {
std::string path = GetPartitionAbsolutePath(partition_name);
- return unique_fd{open(path.c_str(), flags | O_CLOEXEC)};
+ return GetControlFileOrOpen(path.c_str(), flags | O_CLOEXEC);
}
bool PartitionOpener::GetInfo(const std::string& partition_name, BlockDeviceInfo* info) const {
diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp
index ecf94a4..72a3c57 100644
--- a/fs_mgr/liblp/utility.cpp
+++ b/fs_mgr/liblp/utility.cpp
@@ -28,6 +28,10 @@
#include <ext4_utils/ext4_utils.h>
#include <openssl/sha.h>
+#ifdef __ANDROID__
+#include <cutils/android_get_control_file.h>
+#endif
+
#include "utility.h"
namespace android {
@@ -171,5 +175,19 @@
#endif
}
+base::unique_fd GetControlFileOrOpen(const char* path, int flags) {
+#if defined(__ANDROID__)
+ int fd = android_get_control_file(path);
+ if (fd >= 0) {
+ int newfd = TEMP_FAILURE_RETRY(dup(fd));
+ if (newfd >= 0) {
+ return base::unique_fd(newfd);
+ }
+ PERROR << "Cannot dup fd for already controlled file: " << path << ", reopening...";
+ }
+#endif
+ return base::unique_fd(open(path, flags));
+}
+
} // namespace fs_mgr
} // namespace android
diff --git a/fs_mgr/liblp/utility.h b/fs_mgr/liblp/utility.h
index e8b2ca9..96f1717 100644
--- a/fs_mgr/liblp/utility.h
+++ b/fs_mgr/liblp/utility.h
@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
#include "liblp/liblp.h"
@@ -92,6 +93,8 @@
// Call BLKROSET ioctl on fd so that fd is readonly / read-writable.
bool SetBlockReadonly(int fd, bool readonly);
+::android::base::unique_fd GetControlFileOrOpen(const char* path, int flags);
+
} // namespace fs_mgr
} // namespace android
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index b95e54e..c09dc3d 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -447,59 +447,71 @@
exit 1
}
-[ "USAGE: EXPECT_EQ <lval> <rval> [message]
+[ "USAGE: EXPECT_EQ <lval> <rval> [--warning [message]]
Returns true if (regex) lval matches rval" ]
EXPECT_EQ() {
local lval="${1}"
local rval="${2}"
shift 2
+ local error=1
+ local prefix="${RED}[ ERROR ]${NORMAL}"
+ if [ X"${1}" = X"--warning" ]; then
+ prefix="${RED}[ WARNING ]${NORMAL}"
+ error=0
+ shift 1
+ fi
if ! ( echo X"${rval}" | grep '^X'"${lval}"'$' >/dev/null 2>/dev/null ); then
if [ `echo ${lval}${rval}${*} | wc -c` -gt 50 -o "${rval}" != "${rval%
*}" ]; then
- echo "ERROR: expected \"${lval}\"" >&2
- echo " got \"${rval}\"" |
+ echo "${prefix} expected \"${lval}\"" >&2
+ echo "${prefix} got \"${rval}\"" |
sed ': again
N
s/\(\n\)\([^ ]\)/\1 \2/
t again' >&2
if [ -n "${*}" ] ; then
- echo " ${*}" >&2
+ echo "${prefix} ${*}" >&2
fi
else
- echo "ERROR: expected \"${lval}\" got \"${rval}\" ${*}" >&2
+ echo "${prefix} expected \"${lval}\" got \"${rval}\" ${*}" >&2
fi
- return 1
+ return ${error}
fi
if [ -n "${*}" ] ; then
- if [ X"${lval}" != X"${rval}" ]; then
+ prefix="${GREEN}[ INFO ]${NORMAL}"
+ if [ X"${lval}" != X"${rval}" ]; then # we were supplied a regex?
if [ `echo ${lval}${rval}${*} | wc -c` -gt 60 -o "${rval}" != "${rval% *}" ]; then
- echo "INFO: ok \"${lval}\"" >&2
+ echo "${prefix} ok \"${lval}\"" >&2
echo " = \"${rval}\"" |
sed ': again
N
s/\(\n\)\([^ ]\)/\1 \2/
t again' >&2
if [ -n "${*}" ] ; then
- echo " ${*}" >&2
+ echo "${prefix} ${*}" >&2
fi
else
- echo "INFO: ok \"${lval}\" = \"${rval}\" ${*}" >&2
+ echo "${prefix} ok \"${lval}\" = \"${rval}\" ${*}" >&2
fi
else
- echo "INFO: ok \"${lval}\" ${*}" >&2
+ echo "${prefix} ok \"${lval}\" ${*}" >&2
fi
fi
return 0
}
-[ "USAGE: check_eq <lval> <rval> [message]
+[ "USAGE: check_eq <lval> <rval> [--warning [message]]
Exits if (regex) lval mismatches rval" ]
check_eq() {
local lval="${1}"
local rval="${2}"
shift 2
+ if [ X"${1}" = X"--warning" ]; then
+ EXPECT_EQ "${lval}" "${rval}" ${*}
+ return
+ fi
EXPECT_EQ "${lval}" "${rval}" ||
die "${@}"
}
@@ -1085,14 +1097,9 @@
check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
vendor content after flash vendor
else
- (
- echo "${ORANGE}[ WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
- restore() {
- true
- }
- check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
- vendor content after flash vendor
- )
+ echo "${ORANGE}[ WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
+ check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
+ --warning vendor content after flash vendor
fi
fi
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 5fe58ac..bde5fbe 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -36,6 +36,7 @@
#include <linux/netlink.h>
#include <sys/socket.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/klog.h>
#include <cutils/misc.h>
#include <cutils/properties.h>
@@ -206,10 +207,9 @@
#define MAX_KLOG_WRITE_BUF_SZ 256
static void dump_last_kmsg(void) {
- char* buf;
+ std::string buf;
char* ptr;
- unsigned sz = 0;
- int len;
+ size_t len;
LOGW("\n");
LOGW("*************** LAST KMSG ***************\n");
@@ -221,21 +221,25 @@
"/proc/last_kmsg",
// clang-format on
};
- for (size_t i = 0; i < arraysize(kmsg); ++i) {
- buf = (char*)load_file(kmsg[i], &sz);
- if (buf && sz) break;
+ for (size_t i = 0; i < arraysize(kmsg) && buf.empty(); ++i) {
+ auto fd = android_get_control_file(kmsg[i]);
+ if (fd >= 0) {
+ android::base::ReadFdToString(fd, &buf);
+ } else {
+ android::base::ReadFileToString(kmsg[i], &buf);
+ }
}
- if (!buf || !sz) {
+ if (buf.empty()) {
LOGW("last_kmsg not found. Cold reset?\n");
goto out;
}
- len = min(sz, LAST_KMSG_MAX_SZ);
- ptr = buf + (sz - len);
+ len = min(buf.size(), LAST_KMSG_MAX_SZ);
+ ptr = &buf[buf.size() - len];
while (len > 0) {
- int cnt = min(len, MAX_KLOG_WRITE_BUF_SZ);
+ size_t cnt = min(len, MAX_KLOG_WRITE_BUF_SZ);
char yoink;
char* nl;
@@ -251,8 +255,6 @@
ptr += cnt;
}
- free(buf);
-
out:
LOGW("\n");
LOGW("************* END LAST KMSG *************\n");
diff --git a/init/README.md b/init/README.md
index b2039b4..d86f077 100644
--- a/init/README.md
+++ b/init/README.md
@@ -277,10 +277,6 @@
since it has some peculiarities for backwards compatibility reasons. The 'imports' section of
this file has more details on the order.
-`parse_apex_configs`
- Parses config file(s) from the mounted APEXes. Intented to be used only once
- when apexd notifies the mount event by setting apexd.status to ready.
-
`priority <priority>`
> Scheduling priority of the service process. This value has to be in range
-20 to 19. Default priority is 0. Priority is set via setpriority().
@@ -512,6 +508,10 @@
_options_ include "barrier=1", "noauto\_da\_alloc", "discard", ... as
a comma separated string, eg: barrier=1,noauto\_da\_alloc
+`parse_apex_configs`
+> Parses config file(s) from the mounted APEXes. Intented to be used only once
+ when apexd notifies the mount event by setting apexd.status to ready.
+
`restart <service>`
> Stops and restarts a running service, does nothing if the service is currently
restarting, otherwise, it just starts the service.
diff --git a/init/service.cpp b/init/service.cpp
index cba42c4..6d08cb1 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -756,6 +756,11 @@
if (args[2] != "r" && args[2] != "w" && args[2] != "rw") {
return Error() << "file type must be 'r', 'w' or 'rw'";
}
+ std::string expanded;
+ if (!expand_props(args[1], &expanded)) {
+ return Error() << "Could not expand property in file path '" << args[1] << "'";
+ }
+ args[1] = std::move(expanded);
if ((args[1][0] != '/') || (args[1].find("../") != std::string::npos)) {
return Error() << "file name must not be relative";
}
diff --git a/janitors/OWNERS b/janitors/OWNERS
index 0610b41..3e32c26 100644
--- a/janitors/OWNERS
+++ b/janitors/OWNERS
@@ -1,4 +1,6 @@
# OWNERS file for projects that don't really have owners so much as volunteer janitors.
+ccross@google.com
+dwillemsen@google.com
enh@google.com
hhb@google.com
narayan@google.com
diff --git a/libbacktrace/UnwindStack.h b/libbacktrace/UnwindStack.h
index 33c4282..4ec591d 100644
--- a/libbacktrace/UnwindStack.h
+++ b/libbacktrace/UnwindStack.h
@@ -58,7 +58,7 @@
bool Unwind(size_t num_ignore_frames, void* context) override;
- std::string GetFunctionNameRaw(uint64_t pc, uint64_t* offset);
+ std::string GetFunctionNameRaw(uint64_t pc, uint64_t* offset) override;
size_t Read(uint64_t addr, uint8_t* buffer, size_t bytes) override;
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index b4b8cd1..83a7140 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -18,7 +18,6 @@
// they correspond to features not used by our host development tools
// which are also hard or even impossible to port to native Win32
libcutils_nonwindows_sources = [
- "android_get_control_file.cpp",
"fs.cpp",
"hashmap.cpp",
"multiuser.cpp",
@@ -102,6 +101,7 @@
android: {
srcs: libcutils_nonwindows_sources + [
+ "android_get_control_file.cpp",
"android_reboot.cpp",
"ashmem-dev.cpp",
"fs_config.cpp",
diff --git a/libcutils/android_get_control_env.h b/libcutils/android_get_control_env.h
index 638c831..a830269 100644
--- a/libcutils/android_get_control_env.h
+++ b/libcutils/android_get_control_env.h
@@ -14,20 +14,13 @@
* limitations under the License.
*/
-#ifndef __CUTILS_ANDROID_GET_CONTROL_ENV_H
-#define __CUTILS_ANDROID_GET_CONTROL_ENV_H
+#pragma once
-/* To declare library function hidden and internal */
-#define LIBCUTILS_HIDDEN __attribute__((visibility("hidden")))
+#include <sys/cdefs.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
-LIBCUTILS_HIDDEN int __android_get_control_from_env(const char* prefix,
- const char* name);
-#ifdef __cplusplus
-}
-#endif
+int __android_get_control_from_env(const char* prefix, const char* name)
+ __attribute__((visibility("hidden")));
-#endif /* __CUTILS_ANDROID_GET_CONTROL_ENV_H */
+__END_DECLS
diff --git a/libcutils/android_get_control_file.cpp b/libcutils/android_get_control_file.cpp
index d8121f5..d5b0894 100644
--- a/libcutils/android_get_control_file.cpp
+++ b/libcutils/android_get_control_file.cpp
@@ -39,14 +39,14 @@
#include <sys/types.h>
#include <unistd.h>
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+
#include "android_get_control_env.h"
-#ifndef TEMP_FAILURE_RETRY
-#define TEMP_FAILURE_RETRY(exp) (exp) // KISS implementation
-#endif
-
-LIBCUTILS_HIDDEN int __android_get_control_from_env(const char* prefix,
- const char* name) {
+int __android_get_control_from_env(const char* prefix, const char* name) {
if (!prefix || !name) return -1;
char *key = NULL;
@@ -67,48 +67,33 @@
long fd = strtol(val, NULL, 10);
if (errno) return -1;
- // validity checking
+ // Since we are inheriting an fd, it could legitimately exceed _SC_OPEN_MAX
if ((fd < 0) || (fd > INT_MAX)) return -1;
- // Since we are inheriting an fd, it could legitimately exceed _SC_OPEN_MAX
-
// Still open?
-#if defined(F_GETFD) // Lowest overhead
if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD)) < 0) return -1;
-#elif defined(F_GETFL) // Alternate lowest overhead
- if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL)) < 0) return -1;
-#else // Hail Mary pass
- struct stat s;
- if (TEMP_FAILURE_RETRY(fstat(fd, &s)) < 0) return -1;
-#endif
return static_cast<int>(fd);
}
int android_get_control_file(const char* path) {
- int fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, path);
+ std::string given_path;
+ if (!android::base::Realpath(path, &given_path)) return -1;
-#if defined(__linux__)
- // Find file path from /proc and make sure it is correct
- char *proc = NULL;
- if (asprintf(&proc, "/proc/self/fd/%d", fd) < 0) return -1;
- if (!proc) return -1;
-
- size_t len = strlen(path);
- // readlink() does not guarantee a nul byte, len+2 so we catch truncation.
- char *buf = static_cast<char *>(calloc(1, len + 2));
- if (!buf) {
- free(proc);
- return -1;
+ // Try path, then realpath(path), as keys to get the fd from env.
+ auto fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, path);
+ if (fd < 0) {
+ fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, given_path.c_str());
+ if (fd < 0) return fd;
}
- ssize_t ret = TEMP_FAILURE_RETRY(readlink(proc, buf, len + 1));
- free(proc);
- int cmp = (len != static_cast<size_t>(ret)) || strcmp(buf, path);
- free(buf);
- if (ret < 0) return -1;
- if (cmp != 0) return -1;
+
+ // Find file path from /proc and make sure it is correct
+ auto proc = android::base::StringPrintf("/proc/self/fd/%d", fd);
+ std::string fd_path;
+ if (!android::base::Realpath(proc, &fd_path)) return -1;
+
+ if (given_path != fd_path) return -1;
// It is what we think it is
-#endif
return fd;
}
diff --git a/libcutils/sockets_unix.cpp b/libcutils/sockets_unix.cpp
index 2248817..6acdcd8 100644
--- a/libcutils/sockets_unix.cpp
+++ b/libcutils/sockets_unix.cpp
@@ -16,8 +16,6 @@
#include <cutils/sockets.h>
-#define LOG_TAG "socket-unix"
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -27,9 +25,6 @@
#include <time.h>
#include <unistd.h>
-#include <cutils/android_get_control_file.h>
-#include <log/log.h>
-
#include "android_get_control_env.h"
int socket_close(int sock) {
@@ -62,6 +57,7 @@
return writev(sock, iovec_buffers, num_buffers);
}
+#if defined(__ANDROID__)
int android_get_control_socket(const char* name) {
int fd = __android_get_control_from_env(ANDROID_SOCKET_ENV_PREFIX, name);
@@ -82,3 +78,8 @@
}
return -1;
}
+#else
+int android_get_control_socket(const char*) {
+ return -1;
+}
+#endif
diff --git a/libkeyutils/mini_keyctl.cpp b/libkeyutils/mini_keyctl.cpp
index e09c864..fe89e62 100644
--- a/libkeyutils/mini_keyctl.cpp
+++ b/libkeyutils/mini_keyctl.cpp
@@ -30,7 +30,6 @@
fprintf(stderr, "usage: mini-keyctl <action> [args,]\n");
fprintf(stderr, " mini-keyctl add <type> <desc> <data> <keyring>\n");
fprintf(stderr, " mini-keyctl padd <type> <desc> <keyring>\n");
- fprintf(stderr, " mini-keyctl dadd <type> <desc_prefix> <cert_dir> <keyring>\n");
fprintf(stderr, " mini-keyctl unlink <key> <keyring>\n");
fprintf(stderr, " mini-keyctl restrict_keyring <keyring>\n");
fprintf(stderr, " mini-keyctl security <key>\n");
@@ -56,14 +55,6 @@
std::string data = argv[4];
std::string keyring = argv[5];
return Add(type, desc, data, keyring);
- } else if (action == "dadd") {
- if (argc != 6) Usage(1);
- std::string type = argv[2];
- // The key description contains desc_prefix and an index.
- std::string desc_prefix = argv[3];
- std::string cert_dir = argv[4];
- std::string keyring = argv[5];
- return AddCertsFromDir(type, desc_prefix, cert_dir, keyring);
} else if (action == "padd") {
if (argc != 5) Usage(1);
std::string type = argv[2];
diff --git a/libkeyutils/mini_keyctl_utils.cpp b/libkeyutils/mini_keyctl_utils.cpp
index 9fe2dfe..56afea4 100644
--- a/libkeyutils/mini_keyctl_utils.cpp
+++ b/libkeyutils/mini_keyctl_utils.cpp
@@ -86,53 +86,6 @@
return false;
}
-int AddCertsFromDir(const std::string& type, const std::string& desc_prefix,
- const std::string& cert_dir, const std::string& keyring) {
- key_serial_t keyring_id;
- if (!GetKeyringId(keyring, &keyring_id)) {
- LOG(ERROR) << "Can not find keyring id";
- return 1;
- }
-
- std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(cert_dir.c_str()), closedir);
- if (!dir) {
- PLOG(WARNING) << "Failed to open directory " << cert_dir;
- return 1;
- }
- int keys_added = 0;
- struct dirent* dp;
- while ((dp = readdir(dir.get())) != NULL) {
- if (dp->d_type != DT_REG) {
- continue;
- }
- std::string cert_path = cert_dir + "/" + dp->d_name;
- std::string cert_buf;
- if (!android::base::ReadFileToString(cert_path, &cert_buf, false /* follow_symlinks */)) {
- LOG(ERROR) << "Failed to read " << cert_path;
- continue;
- }
-
- if (cert_buf.size() > kMaxCertSize) {
- LOG(ERROR) << "Certficate size too large: " << cert_path;
- continue;
- }
-
- // Add key to keyring.
- int key_desc_index = keys_added;
- std::string key_desc = desc_prefix + std::to_string(key_desc_index);
- key_serial_t key =
- add_key(type.c_str(), key_desc.c_str(), &cert_buf[0], cert_buf.size(), keyring_id);
- if (key < 0) {
- PLOG(ERROR) << "Failed to add key to keyring: " << cert_path;
- continue;
- }
- LOG(INFO) << "Key " << cert_path << " added to " << keyring << " with key id 0x" << std::hex
- << key;
- keys_added++;
- }
- return 0;
-}
-
int Unlink(key_serial_t key, const std::string& keyring) {
key_serial_t keyring_id;
if (!GetKeyringId(keyring, &keyring_id)) {
diff --git a/libkeyutils/mini_keyctl_utils.h b/libkeyutils/mini_keyctl_utils.h
index 804a357..3616831 100644
--- a/libkeyutils/mini_keyctl_utils.h
+++ b/libkeyutils/mini_keyctl_utils.h
@@ -18,11 +18,6 @@
#include <string>
-// Add all files in a directory as certificates to a keyring. |keyring| could be the keyring
-// description or keyring id in hex.
-int AddCertsFromDir(const std::string& type, const std::string& desc_prefix,
- const std::string& cert_dir, const std::string& keyring);
-
// Add key to a keyring. Returns non-zero if error happens.
int Add(const std::string& type, const std::string& desc, const std::string& data,
const std::string& keyring);
diff --git a/liblog/logger_name.cpp b/liblog/logger_name.cpp
index 3aa6841..ece0550 100644
--- a/liblog/logger_name.cpp
+++ b/liblog/logger_name.cpp
@@ -50,8 +50,9 @@
unsigned int ret;
if (!logName) {
- return static_cast<log_id_t>(0xFFFFFFFF);
+ return static_cast<log_id_t>(LOG_ID_MAX);
}
+
b = strrchr(logName, '/');
if (!b) {
b = logName;
@@ -65,5 +66,6 @@
return static_cast<log_id_t>(ret);
}
}
- return static_cast<log_id_t>(0xFFFFFFFF); /* should never happen */
+
+ return static_cast<log_id_t>(LOG_ID_MAX);
}
diff --git a/libmemunreachable/HeapWalker.cpp b/libmemunreachable/HeapWalker.cpp
index e11f079..7cae048 100644
--- a/libmemunreachable/HeapWalker.cpp
+++ b/libmemunreachable/HeapWalker.cpp
@@ -207,6 +207,6 @@
}
}
-ScopedSignalHandler::SignalFn ScopedSignalHandler::handler_;
+Allocator<ScopedSignalHandler::SignalFnMap>::unique_ptr ScopedSignalHandler::handler_map_;
} // namespace android
diff --git a/libmemunreachable/HeapWalker.h b/libmemunreachable/HeapWalker.h
index 9e3db08..f00bcca 100644
--- a/libmemunreachable/HeapWalker.h
+++ b/libmemunreachable/HeapWalker.h
@@ -52,7 +52,8 @@
allocation_bytes_(0),
roots_(allocator),
root_vals_(allocator),
- segv_handler_(),
+ sigsegv_handler_(allocator),
+ sigbus_handler_(allocator),
walking_ptr_(0),
walking_range_{0, 0},
segv_logged_(false),
@@ -62,10 +63,14 @@
valid_mappings_range_.end = 0;
valid_mappings_range_.begin = ~valid_allocations_range_.end;
- segv_handler_.install(
+ sigsegv_handler_.install(
SIGSEGV, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) {
this->HandleSegFault(handler, signal, siginfo, uctx);
});
+ sigbus_handler_.install(
+ SIGBUS, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) {
+ this->HandleSegFault(handler, signal, siginfo, uctx);
+ });
}
~HeapWalker() {}
@@ -106,7 +111,8 @@
allocator::vector<Range> roots_;
allocator::vector<uintptr_t> root_vals_;
- ScopedSignalHandler segv_handler_;
+ ScopedSignalHandler sigsegv_handler_;
+ ScopedSignalHandler sigbus_handler_;
volatile uintptr_t walking_ptr_;
Range walking_range_;
bool segv_logged_;
diff --git a/libmemunreachable/ScopedSignalHandler.h b/libmemunreachable/ScopedSignalHandler.h
index 9e08a8e..ef4473f 100644
--- a/libmemunreachable/ScopedSignalHandler.h
+++ b/libmemunreachable/ScopedSignalHandler.h
@@ -24,6 +24,7 @@
#include "android-base/macros.h"
+#include "Allocator.h"
#include "log.h"
namespace android {
@@ -32,17 +33,29 @@
public:
using Fn = std::function<void(ScopedSignalHandler&, int, siginfo_t*, void*)>;
- explicit ScopedSignalHandler() : signal_(-1) {}
+ explicit ScopedSignalHandler(Allocator<ScopedSignalHandler> allocator) : signal_(-1) {
+ if (handler_map_ == nullptr) {
+ Allocator<SignalFnMap> map_allocator = allocator;
+ handler_map_ = map_allocator.make_unique(allocator);
+ }
+ }
~ScopedSignalHandler() { reset(); }
template <class F>
void install(int signal, F&& f) {
if (signal_ != -1) MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed");
- handler_ = SignalFn([=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); });
+ if (handler_map_->find(signal) != handler_map_->end()) {
+ MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed for %d", signal);
+ }
+
+ (*handler_map_)[signal] =
+ SignalFn([=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); });
struct sigaction act {};
- act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) { handler_(signal, si, uctx); };
+ act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) {
+ ((*handler_map_)[signal])(signal, si, uctx);
+ };
act.sa_flags = SA_SIGINFO;
int ret = sigaction(signal, &act, &old_act_);
@@ -59,19 +72,22 @@
if (ret < 0) {
MEM_ALOGE("failed to uninstall segfault handler");
}
- handler_ = SignalFn{};
+
+ handler_map_->erase(signal_);
+ if (handler_map_->empty()) {
+ handler_map_.reset();
+ }
signal_ = -1;
}
}
private:
using SignalFn = std::function<void(int, siginfo_t*, void*)>;
+ using SignalFnMap = allocator::unordered_map<int, SignalFn>;
DISALLOW_COPY_AND_ASSIGN(ScopedSignalHandler);
int signal_;
struct sigaction old_act_;
- // TODO(ccross): to support multiple ScopedSignalHandlers handler_ would need
- // to be a static map of signals to handlers, but allocated with Allocator.
- static SignalFn handler_;
+ static Allocator<SignalFnMap>::unique_ptr handler_map_;
};
} // namespace android
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 1c2581f..5cc0857 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -288,8 +288,9 @@
// Give access to VNDK-SP libraries from the 'vndk' namespace.
vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
- LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr, "Cannot find \"%s\" namespace for %s apks",
- kVndkNamespaceName, origin_partition);
+ if (vndk_ns == nullptr) {
+ ALOGW("Cannot find \"%s\" namespace for %s apks", kVndkNamespaceName, origin_partition);
+ }
// Different name is useful for debugging
namespace_name = kVendorClassloaderNamespaceName;
diff --git a/libprocessgroup/Android.bp b/libprocessgroup/Android.bp
index d97f09f..07cbce9 100644
--- a/libprocessgroup/Android.bp
+++ b/libprocessgroup/Android.bp
@@ -45,5 +45,6 @@
cflags: [
"-Wall",
"-Werror",
+ "-Wexit-time-destructors",
],
}
diff --git a/libprocessgroup/cgroup_map.cpp b/libprocessgroup/cgroup_map.cpp
index 9951621..b3b497f 100644
--- a/libprocessgroup/cgroup_map.cpp
+++ b/libprocessgroup/cgroup_map.cpp
@@ -336,8 +336,10 @@
}
CgroupMap& CgroupMap::GetInstance() {
- static CgroupMap instance;
- return instance;
+ // Deliberately leak this object to avoid a race between destruction on
+ // process exit and concurrent access from another thread.
+ static auto* instance = new CgroupMap;
+ return *instance;
}
bool CgroupMap::LoadRcFile() {
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index f1fbcde..9362c03 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -284,8 +284,10 @@
}
TaskProfiles& TaskProfiles::GetInstance() {
- static TaskProfiles instance;
- return instance;
+ // Deliberately leak this object to avoid a race between destruction on
+ // process exit and concurrent access from another thread.
+ static auto* instance = new TaskProfiles;
+ return *instance;
}
TaskProfiles::TaskProfiles() {
diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp
index b07853a..523584a 100644
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -26,7 +26,7 @@
#include <sysutils/FrameworkListener.h>
#include <sysutils/SocketClient.h>
-static const int CMD_BUF_SIZE = 1024;
+static const int CMD_BUF_SIZE = 4096;
FrameworkListener::FrameworkListener(const char *socketName, bool withSeq) :
SocketListener(socketName, true, withSeq) {
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index a1c58dd..3f2e1c1 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -284,17 +284,9 @@
}
}
-std::string Unwinder::FormatFrame(size_t frame_num) {
- if (frame_num >= frames_.size()) {
- return "";
- }
- return FormatFrame(frames_[frame_num], regs_->Is32Bit());
-}
-
-std::string Unwinder::FormatFrame(const FrameData& frame, bool is32bit) {
+std::string Unwinder::FormatFrame(const FrameData& frame) {
std::string data;
-
- if (is32bit) {
+ if (regs_->Is32Bit()) {
data += android::base::StringPrintf(" #%02zu pc %08" PRIx64, frame.num, frame.rel_pc);
} else {
data += android::base::StringPrintf(" #%02zu pc %016" PRIx64, frame.num, frame.rel_pc);
@@ -320,9 +312,24 @@
}
data += ')';
}
+
+ MapInfo* map_info = maps_->Find(frame.map_start);
+ if (map_info != nullptr && display_build_id_) {
+ std::string build_id = map_info->GetPrintableBuildID();
+ if (!build_id.empty()) {
+ data += " (BuildId: " + build_id + ')';
+ }
+ }
return data;
}
+std::string Unwinder::FormatFrame(size_t frame_num) {
+ if (frame_num >= frames_.size()) {
+ return "";
+ }
+ return FormatFrame(frames_[frame_num]);
+}
+
void Unwinder::SetJitDebug(JitDebug* jit_debug, ArchEnum arch) {
jit_debug->SetArch(arch);
jit_debug_ = jit_debug;
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h
index a0554e2..8b01654 100644
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -88,7 +88,7 @@
}
std::string FormatFrame(size_t frame_num);
- static std::string FormatFrame(const FrameData& frame, bool is32bit);
+ std::string FormatFrame(const FrameData& frame);
void SetJitDebug(JitDebug* jit_debug, ArchEnum arch);
@@ -105,6 +105,8 @@
// NOTE: This does nothing unless resolving names is enabled.
void SetEmbeddedSoname(bool embedded_soname) { embedded_soname_ = embedded_soname; }
+ void SetDisplayBuildID(bool display_build_id) { display_build_id_ = display_build_id; }
+
#if !defined(NO_LIBDEXFILE_SUPPORT)
void SetDexFiles(DexFiles* dex_files, ArchEnum arch);
#endif
@@ -130,6 +132,7 @@
#endif
bool resolve_names_ = true;
bool embedded_soname_ = true;
+ bool display_build_id_ = false;
ErrorData last_error_;
};
diff --git a/libunwindstack/tests/RegsFake.h b/libunwindstack/tests/RegsFake.h
index d6ca9b7..207d46e 100644
--- a/libunwindstack/tests/RegsFake.h
+++ b/libunwindstack/tests/RegsFake.h
@@ -23,6 +23,8 @@
#include <unwindstack/Memory.h>
#include <unwindstack/Regs.h>
+#include "Check.h"
+
namespace unwindstack {
class RegsFake : public Regs {
@@ -47,7 +49,10 @@
void IterateRegisters(std::function<void(const char*, uint64_t)>) override {}
- bool Is32Bit() { return false; }
+ bool Is32Bit() {
+ CHECK(fake_arch_ != ARCH_UNKNOWN);
+ return fake_arch_ == ARCH_ARM || fake_arch_ == ARCH_X86 || fake_arch_ == ARCH_MIPS;
+ }
uint64_t GetPcAdjustment(uint64_t, Elf*) override { return 2; }
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp
index 504b57a..48e038e 100644
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -58,7 +58,9 @@
maps_.reset(new Maps);
ElfFake* elf = new ElfFake(new MemoryFake);
- elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
+ ElfInterfaceFake* interface_fake = new ElfInterfaceFake(nullptr);
+ interface_fake->FakeSetBuildID("FAKE");
+ elf->FakeSetInterface(interface_fake);
AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
@@ -1102,7 +1104,15 @@
}
// Verify format frame code.
-TEST_F(UnwinderTest, format_frame_static) {
+TEST_F(UnwinderTest, format_frame) {
+ RegsFake regs_arm(10);
+ regs_arm.FakeSetArch(ARCH_ARM);
+ Unwinder unwinder32(10, maps_.get(), ®s_arm, process_memory_);
+
+ RegsFake regs_arm64(10);
+ regs_arm64.FakeSetArch(ARCH_ARM64);
+ Unwinder unwinder64(10, maps_.get(), ®s_arm64, process_memory_);
+
FrameData frame;
frame.num = 1;
frame.rel_pc = 0x1000;
@@ -1117,39 +1127,61 @@
frame.map_flags = PROT_READ;
EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
- Unwinder::FormatFrame(frame, false));
+ unwinder64.FormatFrame(frame));
EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
- Unwinder::FormatFrame(frame, true));
+ unwinder32.FormatFrame(frame));
frame.map_elf_start_offset = 0;
EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
- Unwinder::FormatFrame(frame, false));
- EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)",
- Unwinder::FormatFrame(frame, true));
+ unwinder64.FormatFrame(frame));
+ EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder32.FormatFrame(frame));
frame.function_offset = 0;
EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
- Unwinder::FormatFrame(frame, false));
- EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", Unwinder::FormatFrame(frame, true));
+ unwinder64.FormatFrame(frame));
+ EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", unwinder32.FormatFrame(frame));
// Verify the function name is demangled.
frame.function_name = "_ZN4funcEv";
- EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())",
- Unwinder::FormatFrame(frame, false));
- EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", Unwinder::FormatFrame(frame, true));
+ EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())", unwinder64.FormatFrame(frame));
+ EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", unwinder32.FormatFrame(frame));
frame.function_name = "";
- EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", Unwinder::FormatFrame(frame, false));
- EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", Unwinder::FormatFrame(frame, true));
+ EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", unwinder64.FormatFrame(frame));
+ EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", unwinder32.FormatFrame(frame));
frame.map_name = "";
- EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", Unwinder::FormatFrame(frame, false));
- EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", Unwinder::FormatFrame(frame, true));
+ EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", unwinder64.FormatFrame(frame));
+ EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", unwinder32.FormatFrame(frame));
frame.map_start = 0;
frame.map_end = 0;
- EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", Unwinder::FormatFrame(frame, false));
- EXPECT_EQ(" #01 pc 00001000 <unknown>", Unwinder::FormatFrame(frame, true));
+ EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", unwinder64.FormatFrame(frame));
+ EXPECT_EQ(" #01 pc 00001000 <unknown>", unwinder32.FormatFrame(frame));
+}
+
+TEST_F(UnwinderTest, format_frame_build_id) {
+ RegsFake regs(10);
+ regs.FakeSetArch(ARCH_ARM);
+ Unwinder unwinder(10, maps_.get(), ®s, process_memory_);
+
+ FrameData frame;
+ frame.num = 1;
+ frame.rel_pc = 0x1000;
+ frame.pc = 0x4000;
+ frame.sp = 0x1000;
+ frame.function_name = "function";
+ frame.function_offset = 100;
+ frame.map_name = "/fake/libfake.so";
+ frame.map_elf_start_offset = 0;
+ frame.map_start = 0x3000;
+ frame.map_end = 0x6000;
+ frame.map_flags = PROT_READ;
+
+ EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder.FormatFrame(frame));
+ unwinder.SetDisplayBuildID(true);
+ EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100) (BuildId: 46414b45)",
+ unwinder.FormatFrame(frame));
}
static std::string ArchToString(ArchEnum arch) {
@@ -1167,7 +1199,7 @@
}
// Verify format frame code.
-TEST_F(UnwinderTest, format_frame) {
+TEST_F(UnwinderTest, format_frame_by_arch) {
std::vector<Regs*> reg_list;
RegsArm* arm = new RegsArm;
arm->set_pc(0x2300);
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index 9538bba..bc1543b 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -38,6 +38,19 @@
],
},
},
+ sanitize: {
+ misc_undefined: [
+ "signed-integer-overflow",
+ "unsigned-integer-overflow",
+ "shift",
+ "integer-divide-by-zero",
+ "implicit-signed-integer-truncation",
+ // TODO: Fix crash when we enable this option
+ // "implicit-unsigned-integer-truncation",
+ // TODO: not tested yet.
+ // "implicit-integer-sign-change",
+ ],
+ },
}
cc_defaults {
diff --git a/libziparchive/entry_name_utils-inl.h b/libziparchive/entry_name_utils-inl.h
index 5fc2fb4..1714586 100644
--- a/libziparchive/entry_name_utils-inl.h
+++ b/libziparchive/entry_name_utils-inl.h
@@ -35,7 +35,7 @@
return false;
} else {
// 2-5 byte sequences.
- for (uint8_t first = byte << 1; first & 0x80; first <<= 1) {
+ for (uint8_t first = (byte & 0x7f) << 1; first & 0x80; first = (first & 0x7f) << 1) {
++i;
// Missing continuation byte..
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 6b9f6e1..0710d0a 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -278,11 +278,6 @@
if (static_cast<off64_t>(eocd->cd_start_offset) + eocd->cd_size > eocd_offset) {
ALOGW("Zip: bad offsets (dir %" PRIu32 ", size %" PRIu32 ", eocd %" PRId64 ")",
eocd->cd_start_offset, eocd->cd_size, static_cast<int64_t>(eocd_offset));
-#if defined(__ANDROID__)
- if (eocd->cd_start_offset + eocd->cd_size <= eocd_offset) {
- android_errorWriteLog(0x534e4554, "31251826");
- }
-#endif
return kInvalidOffset;
}
if (eocd->num_records == 0) {
diff --git a/lmkd/event.logtags b/lmkd/event.logtags
index 7c2cd18..065c6db 100644
--- a/lmkd/event.logtags
+++ b/lmkd/event.logtags
@@ -35,4 +35,4 @@
# TODO: generate ".java" and ".h" files with integer constants from this file.
# for meminfo logs
-10195355 meminfo (MemFree|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(ION_heap|1),(ION_heap_pool|1),(CmaFree|1)
+10195355 meminfo (MemFree|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(SwapTotal|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(ION_heap|1),(ION_heap_pool|1),(CmaFree|1)
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 2d3fbfc..2de7378 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -110,7 +110,7 @@
*/
#define PSI_WINDOW_SIZE_MS 1000
/* Polling period after initial PSI signal */
-#define PSI_POLL_PERIOD_MS 40
+#define PSI_POLL_PERIOD_MS 10
/* Poll for the duration of one window after initial PSI signal */
#define PSI_POLL_COUNT (PSI_WINDOW_SIZE_MS / PSI_POLL_PERIOD_MS)
diff --git a/logcat/event.logtags b/logcat/event.logtags
index da8d2d4..3a1d36f 100644
--- a/logcat/event.logtags
+++ b/logcat/event.logtags
@@ -116,8 +116,8 @@
# audio
# 61000 - 61199 reserved for audioserver
-# 0 for screen off, 1 for screen on, 2 for key-guard done
-70000 screen_toggled (screen_state|1|5)
+# com.android.server.policy
+# 70000 - 70199 reserved for PhoneWindowManager and other policies
# aggregation service
70200 aggregation (aggregation time|2|3)
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index d5c40be..b32b437 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -33,6 +33,7 @@
#include <android-base/file.h>
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <gtest/gtest.h>
#include <log/event_tag_map.h>
#include <log/log.h>
@@ -1747,3 +1748,13 @@
EXPECT_EQ(logcatHelpTextSize * 2, logcatLastHelpTextSize);
#endif
}
+
+TEST(logcat, invalid_buffer) {
+ FILE* fp = popen("logcat -b foo 2>&1", "r");
+ ASSERT_NE(nullptr, fp);
+ std::string output;
+ ASSERT_TRUE(android::base::ReadFdToString(fileno(fp), &output));
+ pclose(fp);
+
+ ASSERT_TRUE(android::base::StartsWith(output, "unknown buffer foo\n"));
+}
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 54b019e..f78a926 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -8,6 +8,7 @@
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+LOCAL_REQUIRED_MODULES := fsverity_init
# The init symlink must be a post install command of a file that is to TARGET_ROOT_OUT.
# Since init.rc is required for init and satisfies that requirement, we hijack it to create the symlink.
@@ -57,6 +58,15 @@
endif
#######################################
+# fsverity_init
+
+include $(CLEAR_VARS)
+LOCAL_MODULE:= fsverity_init
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_SRC_FILES := fsverity_init.sh
+include $(BUILD_PREBUILT)
+
+#######################################
# init.environ.rc
include $(CLEAR_VARS)
diff --git a/rootdir/etc/ld.config.legacy.txt b/rootdir/etc/ld.config.legacy.txt
index fa46334..c23ee95 100644
--- a/rootdir/etc/ld.config.legacy.txt
+++ b/rootdir/etc/ld.config.legacy.txt
@@ -54,8 +54,7 @@
# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
# libart.
namespace.default.visible = true
-namespace.default.link.runtime.shared_libs = libart.so:libartd.so
-namespace.default.link.runtime.shared_libs += libdexfile_external.so
+namespace.default.link.runtime.shared_libs = libdexfile_external.so
namespace.default.link.runtime.shared_libs += libnativebridge.so
namespace.default.link.runtime.shared_libs += libnativehelper.so
namespace.default.link.runtime.shared_libs += libnativeloader.so
@@ -127,7 +126,7 @@
namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.links = runtime,default
-namespace.conscrypt.link.runtime.shared_libs = libjavacore.so
+namespace.conscrypt.link.runtime.shared_libs = libandroidio.so
namespace.conscrypt.link.default.shared_libs = libc.so
namespace.conscrypt.link.default.shared_libs += libm.so
namespace.conscrypt.link.default.shared_libs += libdl.so
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 641a536..6034f03 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -133,8 +133,7 @@
# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
# libart.
namespace.default.visible = true
-namespace.default.link.runtime.shared_libs = libart.so:libartd.so
-namespace.default.link.runtime.shared_libs += libdexfile_external.so
+namespace.default.link.runtime.shared_libs = libdexfile_external.so
namespace.default.link.runtime.shared_libs += libnativebridge.so
namespace.default.link.runtime.shared_libs += libnativehelper.so
namespace.default.link.runtime.shared_libs += libnativeloader.so
@@ -196,7 +195,7 @@
namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.links = runtime,default
-namespace.conscrypt.link.runtime.shared_libs = libjavacore.so
+namespace.conscrypt.link.runtime.shared_libs = libandroidio.so
namespace.conscrypt.link.default.shared_libs = libc.so
namespace.conscrypt.link.default.shared_libs += libm.so
namespace.conscrypt.link.default.shared_libs += libdl.so
@@ -377,7 +376,7 @@
# (LL-NDK only) access.
###############################################################################
[vendor]
-additional.namespaces = runtime,system,vndk
+additional.namespaces = runtime,system,vndk%VNDK_IN_SYSTEM_NS%
###############################################################################
# "default" namespace
@@ -418,8 +417,9 @@
namespace.default.asan.permitted.paths += /data/asan/vendor
namespace.default.asan.permitted.paths += /vendor
-namespace.default.links = system,vndk
+namespace.default.links = system,vndk%VNDK_IN_SYSTEM_NS%
namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%
+namespace.default.link.vndk_in_system.shared_libs = %VNDK_USING_CORE_VARIANT_LIBRARIES%
namespace.default.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES%
namespace.default.link.vndk.shared_libs += %VNDK_CORE_LIBRARIES%
@@ -468,14 +468,18 @@
# When these NDK libs are required inside this namespace, then it is redirected
# to the system namespace. This is possible since their ABI is stable across
-# Android releases.
-namespace.vndk.links = system,default
+# Android releases. The links here should be identical to that of the
+# 'vndk_in_system' namespace, except for the link between 'vndk' and
+# 'vndk_in_system'.
+namespace.vndk.links = system,default%VNDK_IN_SYSTEM_NS%
namespace.vndk.link.system.shared_libs = %LLNDK_LIBRARIES%
namespace.vndk.link.system.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
namespace.vndk.link.default.allow_all_shared_libs = true
+namespace.vndk.link.vndk_in_system.shared_libs = %VNDK_USING_CORE_VARIANT_LIBRARIES%
+
###############################################################################
# "system" namespace
#
@@ -504,6 +508,51 @@
namespace.system.link.runtime.shared_libs += libandroidicu.so
###############################################################################
+# "vndk_in_system" namespace
+#
+# This namespace is where no-vendor-variant VNDK libraries are loaded for a
+# vendor process. Note that we do not simply export these libraries from
+# "system" namespace, because in some case both the core variant and the
+# vendor variant of a VNDK library may be loaded. In such case, we do not
+# want to eliminate double-loading because doing so means the global states
+# of the library would be shared.
+#
+# Only the no-vendor-variant VNDK libraries are whitelisted in this namespace.
+# This is to ensure that we do not load libraries needed by no-vendor-variant
+# VNDK libraries into vndk_in_system namespace.
+###############################################################################
+namespace.vndk_in_system.isolated = true
+namespace.vndk_in_system.visible = true
+
+# The search paths here should be kept the same as that of the 'system'
+# namespace.
+namespace.vndk_in_system.search.paths = /system/${LIB}
+namespace.vndk_in_system.search.paths += /%PRODUCT%/${LIB}
+namespace.vndk_in_system.search.paths += /%PRODUCT_SERVICES%/${LIB}
+
+namespace.vndk_in_system.asan.search.paths = /data/asan/system/${LIB}
+namespace.vndk_in_system.asan.search.paths += /system/${LIB}
+namespace.vndk_in_system.asan.search.paths += /data/asan/product/${LIB}
+namespace.vndk_in_system.asan.search.paths += /%PRODUCT%/${LIB}
+namespace.vndk_in_system.asan.search.paths += /data/asan/product_services/${LIB}
+namespace.vndk_in_system.asan.search.paths += /%PRODUCT_SERVICES%/${LIB}
+
+namespace.vndk_in_system.whitelisted = %VNDK_USING_CORE_VARIANT_LIBRARIES%
+
+# The links here should be identical to that of the 'vndk' namespace, with the
+# following exception:
+# 1. 'vndk_in_system' needs to be freely linked back to 'vndk'.
+# 2. 'vndk_in_system' does not need to link to 'default', as any library that
+# requires anything vendor would not be a vndk_in_system library.
+namespace.vndk_in_system.links = vndk,system
+
+namespace.vndk_in_system.link.system.shared_libs = %LLNDK_LIBRARIES%
+namespace.vndk_in_system.link.system.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
+
+namespace.vndk_in_system.link.vndk.allow_all_shared_libs = true
+
+
+###############################################################################
# Namespace config for native tests that need access to both system and vendor
# libraries. This replicates the default linker config (done by
# init_default_namespace_no_config in bionic/linker/linker.cpp), except that it
@@ -527,8 +576,7 @@
namespace.default.links = runtime,resolv
namespace.default.visible = true
-namespace.default.link.runtime.shared_libs = libart.so:libartd.so
-namespace.default.link.runtime.shared_libs += libdexfile_external.so
+namespace.default.link.runtime.shared_libs = libdexfile_external.so
namespace.default.link.runtime.shared_libs += libnativebridge.so
namespace.default.link.runtime.shared_libs += libnativehelper.so
namespace.default.link.runtime.shared_libs += libnativeloader.so
@@ -587,7 +635,7 @@
namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.links = runtime,default
-namespace.conscrypt.link.runtime.shared_libs = libjavacore.so
+namespace.conscrypt.link.runtime.shared_libs = libandroidio.so
namespace.conscrypt.link.default.shared_libs = libc.so
namespace.conscrypt.link.default.shared_libs += libm.so
namespace.conscrypt.link.default.shared_libs += libdl.so
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index beb6125..d769c34 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -74,8 +74,7 @@
# Visible because some libraries are dlopen'ed, e.g. libopenjdk is dlopen'ed by
# libart.
namespace.default.visible = true
-namespace.default.link.runtime.shared_libs = libart.so:libartd.so
-namespace.default.link.runtime.shared_libs += libdexfile_external.so
+namespace.default.link.runtime.shared_libs = libdexfile_external.so
namespace.default.link.runtime.shared_libs += libnativebridge.so
namespace.default.link.runtime.shared_libs += libnativehelper.so
namespace.default.link.runtime.shared_libs += libnativeloader.so
@@ -138,7 +137,7 @@
namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.links = runtime,default
-namespace.conscrypt.link.runtime.shared_libs = libjavacore.so
+namespace.conscrypt.link.runtime.shared_libs = libandroidio.so
namespace.conscrypt.link.default.shared_libs = libc.so
namespace.conscrypt.link.default.shared_libs += libm.so
namespace.conscrypt.link.default.shared_libs += libdl.so
@@ -400,8 +399,7 @@
namespace.default.links = runtime,resolv
namespace.default.visible = true
-namespace.default.link.runtime.shared_libs = libart.so:libartd.so
-namespace.default.link.runtime.shared_libs += libdexfile_external.so
+namespace.default.link.runtime.shared_libs = libdexfile_external.so
namespace.default.link.runtime.shared_libs += libnativebridge.so
namespace.default.link.runtime.shared_libs += libnativehelper.so
namespace.default.link.runtime.shared_libs += libnativeloader.so
@@ -460,7 +458,7 @@
namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
namespace.conscrypt.links = runtime,default
-namespace.conscrypt.link.runtime.shared_libs = libjavacore.so
+namespace.conscrypt.link.runtime.shared_libs = libandroidio.so
namespace.conscrypt.link.default.shared_libs = libc.so
namespace.conscrypt.link.default.shared_libs += libm.so
namespace.conscrypt.link.default.shared_libs += libdl.so
diff --git a/rootdir/fsverity_init.sh b/rootdir/fsverity_init.sh
new file mode 100644
index 0000000..29e4519
--- /dev/null
+++ b/rootdir/fsverity_init.sh
@@ -0,0 +1,29 @@
+#!/system/bin/sh
+#
+# Copyright (C) 2019 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.
+#
+
+# Enforce fsverity signature checking
+echo 1 > /proc/sys/fs/verity/require_signatures
+
+# Load all keys
+for cert in /product/etc/security/fsverity/*.der; do
+ /system/bin/mini-keyctl padd asymmetric fsv_product .fs-verity < "$cert" ||
+ log -p e -t fsverity_init "Failed to load $cert"
+done
+
+# Prevent future key links to .fs-verity keyring
+/system/bin/mini-keyctl restrict_keyring .fs-verity ||
+ log -p e -t fsverity_init "Failed to restrict .fs-verity keyring"
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 8e63a81..fec1e68 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -420,12 +420,7 @@
# Load fsverity keys. This needs to happen before apexd, as post-install of
# APEXes may rely on keys.
- exec -- /system/bin/mini-keyctl dadd asymmetric product_cert /product/etc/security/cacerts_fsverity .fs-verity
- exec -- /system/bin/mini-keyctl dadd asymmetric vendor_cert /vendor/etc/security/cacerts_fsverity .fs-verity
- # Prevent future key links to fsverity keyring
- exec -- /system/bin/mini-keyctl restrict_keyring .fs-verity
- # Enforce fsverity signature checking
- write /proc/sys/fs/verity/require_signatures 1
+ exec -- /system/bin/fsverity_init
# Make sure that apexd is started in the default namespace
enter_default_mount_ns
diff --git a/rootdir/update_and_install_ld_config.mk b/rootdir/update_and_install_ld_config.mk
index 852e234..f62c3df 100644
--- a/rootdir/update_and_install_ld_config.mk
+++ b/rootdir/update_and_install_ld_config.mk
@@ -23,6 +23,11 @@
lib_list_from_prebuilts := $(strip $(lib_list_from_prebuilts))
libz_is_llndk := $(strip $(libz_is_llndk))
+my_vndk_use_core_variant := $(TARGET_VNDK_USE_CORE_VARIANT)
+ifeq ($(lib_list_from_prebuilts),true)
+my_vndk_use_core_variant := false
+endif
+
compatibility_check_script := \
$(LOCAL_PATH)/ld_config_backward_compatibility_check.py
intermediates_dir := $(call intermediates-dir-for,ETC,$(LOCAL_MODULE))
@@ -35,6 +40,9 @@
vndksp_libraries_file := $(library_lists_dir)/vndksp.libraries.$(vndk_version).txt
vndkcore_libraries_file := $(library_lists_dir)/vndkcore.libraries.txt
vndkprivate_libraries_file := $(library_lists_dir)/vndkprivate.libraries.txt
+ifeq ($(my_vndk_use_core_variant),true)
+vndk_using_core_variant_libraries_file := $(library_lists_dir)/vndk_using_core_variant.libraries.$(vndk_version).txt
+endif
sanitizer_runtime_libraries := $(call normalize-path-list,$(addsuffix .so,\
$(ADDRESS_SANITIZER_RUNTIME_LIBRARY) \
@@ -68,6 +76,9 @@
$(eval $(call write-libs-to-file,$(vndksp_libraries_list),$(vndksp_libraries_file)))
$(eval $(call write-libs-to-file,$(VNDK_CORE_LIBRARIES),$(vndkcore_libraries_file)))
$(eval $(call write-libs-to-file,$(VNDK_PRIVATE_LIBRARIES),$(vndkprivate_libraries_file)))
+ifeq ($(my_vndk_use_core_variant),true)
+$(eval $(call write-libs-to-file,$(VNDK_USING_CORE_VARIANT_LIBRARIES),$(vndk_using_core_variant_libraries_file)))
+endif
endif # ifneq ($(lib_list_from_prebuilts),true)
# Given a file with a list of libs, filter-out the VNDK private libraries
@@ -94,6 +105,10 @@
ifeq ($(check_backward_compatibility),true)
deps += $(compatibility_check_script)
endif
+ifeq ($(my_vndk_use_core_variant),true)
+$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_USING_CORE_VARIANT_LIBRARIES_FILE := $(vndk_using_core_variant_libraries_file)
+deps += $(vndk_using_core_variant_libraries_file)
+endif
$(LOCAL_BUILT_MODULE): $(ld_config_template) $(deps)
@echo "Generate: $< -> $@"
@@ -109,6 +124,20 @@
$(call private-filter-out-private-libs,$(PRIVATE_VNDK_CORE_LIBRARIES_FILE),$(PRIVATE_INTERMEDIATES_DIR)/vndkcore_filtered)
$(hide) sed -i.bak -e "s?%VNDK_CORE_LIBRARIES%?$$(cat $(PRIVATE_INTERMEDIATES_DIR)/vndkcore_filtered)?g" $@
+ifeq ($(my_vndk_use_core_variant),true)
+ $(call private-filter-out-private-libs,$(PRIVATE_VNDK_USING_CORE_VARIANT_LIBRARIES_FILE),$(PRIVATE_INTERMEDIATES_DIR)/vndk_using_core_variant_filtered)
+ $(hide) sed -i.bak -e "s?%VNDK_IN_SYSTEM_NS%?,vndk_in_system?g" $@
+ $(hide) sed -i.bak -e "s?%VNDK_USING_CORE_VARIANT_LIBRARIES%?$$(cat $(PRIVATE_INTERMEDIATES_DIR)/vndk_using_core_variant_filtered)?g" $@
+else
+ $(hide) sed -i.bak -e "s?%VNDK_IN_SYSTEM_NS%??g" $@
+ # Unlike LLNDK or VNDK-SP, VNDK_USING_CORE_VARIANT_LIBRARIES can be nothing
+ # if TARGET_VNDK_USE_CORE_VARIANT is not set. In this case, we need to remove
+ # the entire line in the linker config so that we are not left with a line
+ # like:
+ # namespace.vndk.link.vndk_in_system.shared_libs =
+ $(hide) sed -i.bak -e 's?^.*= %VNDK_USING_CORE_VARIANT_LIBRARIES%$$??' $@
+endif
+
$(hide) echo -n > $(PRIVATE_INTERMEDIATES_DIR)/private_llndk && \
cat $(PRIVATE_VNDK_PRIVATE_LIBRARIES_FILE) | \
xargs -n 1 -I privatelib bash -c "(grep privatelib $(PRIVATE_LLNDK_LIBRARIES_FILE) || true) >> $(PRIVATE_INTERMEDIATES_DIR)/private_llndk" && \
@@ -146,3 +175,10 @@
llndk_libraries_list :=
vndksp_libraries_list :=
write-libs-to-file :=
+
+ifeq ($(my_vndk_use_core_variant),true)
+vndk_using_core_variant_libraries_file :=
+vndk_using_core_variant_libraries_list :=
+endif
+
+my_vndk_use_core_variant :=