Merge "adbd: reduce the USB buffer sizes to 16k."
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 82ba0a1..c608a8c 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -363,6 +363,12 @@
DefuseSignalHandlers();
InstallSigPipeHandler();
+ // 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
+ // avoid hitting this.
+ setsid();
+
atrace_begin(ATRACE_TAG, "before reparent");
pid_t target_process = getppid();
diff --git a/debuggerd/crasher/crasher.cpp b/debuggerd/crasher/crasher.cpp
index f0bdfbf..3041664 100644
--- a/debuggerd/crasher/crasher.cpp
+++ b/debuggerd/crasher/crasher.cpp
@@ -193,6 +193,7 @@
fprintf(stderr, " kuser_memory_barrier call kuser_memory_barrier\n");
fprintf(stderr, " kuser_cmpxchg64 call kuser_cmpxchg64\n");
#endif
+ fprintf(stderr, " xom read execute-only memory\n");
fprintf(stderr, "\n");
fprintf(stderr, " LOG_ALWAYS_FATAL call liblog LOG_ALWAYS_FATAL\n");
fprintf(stderr, " LOG_ALWAYS_FATAL_IF call liblog LOG_ALWAYS_FATAL_IF\n");
@@ -314,6 +315,11 @@
} else if (!strcasecmp(arg, "seccomp")) {
set_system_seccomp_filter();
syscall(99999);
+#if defined(__LP64__)
+ } else if (!strcasecmp(arg, "xom")) {
+ // Try to read part of our code, which will fail if XOM is active.
+ printf("*%lx = %lx\n", reinterpret_cast<long>(usage), *reinterpret_cast<long*>(usage));
+#endif
#if defined(__arm__)
} else if (!strcasecmp(arg, "kuser_helper_version")) {
return __kuser_helper_version;
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index bca5e36..598ea85 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -268,8 +268,15 @@
_exit(errno);
}
- // Exit immediately on both sides of the fork.
- // crash_dump is ptracing us, so it'll get to do whatever it wants in between.
+ // crash_dump is ptracing both sides of the fork; it'll let the parent exit,
+ // but keep the orphan stopped to peek at its memory.
+
+ // 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
+ // avoid hitting this.
+ setsid();
+
_exit(0);
}
diff --git a/fastboot/device/usb_client.cpp b/fastboot/device/usb_client.cpp
index fb51a90..511bd5c 100644
--- a/fastboot/device/usb_client.cpp
+++ b/fastboot/device/usb_client.cpp
@@ -257,7 +257,7 @@
auto bytes_to_read = std::min(len - bytes_read_total, kFbFfsNumBufs * kFbFfsBufSize);
auto bytes_read_now = handle_->read(handle_.get(), char_data, bytes_to_read);
if (bytes_read_now < 0) {
- return bytes_read_total;
+ return bytes_read_total == 0 ? -1 : bytes_read_total;
}
bytes_read_total += bytes_read_now;
char_data += bytes_read_now;
@@ -278,7 +278,7 @@
auto bytes_to_write = std::min(len - bytes_written_total, kFbFfsNumBufs * kFbFfsBufSize);
auto bytes_written_now = handle_->write(handle_.get(), data, bytes_to_write);
if (bytes_written_now < 0) {
- return bytes_written_total;
+ return bytes_written_total == 0 ? -1 : bytes_written_total;
}
bytes_written_total += bytes_written_now;
char_data += bytes_written_now;
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 045bb48..5114f55 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1268,6 +1268,46 @@
}
}
+int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab) {
+ AvbUniquePtr avb_handle(nullptr);
+ int ret = FsMgrUmountStatus::SUCCESS;
+ for (auto& current_entry : *fstab) {
+ if (!IsMountPointMounted(current_entry.mount_point)) {
+ continue;
+ }
+
+ if (umount(current_entry.mount_point.c_str()) == -1) {
+ PERROR << "Failed to umount " << current_entry.mount_point;
+ ret |= FsMgrUmountStatus::ERROR_UMOUNT;
+ continue;
+ }
+
+ if (current_entry.fs_mgr_flags.logical) {
+ if (!fs_mgr_update_logical_partition(¤t_entry)) {
+ LERROR << "Could not get logical partition blk_device, skipping!";
+ ret |= FsMgrUmountStatus::ERROR_DEVICE_MAPPER;
+ continue;
+ }
+ }
+
+ if (current_entry.fs_mgr_flags.avb || !current_entry.avb_keys.empty()) {
+ if (!AvbHandle::TearDownAvbHashtree(¤t_entry, true /* wait */)) {
+ LERROR << "Failed to tear down AVB on mount point: " << current_entry.mount_point;
+ ret |= FsMgrUmountStatus::ERROR_VERITY;
+ continue;
+ }
+ } else if ((current_entry.fs_mgr_flags.verify)) {
+ if (!fs_mgr_teardown_verity(¤t_entry, true /* wait */)) {
+ LERROR << "Failed to tear down verified partition on mount point: "
+ << current_entry.mount_point;
+ ret |= FsMgrUmountStatus::ERROR_VERITY;
+ continue;
+ }
+ }
+ }
+ return ret;
+}
+
// wrapper to __mount() and expects a fully prepared fstab_rec,
// unlike fs_mgr_do_mount which does more things with avb / verity etc.
int fs_mgr_do_mount_one(const FstabEntry& entry, const std::string& mount_point) {
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
index 45cbff3..ee6ffdb 100644
--- a/fs_mgr/fs_mgr_dm_linear.cpp
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -193,7 +193,7 @@
timeout_ms, path);
}
-bool DestroyLogicalPartition(const std::string& name, const std::chrono::milliseconds& timeout_ms) {
+bool UnmapDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms) {
DeviceMapper& dm = DeviceMapper::Instance();
std::string path;
if (timeout_ms > std::chrono::milliseconds::zero()) {
@@ -206,6 +206,13 @@
LERROR << "Timed out waiting for device path to unlink: " << path;
return false;
}
+ return true;
+}
+
+bool DestroyLogicalPartition(const std::string& name, const std::chrono::milliseconds& timeout_ms) {
+ if (!UnmapDevice(name, timeout_ms)) {
+ return false;
+ }
LINFO << "Unmapped logical partition " << name;
return true;
}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 11602ea..70abf5b 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -103,3 +103,11 @@
bool fs_mgr_is_ext4(const std::string& blk_device);
bool fs_mgr_is_f2fs(const std::string& blk_device);
+
+bool fs_mgr_teardown_verity(android::fs_mgr::FstabEntry* fstab, bool wait);
+
+namespace android {
+namespace fs_mgr {
+bool UnmapDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms);
+} // namespace fs_mgr
+} // namespace android
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index c53e866..3f09157 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -44,6 +44,7 @@
#include "fec/io.h"
#include "fs_mgr.h"
+#include "fs_mgr_dm_linear.h"
#include "fs_mgr_priv.h"
// Realistically, this file should be part of the android::fs_mgr namespace;
@@ -882,3 +883,12 @@
return retval;
}
+
+bool fs_mgr_teardown_verity(FstabEntry* entry, bool wait) {
+ const std::string mount_point(basename(entry->mount_point.c_str()));
+ if (!android::fs_mgr::UnmapDevice(mount_point, wait ? 1000ms : 0ms)) {
+ return false;
+ }
+ LINFO << "Unmapped verity device " << mount_point;
+ return true;
+}
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 8abe609..88b2f8f 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -93,3 +93,14 @@
// specified, the super partition for the corresponding metadata slot will be
// returned. Otherwise, it will use the current slot.
std::string fs_mgr_get_super_partition_name(int slot = -1);
+
+enum FsMgrUmountStatus : int {
+ SUCCESS = 0,
+ ERROR_UNKNOWN = 1 << 0,
+ ERROR_UMOUNT = 1 << 1,
+ ERROR_VERITY = 1 << 2,
+ ERROR_DEVICE_MAPPER = 1 << 3,
+};
+// fs_mgr_umount_all() is the reverse of fs_mgr_mount_all. In particular,
+// it destroys verity devices from device mapper after the device is unmounted.
+int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab);
diff --git a/fs_mgr/libfs_avb/fs_avb.cpp b/fs_mgr/libfs_avb/fs_avb.cpp
index f0767dc..04776ed 100644
--- a/fs_mgr/libfs_avb/fs_avb.cpp
+++ b/fs_mgr/libfs_avb/fs_avb.cpp
@@ -449,6 +449,29 @@
return AvbHashtreeResult::kSuccess;
}
+bool AvbHandle::TearDownAvbHashtree(FstabEntry* fstab_entry, bool wait) {
+ if (!fstab_entry) {
+ return false;
+ }
+
+ const std::string device_name(GetVerityDeviceName(*fstab_entry));
+
+ // TODO: remove duplicated code with UnmapDevice()
+ android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();
+ std::string path;
+ if (wait) {
+ dm.GetDmDevicePathByName(device_name, &path);
+ }
+ if (!dm.DeleteDevice(device_name)) {
+ return false;
+ }
+ if (!path.empty() && !WaitForFile(path, 1000ms, FileWaitMode::DoesNotExist)) {
+ return false;
+ }
+
+ return true;
+}
+
std::string AvbHandle::GetSecurityPatchLevel(const FstabEntry& fstab_entry) const {
if (vbmeta_images_.size() < 1) {
return "";
diff --git a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h
index 7127fa6..521f2d5 100644
--- a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h
+++ b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h
@@ -110,6 +110,11 @@
static AvbHashtreeResult SetUpStandaloneAvbHashtree(FstabEntry* fstab_entry,
bool wait_for_verity_dev = true);
+ // Tear down dm devices created by SetUp[Standalone]AvbHashtree
+ // The 'wait' parameter makes this function wait for the verity device to get destroyed
+ // before return.
+ static bool TearDownAvbHashtree(FstabEntry* fstab_entry, bool wait);
+
static bool IsDeviceUnlocked();
std::string GetSecurityPatchLevel(const FstabEntry& fstab_entry) const;
diff --git a/fs_mgr/libfs_avb/tests/util_test.cpp b/fs_mgr/libfs_avb/tests/util_test.cpp
index 9e37d22..12b5acb 100644
--- a/fs_mgr/libfs_avb/tests/util_test.cpp
+++ b/fs_mgr/libfs_avb/tests/util_test.cpp
@@ -27,6 +27,7 @@
// Target functions to test:
using android::fs_mgr::BytesToHex;
+using android::fs_mgr::FileWaitMode;
using android::fs_mgr::HexToBytes;
using android::fs_mgr::NibbleValue;
using android::fs_mgr::WaitForFile;
@@ -175,7 +176,7 @@
// Waits this path.
base::FilePath wait_path = tmp_dir.Append("libfs_avb-test-exist-dir");
ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */));
- auto wait_file = std::async(WaitForFile, wait_path.value(), 500ms);
+ auto wait_file = std::async(WaitForFile, wait_path.value(), 500ms, FileWaitMode::Exists);
// Sleeps 100ms before creating the wait_path.
std::this_thread::sleep_for(100ms);
@@ -196,7 +197,7 @@
// Waits this path.
base::FilePath wait_path = tmp_dir.Append("libfs_avb-test-exist-dir");
ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */));
- auto wait_file = std::async(WaitForFile, wait_path.value(), 50ms);
+ auto wait_file = std::async(WaitForFile, wait_path.value(), 50ms, FileWaitMode::Exists);
// Sleeps 100ms before creating the wait_path.
std::this_thread::sleep_for(100ms);
diff --git a/fs_mgr/libfs_avb/util.cpp b/fs_mgr/libfs_avb/util.cpp
index 9d4f05f..d214b5b 100644
--- a/fs_mgr/libfs_avb/util.cpp
+++ b/fs_mgr/libfs_avb/util.cpp
@@ -82,12 +82,17 @@
return hex;
}
-bool WaitForFile(const std::string& filename, const std::chrono::milliseconds relative_timeout) {
+// TODO: remove duplicate code with fs_mgr_wait_for_file
+bool WaitForFile(const std::string& filename, const std::chrono::milliseconds relative_timeout,
+ FileWaitMode file_wait_mode) {
auto start_time = std::chrono::steady_clock::now();
while (true) {
- if (0 == access(filename.c_str(), F_OK) || errno != ENOENT) {
- return true;
+ int rv = access(filename.c_str(), F_OK);
+ if (file_wait_mode == FileWaitMode::Exists) {
+ if (!rv || errno != ENOENT) return true;
+ } else if (file_wait_mode == FileWaitMode::DoesNotExist) {
+ if (rv && errno == ENOENT) return true;
}
std::this_thread::sleep_for(50ms);
diff --git a/fs_mgr/libfs_avb/util.h b/fs_mgr/libfs_avb/util.h
index cb861f4..7763da5 100644
--- a/fs_mgr/libfs_avb/util.h
+++ b/fs_mgr/libfs_avb/util.h
@@ -52,7 +52,9 @@
std::string BytesToHex(const uint8_t* bytes, size_t bytes_len);
-bool WaitForFile(const std::string& filename, const std::chrono::milliseconds relative_timeout);
+enum class FileWaitMode { Exists, DoesNotExist };
+bool WaitForFile(const std::string& filename, const std::chrono::milliseconds relative_timeout,
+ FileWaitMode wait_mode = FileWaitMode::Exists);
bool IsDeviceUnlocked();
diff --git a/init/README.md b/init/README.md
index aadf11d..51deb5a 100644
--- a/init/README.md
+++ b/init/README.md
@@ -488,7 +488,11 @@
This is included in the default init.rc.
`loglevel <level>`
-> Sets the kernel log level to level. Properties are expanded within _level_.
+> Sets init's log level to the integer level, from 7 (all logging) to 0
+ (fatal logging only). The numeric values correspond to the kernel log
+ levels, but this command does not affect the kernel log level. Use the
+ `write` command to write to `/proc/sys/kernel/printk` to change that.
+ Properties are expanded within _level_.
`mkdir <path> [mode] [owner] [group]`
> Create a directory at _path_, optionally with the given mode, owner, and
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 8437e37..fc75072 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -451,13 +451,13 @@
if (false) DumpState();
}
-/* mount_fstab
+/* handle_fstab
*
- * Call fs_mgr_mount_all() to mount the given fstab
+ * Read the given fstab file and execute func on it.
*/
-static Result<int> mount_fstab(const char* fstabfile, int mount_mode) {
+static Result<int> handle_fstab(const std::string& fstabfile, std::function<int(Fstab*)> func) {
/*
- * Call fs_mgr_mount_all() to mount all filesystems. We fork(2) and
+ * Call fs_mgr_[u]mount_all() to [u]mount all filesystems. We fork(2) and
* do the call in the child to provide protection to the main init
* process if anything goes wrong (crash or memory leak), and wait for
* the child to finish in the parent.
@@ -478,25 +478,51 @@
return Error() << "child aborted";
}
} else if (pid == 0) {
- /* child, call fs_mgr_mount_all() */
+ /* child, call fs_mgr_[u]mount_all() */
- // So we can always see what fs_mgr_mount_all() does.
+ // So we can always see what fs_mgr_[u]mount_all() does.
// Only needed if someone explicitly changes the default log level in their init.rc.
android::base::ScopedLogSeverity info(android::base::INFO);
Fstab fstab;
ReadFstabFromFile(fstabfile, &fstab);
- int child_ret = fs_mgr_mount_all(&fstab, mount_mode);
- if (child_ret == -1) {
- PLOG(ERROR) << "fs_mgr_mount_all returned an error";
- }
+ int child_ret = func(&fstab);
+
_exit(child_ret);
} else {
return Error() << "fork() failed";
}
}
+/* mount_fstab
+ *
+ * Call fs_mgr_mount_all() to mount the given fstab
+ */
+static Result<int> mount_fstab(const std::string& fstabfile, int mount_mode) {
+ return handle_fstab(fstabfile, [mount_mode](Fstab* fstab) {
+ int ret = fs_mgr_mount_all(fstab, mount_mode);
+ if (ret == -1) {
+ PLOG(ERROR) << "fs_mgr_mount_all returned an error";
+ }
+ return ret;
+ });
+}
+
+/* umount_fstab
+ *
+ * Call fs_mgr_umount_all() to umount the given fstab
+ */
+static Result<int> umount_fstab(const std::string& fstabfile) {
+ return handle_fstab(fstabfile, [](Fstab* fstab) {
+ int ret = fs_mgr_umount_all(fstab);
+ if (ret != 0) {
+ PLOG(ERROR) << "fs_mgr_umount_all returned " << ret;
+ }
+ return ret;
+ });
+}
+
/* Queue event based on fs_mgr return code.
*
* code: return code of fs_mgr_mount_all
@@ -583,7 +609,7 @@
bool import_rc = true;
bool queue_event = true;
int mount_mode = MOUNT_MODE_DEFAULT;
- const char* fstabfile = args[1].c_str();
+ const auto& fstabfile = args[1];
std::size_t path_arg_end = args.size();
const char* prop_post_fix = "default";
@@ -626,6 +652,15 @@
return Success();
}
+/* umount_all <fstab> */
+static Result<Success> do_umount_all(const BuiltinArguments& args) {
+ auto umount_fstab_return_code = umount_fstab(args[1]);
+ if (!umount_fstab_return_code) {
+ return Error() << "umount_fstab() failed " << umount_fstab_return_code.error();
+ }
+ return Success();
+}
+
static Result<Success> do_swapon_all(const BuiltinArguments& args) {
Fstab fstab;
if (!ReadFstabFromFile(args[1], &fstab)) {
@@ -1165,6 +1200,7 @@
{"mount", {3, kMax, {false, do_mount}}},
{"parse_apex_configs", {0, 0, {false, do_parse_apex_configs}}},
{"umount", {1, 1, {false, do_umount}}},
+ {"umount_all", {1, 1, {false, do_umount_all}}},
{"readahead", {1, 2, {true, do_readahead}}},
{"restart", {1, 1, {false, do_restart}}},
{"restorecon", {1, kMax, {true, do_restorecon}}},
diff --git a/libkeyutils/mini_keyctl_utils.cpp b/libkeyutils/mini_keyctl_utils.cpp
index b012a33..79b4680 100644
--- a/libkeyutils/mini_keyctl_utils.cpp
+++ b/libkeyutils/mini_keyctl_utils.cpp
@@ -67,7 +67,7 @@
if (tokens.size() < 9) {
continue;
}
- std::string key_id = tokens[0];
+ std::string key_id = "0x" + tokens[0];
std::string key_type = tokens[7];
// The key description may contain space.
std::string key_desc_prefix = tokens[8];
@@ -77,7 +77,7 @@
continue;
}
if (!android::base::ParseInt(key_id.c_str(), &keyring_id)) {
- error(1, 0, "Unexpected key format in /proc/keys");
+ error(1, 0, "Unexpected key format in /proc/keys: %s", key_id.c_str());
return -1;
}
return keyring_id;
diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp
index c7d0cca..ab0f1ca 100644
--- a/libprocessgroup/sched_policy.cpp
+++ b/libprocessgroup/sched_policy.cpp
@@ -126,24 +126,15 @@
switch (policy) {
case SP_BACKGROUND:
- return SetTaskProfiles(tid, {"HighEnergySaving", "LowIoPriority", "TimerSlackHigh"})
- ? 0
- : -1;
+ return SetTaskProfiles(tid, {"HighEnergySaving", "TimerSlackHigh"}) ? 0 : -1;
case SP_FOREGROUND:
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
- return SetTaskProfiles(tid, {"HighPerformance", "HighIoPriority", "TimerSlackNormal"})
- ? 0
- : -1;
+ return SetTaskProfiles(tid, {"HighPerformance", "TimerSlackNormal"}) ? 0 : -1;
case SP_TOP_APP:
- return SetTaskProfiles(tid, {"MaxPerformance", "MaxIoPriority", "TimerSlackNormal"})
- ? 0
- : -1;
+ return SetTaskProfiles(tid, {"MaxPerformance", "TimerSlackNormal"}) ? 0 : -1;
case SP_RT_APP:
- return SetTaskProfiles(tid,
- {"RealtimePerformance", "MaxIoPriority", "TimerSlackNormal"})
- ? 0
- : -1;
+ return SetTaskProfiles(tid, {"RealtimePerformance", "TimerSlackNormal"}) ? 0 : -1;
default:
return SetTaskProfiles(tid, {"TimerSlackNormal"}) ? 0 : -1;
}