Merge "fastboot: Flash boot partitions before rebooting to fastbootd."
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index dfb7a6a..e2ea480 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -29,6 +29,7 @@
#include <regex>
#include <thread>
+#include <android/fdsan.h>
#include <android/set_abort_message.h>
#include <android-base/file.h>
@@ -801,6 +802,31 @@
AssertDeath(SIGABRT);
}
+TEST_F(CrasherTest, fdsan_warning_abort_message) {
+ int intercept_result;
+ unique_fd output_fd;
+
+ StartProcess([]() {
+ android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
+ unique_fd fd(open("/dev/null", O_RDONLY | O_CLOEXEC));
+ if (fd == -1) {
+ abort();
+ }
+ close(fd.get());
+ _exit(0);
+ });
+
+ StartIntercept(&output_fd);
+ FinishCrasher();
+ AssertDeath(0);
+ FinishIntercept(&intercept_result);
+ ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
+
+ std::string result;
+ ConsumeFd(std::move(output_fd), &result);
+ ASSERT_MATCH(result, "Abort message: 'attempted to close");
+}
+
TEST(crash_dump, zombie) {
pid_t forkpid = fork();
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index 91e6f71..15557b6 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -457,14 +457,14 @@
info = nullptr;
}
- struct siginfo si = {};
+ struct siginfo dummy_info = {};
if (!info) {
- memset(&si, 0, sizeof(si));
- si.si_signo = signal_number;
- si.si_code = SI_USER;
- si.si_pid = __getpid();
- si.si_uid = getuid();
- info = &si;
+ memset(&dummy_info, 0, sizeof(dummy_info));
+ dummy_info.si_signo = signal_number;
+ dummy_info.si_code = SI_USER;
+ dummy_info.si_pid = __getpid();
+ dummy_info.si_uid = getuid();
+ info = &dummy_info;
} else if (info->si_code >= 0 || info->si_code == SI_TKILL) {
// rt_tgsigqueueinfo(2)'s documentation appears to be incorrect on kernels
// that contain commit 66dd34a (3.9+). The manpage claims to only allow
@@ -473,8 +473,18 @@
}
void* abort_message = nullptr;
- if (signal_number != DEBUGGER_SIGNAL && g_callbacks.get_abort_message) {
- abort_message = g_callbacks.get_abort_message();
+ if (signal_number == DEBUGGER_SIGNAL) {
+ if (info->si_code == SI_QUEUE && info->si_pid == __getpid()) {
+ // Allow for the abort message to be explicitly specified via the sigqueue value.
+ // Keep the bottom bit intact for representing whether we want a backtrace or a tombstone.
+ uintptr_t value = reinterpret_cast<uintptr_t>(info->si_ptr);
+ abort_message = reinterpret_cast<void*>(value & ~1);
+ info->si_ptr = reinterpret_cast<void*>(value & 1);
+ }
+ } else {
+ if (g_callbacks.get_abort_message) {
+ abort_message = g_callbacks.get_abort_message();
+ }
}
// If sival_int is ~0, it means that the fallback handler has been called
diff --git a/debuggerd/libdebuggerd/open_files_list.cpp b/debuggerd/libdebuggerd/open_files_list.cpp
index 03e4e8e..743a2e7 100644
--- a/debuggerd/libdebuggerd/open_files_list.cpp
+++ b/debuggerd/libdebuggerd/open_files_list.cpp
@@ -18,6 +18,7 @@
#include "libdebuggerd/open_files_list.h"
+#include <android/fdsan.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
@@ -122,8 +123,10 @@
const std::optional<std::string>& path = entry.path;
const std::optional<uint64_t>& fdsan_owner = entry.fdsan_owner;
if (path && fdsan_owner) {
- _LOG(log, logtype::OPEN_FILES, "%sfd %i: %s (owned by %#" PRIx64 ")\n", prefix, fd,
- path->c_str(), *fdsan_owner);
+ const char* type = android_fdsan_get_tag_type(*fdsan_owner);
+ uint64_t value = android_fdsan_get_tag_value(*fdsan_owner);
+ _LOG(log, logtype::OPEN_FILES, "%sfd %i: %s (owned by %s %#" PRIx64 ")\n", prefix, fd,
+ path->c_str(), type, value);
} else if (path && !fdsan_owner) {
_LOG(log, logtype::OPEN_FILES, "%sfd %i: %s (unowned)\n", prefix, fd, path->c_str());
} else if (!path && fdsan_owner) {
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index fb57715..720dcfd 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -141,14 +141,13 @@
constexpr char upperdir_option[] = "upperdir=";
// default options for mount_point, returns empty string for none available.
-std::string fs_mgr_get_overlayfs_options(const char* mount_point) {
- auto fsrec_mount_point = std::string(mount_point);
- auto candidate = fs_mgr_get_overlayfs_candidate(fsrec_mount_point);
+std::string fs_mgr_get_overlayfs_options(const std::string& mount_point) {
+ auto candidate = fs_mgr_get_overlayfs_candidate(mount_point);
if (candidate.empty()) return "";
- auto context = fs_mgr_get_context(fsrec_mount_point);
+ auto context = fs_mgr_get_context(mount_point);
if (!context.empty()) context = ",rootcontext="s + context;
- return "override_creds=off,"s + lowerdir_option + fsrec_mount_point + "," + upperdir_option +
+ return "override_creds=off,"s + lowerdir_option + mount_point + "," + upperdir_option +
candidate + upper_name + ",workdir=" + candidate + work_name + context;
}
@@ -167,10 +166,11 @@
return true;
}
-std::string fs_mgr_get_overlayfs_options(const fstab* fstab, const char* mount_point) {
- if (fs_mgr_system_root_image(fstab) && ("/"s == mount_point)) mount_point = "/system";
-
- return fs_mgr_get_overlayfs_options(mount_point);
+const char* fs_mgr_mount_point(const fstab* fstab, const char* mount_point) {
+ if (!mount_point) return mount_point;
+ if ("/"s != mount_point) return mount_point;
+ if (!fs_mgr_system_root_image(fstab)) return mount_point;
+ return "/system";
}
// return true if system supports overlayfs
@@ -196,7 +196,7 @@
if (!fsrec) return false;
auto fsrec_mount_point = fsrec->mount_point;
- if (!fsrec_mount_point) return false;
+ if (!fsrec_mount_point || !fsrec_mount_point[0]) return false;
if (!fsrec->blk_device) return false;
if (!fsrec->fs_type) return false;
@@ -265,10 +265,17 @@
return ret;
}
+constexpr char overlayfs_file_context[] = "u:object_r:overlayfs_file:s0";
+
bool fs_mgr_overlayfs_setup_one(const std::string& overlay, const std::string& mount_point,
bool* change) {
auto ret = true;
auto fsrec_mount_point = overlay + android::base::Basename(mount_point) + "/";
+
+ if (setfscreatecon(overlayfs_file_context)) {
+ ret = false;
+ PERROR << "overlayfs setfscreatecon " << overlayfs_file_context;
+ }
auto save_errno = errno;
if (!mkdir(fsrec_mount_point.c_str(), 0755)) {
if (change) *change = true;
@@ -288,6 +295,7 @@
} else {
errno = save_errno;
}
+ setfscreatecon(nullptr);
auto new_context = fs_mgr_get_context(mount_point);
if (!new_context.empty() && setfscreatecon(new_context.c_str())) {
@@ -309,15 +317,12 @@
return ret;
}
-bool fs_mgr_overlayfs_mount(const fstab* fstab, const fstab_rec* fsrec) {
- if (!fs_mgr_wants_overlayfs(fsrec)) return false;
- auto fsrec_mount_point = fsrec->mount_point;
- if (!fsrec_mount_point || !fsrec_mount_point[0]) return false;
- auto options = fs_mgr_get_overlayfs_options(fstab, fsrec_mount_point);
+bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
+ auto options = fs_mgr_get_overlayfs_options(mount_point);
if (options.empty()) return false;
// hijack __mount() report format to help triage
- auto report = "__mount(source=overlay,target="s + fsrec_mount_point + ",type=overlay";
+ auto report = "__mount(source=overlay,target="s + mount_point + ",type=overlay";
const auto opt_list = android::base::Split(options, ",");
for (const auto opt : opt_list) {
if (android::base::StartsWith(opt, upperdir_option)) {
@@ -327,7 +332,7 @@
}
report = report + ")=";
- auto ret = mount("overlay", fsrec_mount_point, "overlay", MS_RDONLY | MS_RELATIME,
+ auto ret = mount("overlay", mount_point.c_str(), "overlay", MS_RDONLY | MS_RELATIME,
options.c_str());
if (ret) {
PERROR << report << ret;
@@ -338,8 +343,7 @@
}
}
-bool fs_mgr_overlayfs_already_mounted(const char* mount_point) {
- if (!mount_point) return false;
+bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point) {
std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)> fstab(
fs_mgr_read_fstab("/proc/mounts"), fs_mgr_free_fstab);
if (!fstab) return false;
@@ -351,7 +355,7 @@
if (("overlay"s != fs_type) && ("overlayfs"s != fs_type)) continue;
auto fsrec_mount_point = fsrec->mount_point;
if (!fsrec_mount_point) continue;
- if (strcmp(fsrec_mount_point, mount_point)) continue;
+ if (mount_point != fsrec_mount_point) continue;
const auto fs_options = fsrec->fs_options;
if (!fs_options) continue;
const auto options = android::base::Split(fs_options, ",");
@@ -364,6 +368,34 @@
return false;
}
+std::vector<std::string> fs_mgr_candidate_list(const fstab* fstab,
+ const char* mount_point = nullptr) {
+ std::vector<std::string> mounts;
+ if (!fstab) return mounts;
+
+ for (auto i = 0; i < fstab->num_entries; i++) {
+ const auto fsrec = &fstab->recs[i];
+ if (!fs_mgr_wants_overlayfs(fsrec)) continue;
+ std::string new_mount_point(fs_mgr_mount_point(fstab, fsrec->mount_point));
+ if (mount_point && (new_mount_point != mount_point)) continue;
+ auto duplicate_or_more_specific = false;
+ for (auto it = mounts.begin(); it != mounts.end();) {
+ if ((*it == new_mount_point) ||
+ (android::base::StartsWith(new_mount_point, *it + "/"))) {
+ duplicate_or_more_specific = true;
+ break;
+ }
+ if (android::base::StartsWith(*it, new_mount_point + "/")) {
+ it = mounts.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ if (!duplicate_or_more_specific) mounts.emplace_back(new_mount_point);
+ }
+ return mounts;
+}
+
} // namespace
bool fs_mgr_overlayfs_mount_all() {
@@ -375,13 +407,9 @@
fs_mgr_free_fstab);
if (!fstab) return ret;
- for (auto i = 0; i < fstab->num_entries; i++) {
- const auto fsrec = &fstab->recs[i];
- auto fsrec_mount_point = fsrec->mount_point;
- if (!fsrec_mount_point) continue;
- if (fs_mgr_overlayfs_already_mounted(fsrec_mount_point)) continue;
-
- if (fs_mgr_overlayfs_mount(fstab.get(), fsrec)) ret = true;
+ for (const auto& mount_point : fs_mgr_candidate_list(fstab.get())) {
+ if (fs_mgr_overlayfs_already_mounted(mount_point)) continue;
+ if (fs_mgr_overlayfs_mount(mount_point)) ret = true;
}
return ret;
}
@@ -404,22 +432,12 @@
std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
fs_mgr_free_fstab);
- std::vector<std::string> mounts;
- if (fstab) {
- if (!fs_mgr_get_entry_for_mount_point(fstab.get(), kOverlayMountPoint)) return ret;
- for (auto i = 0; i < fstab->num_entries; i++) {
- const auto fsrec = &fstab->recs[i];
- auto fsrec_mount_point = fsrec->mount_point;
- if (!fsrec_mount_point) continue;
- if (mount_point && strcmp(fsrec_mount_point, mount_point)) continue;
- if (!fs_mgr_wants_overlayfs(fsrec)) continue;
- mounts.emplace_back(fsrec_mount_point);
- }
- if (mounts.empty()) return ret;
- }
+ if (fstab && !fs_mgr_get_entry_for_mount_point(fstab.get(), kOverlayMountPoint)) return ret;
+ auto mounts = fs_mgr_candidate_list(fstab.get(), fs_mgr_mount_point(fstab.get(), mount_point));
+ if (fstab && mounts.empty()) return ret;
- if (mount_point && ("/"s == mount_point) && fs_mgr_system_root_image(fstab.get())) {
- mount_point = "/system";
+ if (setfscreatecon(overlayfs_file_context)) {
+ PERROR << "overlayfs setfscreatecon " << overlayfs_file_context;
}
auto overlay = kOverlayMountPoint + "/overlay/";
auto save_errno = errno;
@@ -430,6 +448,7 @@
} else {
errno = save_errno;
}
+ setfscreatecon(nullptr);
if (!fstab && mount_point && fs_mgr_overlayfs_setup_one(overlay, mount_point, change)) {
ret = true;
}
@@ -443,11 +462,10 @@
// If something is altered, set *change.
bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
if (change) *change = false;
- if (mount_point && ("/"s == mount_point)) {
- std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)> fstab(
- fs_mgr_read_fstab_default(), fs_mgr_free_fstab);
- if (fs_mgr_system_root_image(fstab.get())) mount_point = "/system";
- }
+ mount_point = fs_mgr_mount_point(std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)>(
+ fs_mgr_read_fstab_default(), fs_mgr_free_fstab)
+ .get(),
+ mount_point);
auto ret = true;
const auto overlay = kOverlayMountPoint + "/overlay";
const auto oldpath = overlay + (mount_point ?: "");
diff --git a/libcutils/tests/sched_policy_test.cpp b/libcutils/tests/sched_policy_test.cpp
index 5942ee5..1f657e2 100644
--- a/libcutils/tests/sched_policy_test.cpp
+++ b/libcutils/tests/sched_policy_test.cpp
@@ -67,6 +67,21 @@
}
TEST(SchedPolicy, set_sched_policy) {
+ if (!schedboost_enabled()) {
+ // schedboost_enabled() (i.e. CONFIG_CGROUP_SCHEDTUNE) is optional;
+ // it's only needed on devices using energy-aware scheduler.
+ GTEST_LOG_(INFO) << "skipping test that requires CONFIG_CGROUP_SCHEDTUNE";
+ return;
+ }
+
+ ASSERT_EQ(0, set_sched_policy(0, SP_BACKGROUND));
+ AssertPolicy(SP_BACKGROUND);
+
+ ASSERT_EQ(0, set_sched_policy(0, SP_FOREGROUND));
+ AssertPolicy(SP_FOREGROUND);
+}
+
+TEST(SchedPolicy, set_sched_policy_timerslack) {
if (!hasCapSysNice()) {
GTEST_LOG_(INFO) << "skipping test that requires CAP_SYS_NICE";
return;
@@ -82,11 +97,9 @@
const unsigned int BG_FG_SLACK_FACTOR = 100;
ASSERT_EQ(0, set_sched_policy(0, SP_BACKGROUND));
- AssertPolicy(SP_BACKGROUND);
auto bgSleepTime = medianSleepTime();
ASSERT_EQ(0, set_sched_policy(0, SP_FOREGROUND));
- AssertPolicy(SP_FOREGROUND);
auto fgSleepTime = medianSleepTime();
ASSERT_GT(bgSleepTime, fgSleepTime * BG_FG_SLACK_FACTOR);
}
diff --git a/libutils/Android.bp b/libutils/Android.bp
index d635e65..1c1bdf7 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -58,7 +58,6 @@
"-Wall",
"-Werror",
],
- include_dirs: ["external/safe-iop/include"],
header_libs: [
"libutils_headers",
],
diff --git a/libutils/VectorImpl.cpp b/libutils/VectorImpl.cpp
index 00a904d..e16f88d 100644
--- a/libutils/VectorImpl.cpp
+++ b/libutils/VectorImpl.cpp
@@ -24,8 +24,6 @@
#include <log/log.h>
-#include <safe_iop.h>
-
#include "SharedBuffer.h"
/*****************************************************************************/
@@ -342,7 +340,7 @@
}
size_t new_allocation_size = 0;
- LOG_ALWAYS_FATAL_IF(!safe_mul(&new_allocation_size, new_capacity, mItemSize));
+ LOG_ALWAYS_FATAL_IF(__builtin_mul_overflow(new_capacity, mItemSize, &new_allocation_size));
SharedBuffer* sb = SharedBuffer::alloc(new_allocation_size);
if (sb) {
void* array = sb->data();
@@ -386,7 +384,7 @@
this, (int)where, (int)amount, (int)mCount); // caller already checked
size_t new_size;
- LOG_ALWAYS_FATAL_IF(!safe_add(&new_size, mCount, amount), "new_size overflow");
+ LOG_ALWAYS_FATAL_IF(__builtin_add_overflow(mCount, amount, &new_size), "new_size overflow");
if (capacity() < new_size) {
// NOTE: This implementation used to resize vectors as per ((3*x + 1) / 2)
@@ -397,17 +395,18 @@
//
// This approximates the old calculation, using (x + (x/2) + 1) instead.
size_t new_capacity = 0;
- LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_size, (new_size / 2)),
+ LOG_ALWAYS_FATAL_IF(__builtin_add_overflow(new_size, (new_size / 2), &new_capacity),
"new_capacity overflow");
- LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_capacity, static_cast<size_t>(1u)),
- "new_capacity overflow");
+ LOG_ALWAYS_FATAL_IF(
+ __builtin_add_overflow(new_capacity, static_cast<size_t>(1u), &new_capacity),
+ "new_capacity overflow");
new_capacity = max(kMinVectorCapacity, new_capacity);
size_t new_alloc_size = 0;
- LOG_ALWAYS_FATAL_IF(!safe_mul(&new_alloc_size, new_capacity, mItemSize),
+ LOG_ALWAYS_FATAL_IF(__builtin_mul_overflow(new_capacity, mItemSize, &new_alloc_size),
"new_alloc_size overflow");
-// ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
+ // ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
if ((mStorage) &&
(mCount==where) &&
(mFlags & HAS_TRIVIAL_COPY) &&
@@ -464,7 +463,7 @@
this, (int)where, (int)amount, (int)mCount); // caller already checked
size_t new_size;
- LOG_ALWAYS_FATAL_IF(!safe_sub(&new_size, mCount, amount));
+ LOG_ALWAYS_FATAL_IF(__builtin_sub_overflow(mCount, amount, &new_size));
if (new_size < (capacity() / 2)) {
// NOTE: (new_size * 2) is safe because capacity didn't overflow and
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 9536fc7..add6e14 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -41,6 +41,7 @@
#include <android-base/logging.h>
#include <android-base/macros.h> // TEMP_FAILURE_RETRY may or may not be in unistd
#include <android-base/memory.h>
+#include <android-base/utf8.h>
#include <log/log.h>
#include <utils/Compat.h>
#include <utils/FileMap.h>
@@ -471,7 +472,7 @@
}
int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle) {
- const int fd = open(fileName, O_RDONLY | O_BINARY, 0);
+ const int fd = ::android::base::utf8::open(fileName, O_RDONLY | O_BINARY, 0);
ZipArchive* archive = new ZipArchive(fd, true);
*handle = archive;
diff --git a/llkd/libllkd.cpp b/llkd/libllkd.cpp
index 48551f2..bb55d1f 100644
--- a/llkd/libllkd.cpp
+++ b/llkd/libllkd.cpp
@@ -738,6 +738,8 @@
}
void* llkThread(void* obj) {
+ prctl(PR_SET_DUMPABLE, 0);
+
LOG(INFO) << "started";
std::string name = std::to_string(::gettid());
diff --git a/llkd/llkd.cpp b/llkd/llkd.cpp
index f10253d..1920198 100644
--- a/llkd/llkd.cpp
+++ b/llkd/llkd.cpp
@@ -17,6 +17,7 @@
#include "llkd.h"
#include <sched.h>
+#include <sys/prctl.h>
#include <unistd.h>
#include <chrono>
@@ -26,6 +27,8 @@
using namespace std::chrono;
int main(int, char**) {
+ prctl(PR_SET_DUMPABLE, 0);
+
LOG(INFO) << "started";
bool enabled = llkInit();