Merge "Use new libfscrypt interface"
diff --git a/adb/Android.bp b/adb/Android.bp
index 170053b..d14fe56 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -428,18 +428,10 @@
"daemon/abb_service.cpp",
"daemon/framebuffer_service.cpp",
"daemon/mdns.cpp",
- "daemon/reboot_service.cpp",
"daemon/restart_service.cpp",
- "daemon/set_verity_enable_state_service.cpp",
- ],
- static_libs: [
- "libavb_user",
],
shared_libs: [
- "libbootloader_message",
"libmdnssd",
- "libfec",
- "libfs_mgr",
"libselinux",
],
},
@@ -513,6 +505,22 @@
],
}
+phony {
+ name: "adbd_system_binaries",
+ required: [
+ "abb",
+ "reboot",
+ "set-verity-state",
+ ]
+}
+
+phony {
+ name: "adbd_system_binaries_recovery",
+ required: [
+ "reboot.recovery",
+ ],
+}
+
cc_binary {
name: "static_adbd",
defaults: ["adbd_defaults", "host_adbd_supported"],
@@ -608,7 +616,6 @@
static_libs: [
"libadbd",
"libbase",
- "libbootloader_message",
"libcutils",
"libcrypto_utils",
"libcrypto_static",
diff --git a/adb/daemon/reboot_service.cpp b/adb/daemon/reboot_service.cpp
deleted file mode 100644
index 13398af..0000000
--- a/adb/daemon/reboot_service.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.
- */
-
-#define TRACE_TAG SERVICES
-
-#include "sysdeps.h"
-
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <bootloader_message/bootloader_message.h>
-#include <cutils/android_reboot.h>
-
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-
-void reboot_service(unique_fd fd, const std::string& arg) {
- std::string reboot_arg = arg;
- sync();
-
- if (reboot_arg.empty()) reboot_arg = "adb";
- std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg.c_str());
-
- if (reboot_arg == "fastboot" &&
- android::base::GetBoolProperty("ro.boot.dynamic_partitions", false) &&
- access("/dev/socket/recovery", F_OK) == 0) {
- LOG(INFO) << "Recovery specific reboot fastboot";
- /*
- * The socket is created to allow switching between recovery and
- * fastboot.
- */
- android::base::unique_fd sock(socket(AF_UNIX, SOCK_STREAM, 0));
- if (sock < 0) {
- WriteFdFmt(fd, "reboot (%s) create\n", strerror(errno));
- PLOG(ERROR) << "Creating recovery socket failed";
- return;
- }
-
- sockaddr_un addr = {.sun_family = AF_UNIX};
- strncpy(addr.sun_path, "/dev/socket/recovery", sizeof(addr.sun_path) - 1);
- if (connect(sock.get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
- WriteFdFmt(fd, "reboot (%s) connect\n", strerror(errno));
- PLOG(ERROR) << "Couldn't connect to recovery socket";
- return;
- }
- const char msg_switch_to_fastboot = 'f';
- auto ret = adb_write(sock, &msg_switch_to_fastboot, sizeof(msg_switch_to_fastboot));
- if (ret != sizeof(msg_switch_to_fastboot)) {
- WriteFdFmt(fd, "reboot (%s) write\n", strerror(errno));
- PLOG(ERROR) << "Couldn't write message to recovery socket to switch to fastboot";
- return;
- }
- } else {
- if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
- WriteFdFmt(fd.get(), "reboot (%s) failed\n", reboot_string.c_str());
- return;
- }
- }
- // Don't return early. Give the reboot command time to take effect
- // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
- while (true) {
- pause();
- }
-}
diff --git a/adb/daemon/services.cpp b/adb/daemon/services.cpp
index 181a8c5..a44c10b 100644
--- a/adb/daemon/services.cpp
+++ b/adb/daemon/services.cpp
@@ -53,9 +53,7 @@
#include "daemon/file_sync_service.h"
#include "daemon/framebuffer_service.h"
-#include "daemon/reboot_service.h"
#include "daemon/restart_service.h"
-#include "daemon/set_verity_enable_state_service.h"
#include "daemon/shell_service.h"
@@ -254,9 +252,9 @@
cmd += name;
return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
} else if (android::base::ConsumePrefix(&name, "reboot:")) {
- std::string arg(name);
- return create_service_thread("reboot",
- std::bind(reboot_service, std::placeholders::_1, arg));
+ std::string cmd = "/system/bin/reboot ";
+ cmd += name;
+ return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
} else if (name.starts_with("root:")) {
return create_service_thread("root", restart_root_service);
} else if (name.starts_with("unroot:")) {
@@ -269,11 +267,11 @@
return StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw,
SubprocessProtocol::kNone);
} else if (name.starts_with("disable-verity:")) {
- return create_service_thread("verity-on", std::bind(set_verity_enabled_state_service,
- std::placeholders::_1, false));
+ return StartSubprocess("/system/bin/disable-verity", nullptr, SubprocessType::kRaw,
+ SubprocessProtocol::kNone);
} else if (name.starts_with("enable-verity:")) {
- return create_service_thread("verity-off", std::bind(set_verity_enabled_state_service,
- std::placeholders::_1, true));
+ return StartSubprocess("/system/bin/enable-verity", nullptr, SubprocessType::kRaw,
+ SubprocessProtocol::kNone);
} else if (android::base::ConsumePrefix(&name, "tcpip:")) {
std::string str(name);
diff --git a/adb/daemon/set_verity_enable_state_service.cpp b/adb/daemon/set_verity_enable_state_service.cpp
deleted file mode 100644
index 4fbccdb..0000000
--- a/adb/daemon/set_verity_enable_state_service.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "set_verity_enable_state_service.h"
-#include "sysdeps.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <libavb_user/libavb_user.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <fs_mgr.h>
-#include <fs_mgr_overlayfs.h>
-#include <fstab/fstab.h>
-#include <log/log_properties.h>
-
-#include "adb.h"
-#include "adb_io.h"
-#include "adb_unique_fd.h"
-
-#include "fec/io.h"
-
-#ifdef ALLOW_ADBD_DISABLE_VERITY
-static const bool kAllowDisableVerity = true;
-#else
-static const bool kAllowDisableVerity = false;
-#endif
-
-void suggest_run_adb_root(int fd) {
- if (getuid() != 0) WriteFdExactly(fd, "Maybe run adb root?\n");
-}
-
-static bool make_block_device_writable(const std::string& dev) {
- unique_fd fd(unix_open(dev, O_RDONLY | O_CLOEXEC));
- if (fd == -1) {
- return false;
- }
-
- int OFF = 0;
- bool result = (ioctl(fd.get(), BLKROSET, &OFF) != -1);
- return result;
-}
-
-/* Turn verity on/off */
-static bool set_verity_enabled_state(int fd, const char* block_device, const char* mount_point,
- bool enable) {
- if (!make_block_device_writable(block_device)) {
- WriteFdFmt(fd, "Could not make block device %s writable (%s).\n",
- block_device, strerror(errno));
- return false;
- }
-
- fec::io fh(block_device, O_RDWR);
-
- if (!fh) {
- WriteFdFmt(fd, "Could not open block device %s (%s).\n", block_device, strerror(errno));
- suggest_run_adb_root(fd);
- return false;
- }
-
- fec_verity_metadata metadata;
-
- if (!fh.get_verity_metadata(metadata)) {
- WriteFdExactly(fd, "Couldn't find verity metadata!\n");
- return false;
- }
-
- if (!enable && metadata.disabled) {
- WriteFdFmt(fd, "Verity already disabled on %s\n", mount_point);
- return false;
- }
-
- if (enable && !metadata.disabled) {
- WriteFdFmt(fd, "Verity already enabled on %s\n", mount_point);
- return false;
- }
-
- if (!fh.set_verity_status(enable)) {
- WriteFdFmt(fd, "Could not set verity %s flag on device %s with error %s\n",
- enable ? "enabled" : "disabled",
- block_device, strerror(errno));
- return false;
- }
-
- auto change = false;
- errno = 0;
- if (enable ? fs_mgr_overlayfs_teardown(mount_point, &change)
- : fs_mgr_overlayfs_setup(nullptr, mount_point, &change)) {
- if (change) {
- WriteFdFmt(fd, "%s overlayfs for %s\n", enable ? "disabling" : "using", mount_point);
- }
- } else if (errno) {
- int expected_errno = enable ? EBUSY : ENOENT;
- if (errno != expected_errno) {
- WriteFdFmt(fd, "Overlayfs %s for %s failed with error %s\n",
- enable ? "teardown" : "setup", mount_point, strerror(errno));
- }
- }
- WriteFdFmt(fd, "Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point);
- return true;
-}
-
-/* Helper function to get A/B suffix, if any. If the device isn't
- * using A/B the empty string is returned. Otherwise either "_a",
- * "_b", ... is returned.
- */
-static std::string get_ab_suffix() {
- return android::base::GetProperty("ro.boot.slot_suffix", "");
-}
-
-static bool is_avb_device_locked() {
- return android::base::GetProperty("ro.boot.vbmeta.device_state", "") == "locked";
-}
-
-static bool overlayfs_setup(int fd, bool enable) {
- auto change = false;
- errno = 0;
- if (enable ? fs_mgr_overlayfs_teardown(nullptr, &change)
- : fs_mgr_overlayfs_setup(nullptr, nullptr, &change)) {
- if (change) {
- WriteFdFmt(fd, "%s overlayfs\n", enable ? "disabling" : "using");
- }
- } else if (errno) {
- WriteFdFmt(fd, "Overlayfs %s failed with error %s\n", enable ? "teardown" : "setup",
- strerror(errno));
- suggest_run_adb_root(fd);
- }
- return change;
-}
-
-/* Use AVB to turn verity on/off */
-static bool set_avb_verity_enabled_state(int fd, AvbOps* ops, bool enable_verity) {
- std::string ab_suffix = get_ab_suffix();
- bool verity_enabled;
-
- if (is_avb_device_locked()) {
- WriteFdExactly(fd, "Device is locked. Please unlock the device first\n");
- return false;
- }
-
- if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
- WriteFdExactly(fd, "Error getting verity state. Try adb root first?\n");
- return false;
- }
-
- if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) {
- WriteFdFmt(fd, "verity is already %s\n", verity_enabled ? "enabled" : "disabled");
- return false;
- }
-
- if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) {
- WriteFdExactly(fd, "Error setting verity\n");
- return false;
- }
-
- overlayfs_setup(fd, enable_verity);
- WriteFdFmt(fd, "Successfully %s verity\n", enable_verity ? "enabled" : "disabled");
- return true;
-}
-
-void set_verity_enabled_state_service(unique_fd fd, bool enable) {
- bool any_changed = false;
-
- // Figure out if we're using VB1.0 or VB2.0 (aka AVB) - by
- // contract, androidboot.vbmeta.digest is set by the bootloader
- // when using AVB).
- bool using_avb = !android::base::GetProperty("ro.boot.vbmeta.digest", "").empty();
-
- // If using AVB, dm-verity is used on any build so we want it to
- // be possible to disable/enable on any build (except USER). For
- // VB1.0 dm-verity is only enabled on certain builds.
- if (!using_avb) {
- if (!kAllowDisableVerity) {
- WriteFdFmt(fd.get(), "%s-verity only works for userdebug builds\n",
- enable ? "enable" : "disable");
- }
-
- if (!android::base::GetBoolProperty("ro.secure", false)) {
- overlayfs_setup(fd.get(), enable);
- WriteFdExactly(fd.get(), "verity not enabled - ENG build\n");
- return;
- }
- }
-
- // Should never be possible to disable dm-verity on a USER build
- // regardless of using AVB or VB1.0.
- if (!__android_log_is_debuggable()) {
- WriteFdExactly(fd.get(), "verity cannot be disabled/enabled - USER build\n");
- return;
- }
-
- if (using_avb) {
- // Yep, the system is using AVB.
- AvbOps* ops = avb_ops_user_new();
- if (ops == nullptr) {
- WriteFdExactly(fd.get(), "Error getting AVB ops\n");
- return;
- }
- if (set_avb_verity_enabled_state(fd.get(), ops, enable)) {
- any_changed = true;
- }
- avb_ops_user_free(ops);
- } else {
- // Not using AVB - assume VB1.0.
-
- // read all fstab entries at once from all sources
- android::fs_mgr::Fstab fstab;
- if (!android::fs_mgr::ReadDefaultFstab(&fstab)) {
- WriteFdExactly(fd.get(), "Failed to read fstab\n");
- suggest_run_adb_root(fd.get());
- return;
- }
-
- // Loop through entries looking for ones that verity manages.
- for (const auto& entry : fstab) {
- if (entry.fs_mgr_flags.verify) {
- if (set_verity_enabled_state(fd.get(), entry.blk_device.c_str(),
- entry.mount_point.c_str(), enable)) {
- any_changed = true;
- }
- }
- }
- }
- if (!any_changed) any_changed = overlayfs_setup(fd.get(), enable);
-
- if (any_changed) {
- WriteFdExactly(fd.get(), "Now reboot your device for settings to take effect\n");
- }
-}
diff --git a/adb/daemon/set_verity_enable_state_service.h b/adb/daemon/set_verity_enable_state_service.h
deleted file mode 100644
index c0ed98e..0000000
--- a/adb/daemon/set_verity_enable_state_service.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "adb_unique_fd.h"
-
-#if defined(__ANDROID__)
-void set_verity_enabled_state_service(unique_fd fd, bool enable);
-#endif
diff --git a/adb/fastdeploy/Android.bp b/adb/fastdeploy/Android.bp
index 245d52a..f5893aa 100644
--- a/adb/fastdeploy/Android.bp
+++ b/adb/fastdeploy/Android.bp
@@ -27,6 +27,7 @@
java_binary {
name: "deployagent",
+ sdk_version: "24",
static_libs: [
"deployagent_lib",
],
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index da2ba58..1993840 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -595,7 +595,7 @@
}
AndroidLogEntry e;
char buf[512];
- if (android_log_processBinaryLogBuffer(&log_entry.entry_v1, &e, g_eventTagMap, buf,
+ if (android_log_processBinaryLogBuffer(&log_entry.entry, &e, g_eventTagMap, buf,
sizeof(buf)) == 0) {
_LOG(log, logtype::LOGS, "%s.%03d %5d %5d %c %-8.*s: %s\n", timeBuf,
log_entry.entry.nsec / 1000000, log_entry.entry.pid, log_entry.entry.tid, 'I',
diff --git a/fastboot/device/commands.h b/fastboot/device/commands.h
index afd6d08..9b6e7b6 100644
--- a/fastboot/device/commands.h
+++ b/fastboot/device/commands.h
@@ -19,7 +19,7 @@
#include <string>
#include <vector>
-constexpr unsigned int kMaxDownloadSizeDefault = 0x20000000;
+constexpr unsigned int kMaxDownloadSizeDefault = 0x10000000;
class FastbootDevice;
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index ba43949..9256a16 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -131,6 +131,7 @@
],
shared_libs: [
"libbinder",
+ "libcrypto",
"libhidlbase",
"libprotobuf-cpp-lite",
"libutils",
@@ -138,7 +139,6 @@
static_libs: [
"android.hardware.boot@1.0",
"android.hardware.boot@1.1",
- "libcrypto_static",
"libfs_mgr",
"libgmock",
"liblp",
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index fcaa73a..120340c 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -19,6 +19,7 @@
#include <chrono>
#include <map>
#include <memory>
+#include <optional>
#include <ostream>
#include <string>
#include <string_view>
@@ -298,7 +299,8 @@
std::string* dev_path);
// Map a COW image that was previous created with CreateCowImage.
- bool MapCowImage(const std::string& name, const std::chrono::milliseconds& timeout_ms);
+ std::optional<std::string> MapCowImage(const std::string& name,
+ const std::chrono::milliseconds& timeout_ms);
// Remove the backing copy-on-write image and snapshot states for the named snapshot. The
// caller is responsible for ensuring that the snapshot is unmapped.
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 48a94e4..758f69b 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -342,7 +342,6 @@
const std::chrono::milliseconds& timeout_ms,
std::string* dev_path) {
CHECK(lock);
- if (!EnsureImageManager()) return false;
SnapshotStatus status;
if (!ReadSnapshotStatus(lock, name, &status)) {
@@ -450,9 +449,9 @@
return true;
}
-bool SnapshotManager::MapCowImage(const std::string& name,
- const std::chrono::milliseconds& timeout_ms) {
- if (!EnsureImageManager()) return false;
+std::optional<std::string> SnapshotManager::MapCowImage(
+ const std::string& name, const std::chrono::milliseconds& timeout_ms) {
+ if (!EnsureImageManager()) return std::nullopt;
auto cow_image_name = GetCowImageDeviceName(name);
bool ok;
@@ -468,10 +467,10 @@
if (ok) {
LOG(INFO) << "Mapped " << cow_image_name << " to " << cow_dev;
- } else {
- LOG(ERROR) << "Could not map image device: " << cow_image_name;
+ return cow_dev;
}
- return ok;
+ LOG(ERROR) << "Could not map image device: " << cow_image_name;
+ return std::nullopt;
}
bool SnapshotManager::UnmapSnapshot(LockedFile* lock, const std::string& name) {
@@ -1428,7 +1427,6 @@
const SnapshotStatus& snapshot_status,
AutoDeviceList* created_devices, std::string* cow_name) {
CHECK(lock);
- if (!EnsureImageManager()) return false;
CHECK(snapshot_status.cow_partition_size() + snapshot_status.cow_file_size() > 0);
auto begin = std::chrono::steady_clock::now();
@@ -1440,10 +1438,11 @@
// Map COW image if necessary.
if (snapshot_status.cow_file_size() > 0) {
+ if (!EnsureImageManager()) return false;
auto remaining_time = GetRemainingTime(params.timeout_ms, begin);
if (remaining_time.count() < 0) return false;
- if (!MapCowImage(partition_name, remaining_time)) {
+ if (!MapCowImage(partition_name, remaining_time).has_value()) {
LOG(ERROR) << "Could not map cow image for partition: " << partition_name;
return false;
}
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index a008294..f6a4722 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -254,12 +254,11 @@
AssertionResult MapCowImage(const std::string& name,
const std::chrono::milliseconds& timeout_ms, std::string* path) {
- if (!sm->MapCowImage(name, timeout_ms)) {
+ auto cow_image_path = sm->MapCowImage(name, timeout_ms);
+ if (!cow_image_path.has_value()) {
return AssertionFailure() << "Cannot map cow image " << name;
}
- if (!dm_.GetDmDevicePathByName(name + "-cow-img"s, path)) {
- return AssertionFailure() << "No path for " << name << "-cow-img";
- }
+ *path = *cow_image_path;
return AssertionSuccess();
}
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 06c8176..57ed362 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -200,9 +200,7 @@
return value;
}
-bool BatteryMonitor::update(void) {
- bool logthis;
-
+void BatteryMonitor::updateValues(void) {
initBatteryProperties(&props);
if (!mHealthdConfig->batteryPresentPath.isEmpty())
@@ -289,50 +287,44 @@
}
}
}
+}
- logthis = !healthd_board_battery_update(&props);
+void BatteryMonitor::logValues(void) {
+ char dmesgline[256];
+ size_t len;
+ if (props.batteryPresent) {
+ snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
+ props.batteryLevel, props.batteryVoltage, props.batteryTemperature < 0 ? "-" : "",
+ abs(props.batteryTemperature / 10), abs(props.batteryTemperature % 10),
+ props.batteryHealth, props.batteryStatus);
- if (logthis) {
- char dmesgline[256];
- size_t len;
- if (props.batteryPresent) {
- snprintf(dmesgline, sizeof(dmesgline),
- "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
- props.batteryLevel, props.batteryVoltage,
- props.batteryTemperature < 0 ? "-" : "",
- abs(props.batteryTemperature / 10),
- abs(props.batteryTemperature % 10), props.batteryHealth,
- props.batteryStatus);
-
- len = strlen(dmesgline);
- if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
- len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
- " c=%d", props.batteryCurrent);
- }
-
- if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
- len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
- " fc=%d", props.batteryFullCharge);
- }
-
- if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
- len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
- " cc=%d", props.batteryCycleCount);
- }
- } else {
- len = snprintf(dmesgline, sizeof(dmesgline),
- "battery none");
+ len = strlen(dmesgline);
+ if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+ len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
+ props.batteryCurrent);
}
- snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s",
- props.chargerAcOnline ? "a" : "",
- props.chargerUsbOnline ? "u" : "",
- props.chargerWirelessOnline ? "w" : "");
+ if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
+ len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
+ props.batteryFullCharge);
+ }
- KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
+ if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
+ len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " cc=%d",
+ props.batteryCycleCount);
+ }
+ } else {
+ len = snprintf(dmesgline, sizeof(dmesgline), "battery none");
}
- healthd_mode_ops->battery_update(&props);
+ snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s",
+ props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "",
+ props.chargerWirelessOnline ? "w" : "");
+
+ KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
+}
+
+bool BatteryMonitor::isChargerOnline() {
return props.chargerAcOnline | props.chargerUsbOnline |
props.chargerWirelessOnline;
}
diff --git a/healthd/include/healthd/BatteryMonitor.h b/healthd/include/healthd/BatteryMonitor.h
index 4d1d53f..0fd3824 100644
--- a/healthd/include/healthd/BatteryMonitor.h
+++ b/healthd/include/healthd/BatteryMonitor.h
@@ -38,12 +38,15 @@
BatteryMonitor();
void init(struct healthd_config *hc);
- bool update(void);
int getChargeStatus();
status_t getProperty(int id, struct BatteryProperty *val);
void dumpState(int fd);
friend struct BatteryProperties getBatteryProperties(BatteryMonitor* batteryMonitor);
+ void updateValues(void);
+ void logValues(void);
+ bool isChargerOnline();
+
private:
struct healthd_config *mHealthdConfig;
Vector<String8> mChargerNames;
diff --git a/init/Android.bp b/init/Android.bp
index ce5b12a..bd2d38c 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -82,7 +82,6 @@
"libfscrypt",
"libgsi",
"libhidl-gen-utils",
- "libjsoncpp",
"libkeyutils",
"liblog",
"liblogwrap",
@@ -286,13 +285,11 @@
shared_libs: [
"libcutils",
"libhidl-gen-utils",
+ "libhidlmetadata",
"liblog",
"libprocessgroup",
"libprotobuf-cpp-lite",
],
- header_libs: [
- "libjsoncpp_headers",
- ],
srcs: [
"action.cpp",
"action_manager.cpp",
diff --git a/init/host_init_verifier.cpp b/init/host_init_verifier.cpp
index b2402b3..522709e 100644
--- a/init/host_init_verifier.cpp
+++ b/init/host_init_verifier.cpp
@@ -30,6 +30,7 @@
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
+#include <hidl/metadata.h>
#include "action.h"
#include "action_manager.h"
@@ -142,28 +143,46 @@
#include "generated_stub_builtin_function_map.h"
void PrintUsage() {
- std::cout << "usage: host_init_verifier [-p FILE] -i FILE <init rc file>\n"
+ std::cout << "usage: host_init_verifier [-p FILE] <init rc file>\n"
"\n"
"Tests an init script for correctness\n"
"\n"
"-p FILE\tSearch this passwd file for users and groups\n"
- "-i FILE\tParse this JSON file for the HIDL interface inheritance hierarchy\n"
<< std::endl;
}
+Result<InterfaceInheritanceHierarchyMap> ReadInterfaceInheritanceHierarchy() {
+ InterfaceInheritanceHierarchyMap result;
+ for (const HidlInterfaceMetadata& iface : HidlInterfaceMetadata::all()) {
+ std::set<FQName> inherited_interfaces;
+ for (const std::string& intf : iface.inherited) {
+ FQName fqname;
+ if (!fqname.setTo(intf)) {
+ return Error() << "Unable to parse interface '" << intf << "'";
+ }
+ inherited_interfaces.insert(fqname);
+ }
+ FQName fqname;
+ if (!fqname.setTo(iface.name)) {
+ return Error() << "Unable to parse interface '" << iface.name << "'";
+ }
+ result[fqname] = inherited_interfaces;
+ }
+
+ return result;
+}
+
int main(int argc, char** argv) {
android::base::InitLogging(argv, &android::base::StdioLogger);
android::base::SetMinimumLogSeverity(android::base::ERROR);
- std::string interface_inheritance_hierarchy_file;
-
while (true) {
static const struct option long_options[] = {
{"help", no_argument, nullptr, 'h'},
{nullptr, 0, nullptr, 0},
};
- int arg = getopt_long(argc, argv, "p:i:", long_options, nullptr);
+ int arg = getopt_long(argc, argv, "p:", long_options, nullptr);
if (arg == -1) {
break;
@@ -176,9 +195,6 @@
case 'p':
passwd_files.emplace_back(optarg);
break;
- case 'i':
- interface_inheritance_hierarchy_file = optarg;
- break;
default:
std::cerr << "getprop: getopt returned invalid result: " << arg << std::endl;
return EXIT_FAILURE;
@@ -188,13 +204,12 @@
argc -= optind;
argv += optind;
- if (argc != 1 || interface_inheritance_hierarchy_file.empty()) {
+ if (argc != 1) {
PrintUsage();
return EXIT_FAILURE;
}
- auto interface_inheritance_hierarchy_map =
- ReadInterfaceInheritanceHierarchy(interface_inheritance_hierarchy_file);
+ auto interface_inheritance_hierarchy_map = ReadInterfaceInheritanceHierarchy();
if (!interface_inheritance_hierarchy_map) {
LOG(ERROR) << interface_inheritance_hierarchy_map.error();
return EXIT_FAILURE;
diff --git a/init/interface_utils.cpp b/init/interface_utils.cpp
index ddbacd7..1b76bba 100644
--- a/init/interface_utils.cpp
+++ b/init/interface_utils.cpp
@@ -21,7 +21,6 @@
#include <android-base/strings.h>
#include <hidl-util/FqInstance.h>
-#include <json/json.h>
using android::FqInstance;
using android::FQName;
@@ -42,37 +41,6 @@
} // namespace
-Result<InterfaceInheritanceHierarchyMap> ReadInterfaceInheritanceHierarchy(
- const std::string& path) {
- Json::Value root;
- Json::Reader reader;
- std::ifstream stream(path);
- if (!reader.parse(stream, root)) {
- return Error() << "Failed to read interface inheritance hierarchy file: " << path << "\n"
- << reader.getFormattedErrorMessages();
- }
-
- InterfaceInheritanceHierarchyMap result;
- for (const Json::Value& entry : root) {
- std::set<FQName> inherited_interfaces;
- for (const Json::Value& intf : entry["inheritedInterfaces"]) {
- FQName fqname;
- if (!fqname.setTo(intf.asString())) {
- return Error() << "Unable to parse interface '" << intf.asString() << "'";
- }
- inherited_interfaces.insert(fqname);
- }
- std::string intf_string = entry["interface"].asString();
- FQName fqname;
- if (!fqname.setTo(intf_string)) {
- return Error() << "Unable to parse interface '" << intf_string << "'";
- }
- result[fqname] = inherited_interfaces;
- }
-
- return result;
-}
-
Result<void> CheckInterfaceInheritanceHierarchy(const std::set<std::string>& instances,
const InterfaceInheritanceHierarchyMap& hierarchy) {
std::set<FQName> interface_fqnames;
diff --git a/init/interface_utils.h b/init/interface_utils.h
index bd0c104..4ca377f 100644
--- a/init/interface_utils.h
+++ b/init/interface_utils.h
@@ -29,9 +29,6 @@
using InterfaceInheritanceHierarchyMap = std::map<android::FQName, std::set<android::FQName>>;
-// Reads the HIDL interface inheritance hierarchy JSON file at the given path.
-Result<InterfaceInheritanceHierarchyMap> ReadInterfaceInheritanceHierarchy(const std::string& path);
-
// For the given set of interfaces / interface instances, checks that each
// interface's hierarchy of inherited interfaces is also included in the given
// interface set. Uses the provided hierarchy data.
diff --git a/init/property_service.cpp b/init/property_service.cpp
index c6bbc14..3baaf7c 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -404,7 +404,7 @@
// We must release the fd before sending it to init, otherwise there will be a race with init.
// If init calls close() before Release(), then fdsan will see the wrong tag and abort().
int fd = -1;
- if (socket != nullptr) {
+ if (socket != nullptr && SelinuxGetVendorAndroidVersion() > __ANDROID_API_Q__) {
fd = socket->Release();
control_message->set_fd(fd);
}
diff --git a/init/reboot.cpp b/init/reboot.cpp
index d77b975..d453655 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -209,8 +209,8 @@
// Find all read+write block devices and emulated devices in /proc/mounts and add them to
// the correpsponding list.
-static bool FindPartitionsToUmount(std::vector<MountEntry>* blockDevPartitions,
- std::vector<MountEntry>* emulatedPartitions, bool dump) {
+static bool FindPartitionsToUmount(std::vector<MountEntry>* block_dev_partitions,
+ std::vector<MountEntry>* emulated_partitions, bool dump) {
std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "re"), endmntent);
if (fp == nullptr) {
PLOG(ERROR) << "Failed to open /proc/mounts";
@@ -227,10 +227,10 @@
// Do not umount them as shutdown critical services may rely on them.
if (mount_dir != "/" && mount_dir != "/system" && mount_dir != "/vendor" &&
mount_dir != "/oem") {
- blockDevPartitions->emplace(blockDevPartitions->begin(), *mentry);
+ block_dev_partitions->emplace(block_dev_partitions->begin(), *mentry);
}
} else if (MountEntry::IsEmulatedDevice(*mentry)) {
- emulatedPartitions->emplace(emulatedPartitions->begin(), *mentry);
+ emulated_partitions->emplace(emulated_partitions->begin(), *mentry);
}
}
return true;
@@ -292,8 +292,9 @@
}
// Create reboot/shutdwon monitor thread
-void RebootMonitorThread(unsigned int cmd, const std::string& rebootTarget, sem_t* reboot_semaphore,
- std::chrono::milliseconds shutdown_timeout, bool* reboot_monitor_run) {
+void RebootMonitorThread(unsigned int cmd, const std::string& reboot_target,
+ sem_t* reboot_semaphore, std::chrono::milliseconds shutdown_timeout,
+ bool* reboot_monitor_run) {
unsigned int remaining_shutdown_time = 0;
// 30 seconds more than the timeout passed to the thread as there is a final Umount pass
@@ -355,7 +356,7 @@
WriteStringToFile("u", PROC_SYSRQ);
- RebootSystem(cmd, rebootTarget);
+ RebootSystem(cmd, reboot_target);
}
LOG(ERROR) << "Trigger crash at last!";
@@ -385,13 +386,13 @@
*
* return true when umount was successful. false when timed out.
*/
-static UmountStat TryUmountAndFsck(unsigned int cmd, const std::string& rebootTarget, bool runFsck,
+static UmountStat TryUmountAndFsck(unsigned int cmd, bool run_fsck,
std::chrono::milliseconds timeout, sem_t* reboot_semaphore) {
Timer t;
std::vector<MountEntry> block_devices;
std::vector<MountEntry> emulated_devices;
- if (runFsck && !FindPartitionsToUmount(&block_devices, &emulated_devices, false)) {
+ if (run_fsck && !FindPartitionsToUmount(&block_devices, &emulated_devices, false)) {
return UMOUNT_STAT_ERROR;
}
@@ -405,7 +406,7 @@
if ((st != UMOUNT_STAT_SUCCESS) && DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
}
- if (stat == UMOUNT_STAT_SUCCESS && runFsck) {
+ if (stat == UMOUNT_STAT_SUCCESS && run_fsck) {
LOG(INFO) << "Pause reboot monitor thread before fsck";
sem_post(reboot_semaphore);
@@ -509,20 +510,19 @@
//* Reboot / shutdown the system.
// cmd ANDROID_RB_* as defined in android_reboot.h
// reason Reason string like "reboot", "shutdown,userrequested"
-// rebootTarget Reboot target string like "bootloader". Otherwise, it should be an
-// empty string.
-// runFsck Whether to run fsck after umount is done.
+// reboot_target Reboot target string like "bootloader". Otherwise, it should be an empty string.
+// run_fsck Whether to run fsck after umount is done.
//
-static void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget,
- bool runFsck) {
+static void DoReboot(unsigned int cmd, const std::string& reason, const std::string& reboot_target,
+ bool run_fsck) {
Timer t;
- LOG(INFO) << "Reboot start, reason: " << reason << ", rebootTarget: " << rebootTarget;
+ LOG(INFO) << "Reboot start, reason: " << reason << ", reboot_target: " << reboot_target;
// If /data isn't mounted then we can skip the extra reboot steps below, since we don't need to
// worry about unmounting it.
if (!IsDataMounted()) {
sync();
- RebootSystem(cmd, rebootTarget);
+ RebootSystem(cmd, reboot_target);
abort();
}
@@ -557,13 +557,13 @@
if (sem_init(&reboot_semaphore, false, 0) == -1) {
// These should never fail, but if they do, skip the graceful reboot and reboot immediately.
LOG(ERROR) << "sem_init() fail and RebootSystem() return!";
- RebootSystem(cmd, rebootTarget);
+ RebootSystem(cmd, reboot_target);
}
// Start a thread to monitor init shutdown process
LOG(INFO) << "Create reboot monitor thread.";
bool reboot_monitor_run = true;
- std::thread reboot_monitor_thread(&RebootMonitorThread, cmd, rebootTarget, &reboot_semaphore,
+ std::thread reboot_monitor_thread(&RebootMonitorThread, cmd, reboot_target, &reboot_semaphore,
shutdown_timeout, &reboot_monitor_run);
reboot_monitor_thread.detach();
@@ -600,16 +600,16 @@
TurnOffBacklight();
}
- Service* bootAnim = ServiceList::GetInstance().FindService("bootanim");
- Service* surfaceFlinger = ServiceList::GetInstance().FindService("surfaceflinger");
- if (bootAnim != nullptr && surfaceFlinger != nullptr && surfaceFlinger->IsRunning()) {
+ Service* boot_anim = ServiceList::GetInstance().FindService("bootanim");
+ Service* surface_flinger = ServiceList::GetInstance().FindService("surfaceflinger");
+ if (boot_anim != nullptr && surface_flinger != nullptr && surface_flinger->IsRunning()) {
bool do_shutdown_animation = GetBoolProperty("ro.init.shutdown_animation", false);
if (do_shutdown_animation) {
property_set("service.bootanim.exit", "0");
// Could be in the middle of animation. Stop and start so that it can pick
// up the right mode.
- bootAnim->Stop();
+ boot_anim->Stop();
}
for (const auto& service : ServiceList::GetInstance()) {
@@ -625,9 +625,9 @@
}
if (do_shutdown_animation) {
- bootAnim->Start();
- surfaceFlinger->SetShutdownCritical();
- bootAnim->SetShutdownCritical();
+ boot_anim->Start();
+ surface_flinger->SetShutdownCritical();
+ boot_anim->SetShutdownCritical();
}
}
@@ -643,10 +643,10 @@
ReapAnyOutstandingChildren();
// 3. send volume shutdown to vold
- Service* voldService = ServiceList::GetInstance().FindService("vold");
- if (voldService != nullptr && voldService->IsRunning()) {
+ Service* vold_service = ServiceList::GetInstance().FindService("vold");
+ if (vold_service != nullptr && vold_service->IsRunning()) {
ShutdownVold();
- voldService->Stop();
+ vold_service->Stop();
} else {
LOG(INFO) << "vold not running, skipping vold shutdown";
}
@@ -662,8 +662,8 @@
// 5. drop caches and disable zram backing device, if exist
KillZramBackingDevice();
- UmountStat stat = TryUmountAndFsck(cmd, rebootTarget, runFsck, shutdown_timeout - t.duration(),
- &reboot_semaphore);
+ UmountStat stat =
+ TryUmountAndFsck(cmd, run_fsck, shutdown_timeout - t.duration(), &reboot_semaphore);
// Follow what linux shutdown is doing: one more sync with little bit delay
{
Timer sync_timer;
@@ -679,7 +679,7 @@
sem_post(&reboot_semaphore);
// Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.
- RebootSystem(cmd, rebootTarget);
+ RebootSystem(cmd, reboot_target);
abort();
}
diff --git a/liblog/Android.bp b/liblog/Android.bp
index c40c5ef..91bd52c 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -105,6 +105,11 @@
versions: ["10000"],
},
+ // TODO(tomcherry): Renable this before release branch is cut
+ header_abi_checker: {
+ enabled: false,
+ },
+
cflags: [
"-Wall",
"-Werror",
diff --git a/liblog/README.protocol.md b/liblog/README.protocol.md
new file mode 100644
index 0000000..fef29c9
--- /dev/null
+++ b/liblog/README.protocol.md
@@ -0,0 +1,49 @@
+# liblog -> logd
+
+The data that liblog sends to logd is represented below.
+
+ struct {
+ android_log_header_t header;
+ union {
+ struct {
+ char prio;
+ char tag[...];
+ char message[...];
+ } string;
+ struct {
+ android_event_header_t event_header;
+ android_event_*_t payload[...];
+ } binary;
+ };
+ };
+
+The payload, excluding the header, has a max size of LOGGER_ENTRY_MAX_PAYLOAD.
+
+## header
+
+The header is added immediately before sending the log message to logd.
+
+## `string` payload
+
+The `string` part of the union is for normal buffers (main, system, radio, etc) and consists of a
+single character priority, followed by a variable length null terminated string for the tag, and
+finally a variable length null terminated string for the message.
+
+This payload is used for the `__android_log_buf_write()` family of functions.
+
+## `binary` payload
+
+The `binary` part of the union is for binary buffers (events, security, etc) and consists of an
+android_event_header_t struct followed by a variable number of android_event_*_t
+(android_event_list_t, android_event_int_t, etc) structs.
+
+If multiple android_event_*_t elements are present, then they must be in a list and the first
+element in payload must be an android_event_list_t.
+
+This payload is used for the `__android_log_bwrite()` family of functions. It is additionally used
+for `android_log_write_list()` and the related functions that manipulate event lists.
+
+# logd -> liblog
+
+logd sends a `logger_entry` struct to liblog followed by the payload. The payload is identical to
+the payloads defined above. The max size of the entire message from logd is LOGGER_ENTRY_MAX_LEN.
diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h
index 2079e7a..ee3b250 100644
--- a/liblog/include/log/log_read.h
+++ b/liblog/include/log/log_read.h
@@ -50,53 +50,9 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wzero-length-array"
-/*
- * The userspace structure for version 1 of the logger_entry ABI.
- */
struct logger_entry {
- uint16_t len; /* length of the payload */
- uint16_t __pad; /* no matter what, we get 2 bytes of padding */
- int32_t pid; /* generating process's pid */
- int32_t tid; /* generating process's tid */
- int32_t sec; /* seconds since Epoch */
- int32_t nsec; /* nanoseconds */
- char msg[0]; /* the entry's payload */
-};
-
-/*
- * The userspace structure for version 2 of the logger_entry ABI.
- */
-struct logger_entry_v2 {
uint16_t len; /* length of the payload */
- uint16_t hdr_size; /* sizeof(struct logger_entry_v2) */
- int32_t pid; /* generating process's pid */
- int32_t tid; /* generating process's tid */
- int32_t sec; /* seconds since Epoch */
- int32_t nsec; /* nanoseconds */
- uint32_t euid; /* effective UID of logger */
- char msg[0]; /* the entry's payload */
-} __attribute__((__packed__));
-
-/*
- * The userspace structure for version 3 of the logger_entry ABI.
- */
-struct logger_entry_v3 {
- uint16_t len; /* length of the payload */
- uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */
- int32_t pid; /* generating process's pid */
- int32_t tid; /* generating process's tid */
- int32_t sec; /* seconds since Epoch */
- int32_t nsec; /* nanoseconds */
- uint32_t lid; /* log id of the payload */
- char msg[0]; /* the entry's payload */
-} __attribute__((__packed__));
-
-/*
- * The userspace structure for version 4 of the logger_entry ABI.
- */
-struct logger_entry_v4 {
- uint16_t len; /* length of the payload */
- uint16_t hdr_size; /* sizeof(struct logger_entry_v4) */
+ uint16_t hdr_size; /* sizeof(struct logger_entry) */
int32_t pid; /* generating process's pid */
uint32_t tid; /* generating process's tid */
uint32_t sec; /* seconds since Epoch */
@@ -124,11 +80,7 @@
struct log_msg {
union {
unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
- struct logger_entry_v4 entry;
- struct logger_entry_v4 entry_v4;
- struct logger_entry_v3 entry_v3;
- struct logger_entry_v2 entry_v2;
- struct logger_entry entry_v1;
+ struct logger_entry entry;
} __attribute__((aligned(4)));
#ifdef __cplusplus
/* Matching log_time operators */
@@ -162,19 +114,12 @@
}
char* msg() {
unsigned short hdr_size = entry.hdr_size;
- if (!hdr_size) {
- hdr_size = sizeof(entry_v1);
- }
- if ((hdr_size < sizeof(entry_v1)) || (hdr_size > sizeof(entry))) {
+ if (hdr_size != sizeof(entry)) {
return nullptr;
}
return reinterpret_cast<char*>(buf) + hdr_size;
}
- unsigned int len() {
- return (entry.hdr_size ? entry.hdr_size
- : static_cast<uint16_t>(sizeof(entry_v1))) +
- entry.len;
- }
+ unsigned int len() { return entry.hdr_size + entry.len; }
#endif
};
diff --git a/liblog/logd_writer.cpp b/liblog/logd_writer.cpp
index 06a2baf..a22c3be 100644
--- a/liblog/logd_writer.cpp
+++ b/liblog/logd_writer.cpp
@@ -148,24 +148,6 @@
return 0;
}
- /*
- * struct {
- * // what we provide to socket
- * android_log_header_t header;
- * // caller provides
- * union {
- * struct {
- * char prio;
- * char payload[];
- * } string;
- * struct {
- * uint32_t tag
- * char payload[];
- * } binary;
- * };
- * };
- */
-
header.tid = gettid();
header.realtime.tv_sec = ts->tv_sec;
header.realtime.tv_nsec = ts->tv_nsec;
diff --git a/liblog/logger.h b/liblog/logger.h
index 8cae66c..02cad22 100644
--- a/liblog/logger.h
+++ b/liblog/logger.h
@@ -96,8 +96,6 @@
struct android_log_transport_read* transport;
unsigned logMask; /* mask of requested log buffers */
- int ret; /* return value associated with following data */
- struct log_msg logMsg; /* peek at upcoming data, valid if logMsg.len != 0 */
};
struct android_log_logger_list {
diff --git a/liblog/logger_read.cpp b/liblog/logger_read.cpp
index ff816b7..4b4012a 100644
--- a/liblog/logger_read.cpp
+++ b/liblog/logger_read.cpp
@@ -92,7 +92,6 @@
logger_list->transport_context.transport = transport;
logger_list->transport_context.logMask = logMask;
- logger_list->transport_context.ret = 1;
#endif
return 0;
}
@@ -273,34 +272,24 @@
struct log_msg* log_msg) {
int ret = (*transp->transport->read)(logger_list, transp, log_msg);
+ if (ret < 0) {
+ return ret;
+ }
+
if (ret > (int)sizeof(*log_msg)) {
ret = sizeof(*log_msg);
}
- transp->ret = ret;
-
- /* propagate errors, or make sure len & hdr_size members visible */
- if (ret < (int)(sizeof(log_msg->entry.len) + sizeof(log_msg->entry.hdr_size))) {
- if (ret >= (int)sizeof(log_msg->entry.len)) {
- log_msg->entry.len = 0;
- }
- return ret;
- }
-
- /* hdr_size correction (logger_entry -> logger_entry_v2+ conversion) */
- if (log_msg->entry_v2.hdr_size == 0) {
- log_msg->entry_v2.hdr_size = sizeof(struct logger_entry);
- }
- if ((log_msg->entry_v2.hdr_size < sizeof(log_msg->entry_v1)) ||
- (log_msg->entry_v2.hdr_size > sizeof(log_msg->entry))) {
+ if (ret < static_cast<int>(sizeof(log_msg->entry))) {
return -EINVAL;
}
- /* len validation */
- if (ret <= log_msg->entry_v2.hdr_size) {
- log_msg->entry.len = 0;
- } else {
- log_msg->entry.len = ret - log_msg->entry_v2.hdr_size;
+ if (log_msg->entry.hdr_size != sizeof(log_msg->entry)) {
+ return -EINVAL;
+ }
+
+ if (log_msg->entry.len > ret - log_msg->entry.hdr_size) {
+ return -EINVAL;
}
return ret;
diff --git a/liblog/logprint.cpp b/liblog/logprint.cpp
index 82fbafd..4b61828 100644
--- a/liblog/logprint.cpp
+++ b/liblog/logprint.cpp
@@ -532,18 +532,12 @@
int i;
char* msg = buf->msg;
- struct logger_entry_v2* buf2 = (struct logger_entry_v2*)buf;
- if (buf2->hdr_size) {
- if ((buf2->hdr_size < sizeof(((struct log_msg*)NULL)->entry_v1)) ||
- (buf2->hdr_size > sizeof(((struct log_msg*)NULL)->entry))) {
- fprintf(stderr, "+++ LOG: entry illegal hdr_size\n");
- return -1;
- }
- msg = ((char*)buf2) + buf2->hdr_size;
- if (buf2->hdr_size >= sizeof(struct logger_entry_v4)) {
- entry->uid = ((struct logger_entry_v4*)buf)->uid;
- }
+ if (buf->hdr_size != sizeof(struct logger_entry)) {
+ fprintf(stderr, "+++ LOG: entry illegal hdr_size\n");
+ return -1;
}
+ entry->uid = buf->uid;
+
for (i = 1; i < buf->len; i++) {
if (msg[i] == '\0') {
if (msgStart == -1) {
@@ -993,27 +987,15 @@
entry->pid = buf->pid;
entry->tid = buf->tid;
- /*
- * Pull the tag out, fill in some additional details based on incoming
- * buffer version (v3 adds lid, v4 adds uid).
- */
eventData = (const unsigned char*)buf->msg;
- struct logger_entry_v2* buf2 = (struct logger_entry_v2*)buf;
- if (buf2->hdr_size) {
- if ((buf2->hdr_size < sizeof(((struct log_msg*)NULL)->entry_v1)) ||
- (buf2->hdr_size > sizeof(((struct log_msg*)NULL)->entry))) {
- fprintf(stderr, "+++ LOG: entry illegal hdr_size\n");
- return -1;
- }
- eventData = ((unsigned char*)buf2) + buf2->hdr_size;
- if ((buf2->hdr_size >= sizeof(struct logger_entry_v3)) &&
- (((struct logger_entry_v3*)buf)->lid == LOG_ID_SECURITY)) {
- entry->priority = ANDROID_LOG_WARN;
- }
- if (buf2->hdr_size >= sizeof(struct logger_entry_v4)) {
- entry->uid = ((struct logger_entry_v4*)buf)->uid;
- }
+ if (buf->hdr_size != sizeof(struct logger_entry)) {
+ fprintf(stderr, "+++ LOG: entry illegal hdr_size\n");
+ return -1;
}
+ if (buf->lid == LOG_ID_SECURITY) {
+ entry->priority = ANDROID_LOG_WARN;
+ }
+ entry->uid = buf->uid;
inCount = buf->len;
if (inCount < sizeof(android_event_header_t)) return -1;
auto* event_header = reinterpret_cast<const android_event_header_t*>(eventData);
@@ -1069,9 +1051,6 @@
if ((result == 1) && fmtStr) {
/* We overflowed :-(, let's repaint the line w/o format dressings */
eventData = (const unsigned char*)buf->msg;
- if (buf2->hdr_size) {
- eventData = ((unsigned char*)buf2) + buf2->hdr_size;
- }
eventData += 4;
outBuf = messageBuf;
outRemaining = messageBufLen - 1;
diff --git a/liblog/pmsg_reader.cpp b/liblog/pmsg_reader.cpp
index ce923f3..f43ce3a 100644
--- a/liblog/pmsg_reader.cpp
+++ b/liblog/pmsg_reader.cpp
@@ -144,7 +144,7 @@
((logger_list->start.tv_sec != buf.l.realtime.tv_sec) ||
(logger_list->start.tv_nsec <= buf.l.realtime.tv_nsec)))) &&
(!logger_list->pid || (logger_list->pid == buf.p.pid))) {
- char* msg = log_msg->entry_v4.msg;
+ char* msg = log_msg->entry.msg;
*msg = buf.prio;
fd = atomic_load(&transp->context.fd);
if (fd <= 0) {
@@ -158,16 +158,16 @@
return -EIO;
}
- log_msg->entry_v4.len = buf.p.len - sizeof(buf) + sizeof(buf.prio);
- log_msg->entry_v4.hdr_size = sizeof(log_msg->entry_v4);
- log_msg->entry_v4.pid = buf.p.pid;
- log_msg->entry_v4.tid = buf.l.tid;
- log_msg->entry_v4.sec = buf.l.realtime.tv_sec;
- log_msg->entry_v4.nsec = buf.l.realtime.tv_nsec;
- log_msg->entry_v4.lid = buf.l.id;
- log_msg->entry_v4.uid = buf.p.uid;
+ log_msg->entry.len = buf.p.len - sizeof(buf) + sizeof(buf.prio);
+ log_msg->entry.hdr_size = sizeof(log_msg->entry);
+ log_msg->entry.pid = buf.p.pid;
+ log_msg->entry.tid = buf.l.tid;
+ log_msg->entry.sec = buf.l.realtime.tv_sec;
+ log_msg->entry.nsec = buf.l.realtime.tv_nsec;
+ log_msg->entry.lid = buf.l.id;
+ log_msg->entry.uid = buf.p.uid;
- return ret + sizeof(buf.prio) + log_msg->entry_v4.hdr_size;
+ return ret + sizeof(buf.prio) + log_msg->entry.hdr_size;
}
fd = atomic_load(&transp->context.fd);
@@ -215,7 +215,7 @@
struct android_log_transport_context transp;
struct content {
struct listnode node;
- struct logger_entry_v4 entry;
+ struct logger_entry entry;
} * content;
struct names {
struct listnode node;
@@ -267,25 +267,26 @@
}
/* Read the file content */
- while (pmsgRead(&logger_list, &transp, &transp.logMsg) > 0) {
+ log_msg log_msg;
+ while (pmsgRead(&logger_list, &transp, &log_msg) > 0) {
const char* cp;
- size_t hdr_size = transp.logMsg.entry.hdr_size ? transp.logMsg.entry.hdr_size
- : sizeof(transp.logMsg.entry_v1);
- char* msg = (char*)&transp.logMsg + hdr_size;
+ size_t hdr_size = log_msg.entry.hdr_size;
+
+ char* msg = (char*)&log_msg + hdr_size;
const char* split = NULL;
- if ((hdr_size < sizeof(transp.logMsg.entry_v1)) || (hdr_size > sizeof(transp.logMsg.entry))) {
+ if (hdr_size != sizeof(log_msg.entry)) {
continue;
}
/* Check for invalid sequence number */
- if ((transp.logMsg.entry.nsec % ANDROID_LOG_PMSG_FILE_SEQUENCE) ||
- ((transp.logMsg.entry.nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >=
- ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE)) {
+ if (log_msg.entry.nsec % ANDROID_LOG_PMSG_FILE_SEQUENCE ||
+ (log_msg.entry.nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >=
+ ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE) {
continue;
}
/* Determine if it has <dirbase>:<filebase> format for tag */
- len = transp.logMsg.entry.len - sizeof(prio);
+ len = log_msg.entry.len - sizeof(prio);
for (cp = msg + sizeof(prio); *cp && isprint(*cp) && !isspace(*cp) && --len; ++cp) {
if (*cp == ':') {
if (split) {
@@ -331,8 +332,8 @@
/* check if there is an existing entry */
list_for_each(node, &name_list) {
names = node_to_item(node, struct names, node);
- if (!strcmp(names->name, msg + sizeof(prio)) && (names->id == transp.logMsg.entry.lid) &&
- (names->prio == *msg)) {
+ if (!strcmp(names->name, msg + sizeof(prio)) && names->id == log_msg.entry.lid &&
+ names->prio == *msg) {
break;
}
}
@@ -349,7 +350,7 @@
break;
}
strcpy(names->name, msg + sizeof(prio));
- names->id = static_cast<log_id_t>(transp.logMsg.entry.lid);
+ names->id = static_cast<log_id_t>(log_msg.entry.lid);
names->prio = *msg;
list_init(&names->content);
/*
@@ -402,7 +403,7 @@
/* Remove any file fragments that match our sequence number */
list_for_each_safe(node, n, &names->content) {
content = node_to_item(node, struct content, node);
- if (transp.logMsg.entry.nsec == content->entry.nsec) {
+ if (log_msg.entry.nsec == content->entry.nsec) {
list_remove(&content->node);
free(content);
}
@@ -410,16 +411,16 @@
/* Add content */
content = static_cast<struct content*>(
- calloc(1, sizeof(content->node) + hdr_size + transp.logMsg.entry.len));
+ calloc(1, sizeof(content->node) + hdr_size + log_msg.entry.len));
if (!content) {
ret = -ENOMEM;
break;
}
- memcpy(&content->entry, &transp.logMsg.entry, hdr_size + transp.logMsg.entry.len);
+ memcpy(&content->entry, &log_msg.entry, hdr_size + log_msg.entry.len);
/* Insert in sequence number sorted order, to ease reconstruction */
list_for_each_reverse(node, &names->content) {
- if ((node_to_item(node, struct content, node))->entry.nsec < transp.logMsg.entry.nsec) {
+ if ((node_to_item(node, struct content, node))->entry.nsec < log_msg.entry.nsec) {
break;
}
}
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 94c4fbb..c402e20 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -385,7 +385,7 @@
fprintf(stderr, "Expect \"Binary log entry conversion failed\"\n");
}
int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
- &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
+ &log_msg.entry, &entry, nullptr, msgBuf, sizeof(msgBuf));
EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer);
if ((processBinaryLogBuffer == 0) || entry.message) {
size_t line_overhead = 20;
@@ -469,8 +469,7 @@
AndroidLogFormat* logformat = android_log_format_new();
EXPECT_TRUE(NULL != logformat);
AndroidLogEntry entry;
- int processLogBuffer =
- android_log_processLogBuffer(&log_msg.entry_v1, &entry);
+ int processLogBuffer = android_log_processLogBuffer(&log_msg.entry, &entry);
EXPECT_EQ(0, processLogBuffer);
if (processLogBuffer == 0) {
size_t line_overhead = 11;
@@ -1013,8 +1012,7 @@
AndroidLogFormat* logformat = android_log_format_new();
EXPECT_TRUE(NULL != logformat);
AndroidLogEntry entry;
- int processLogBuffer =
- android_log_processLogBuffer(&log_msg.entry_v1, &entry);
+ int processLogBuffer = android_log_processLogBuffer(&log_msg.entry, &entry);
EXPECT_EQ(0, processLogBuffer);
if (processLogBuffer == 0) {
fflush(stderr);
@@ -2507,8 +2505,8 @@
EXPECT_TRUE(NULL != logformat);
AndroidLogEntry entry;
char msgBuf[1024];
- int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
- &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
+ int processBinaryLogBuffer =
+ android_log_processBinaryLogBuffer(&log_msg.entry, &entry, nullptr, msgBuf, sizeof(msgBuf));
EXPECT_EQ(0, processBinaryLogBuffer);
if (processBinaryLogBuffer == 0) {
int line_overhead = 20;
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index b0f3786..2573b1c 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -239,6 +239,7 @@
"tests/files/offline/bad_eh_frame_hdr_arm64/*",
"tests/files/offline/debug_frame_first_x86/*",
"tests/files/offline/debug_frame_load_bias_arm/*",
+ "tests/files/offline/eh_frame_bias_x86/*",
"tests/files/offline/eh_frame_hdr_begin_x86_64/*",
"tests/files/offline/invalid_elf_offset_arm/*",
"tests/files/offline/jit_debug_arm/*",
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index e34273c..e863f22 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -228,7 +228,7 @@
case PT_GNU_EH_FRAME:
// This is really the pointer to the .eh_frame_hdr section.
eh_frame_hdr_offset_ = phdr.p_offset;
- eh_frame_hdr_section_bias_ = static_cast<uint64_t>(phdr.p_paddr) - phdr.p_offset;
+ eh_frame_hdr_section_bias_ = static_cast<uint64_t>(phdr.p_vaddr) - phdr.p_offset;
eh_frame_hdr_size_ = phdr.p_memsz;
break;
diff --git a/libunwindstack/tests/ElfInterfaceTest.cpp b/libunwindstack/tests/ElfInterfaceTest.cpp
index b048b17..ea27e3e 100644
--- a/libunwindstack/tests/ElfInterfaceTest.cpp
+++ b/libunwindstack/tests/ElfInterfaceTest.cpp
@@ -1310,7 +1310,7 @@
memset(&phdr, 0, sizeof(phdr));
phdr.p_type = PT_GNU_EH_FRAME;
- phdr.p_paddr = addr;
+ phdr.p_vaddr = addr;
phdr.p_offset = offset;
memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index 72eef3e..0d58c09 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -1583,4 +1583,50 @@
EXPECT_EQ(0x7fdd4a4170ULL, unwinder.frames()[11].sp);
}
+TEST_F(UnwindOfflineTest, eh_frame_bias_x86) {
+ ASSERT_NO_FATAL_FAILURE(Init("eh_frame_bias_x86/", ARCH_X86));
+
+ Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
+ unwinder.Unwind();
+
+ std::string frame_info(DumpFrames(unwinder));
+ ASSERT_EQ(11U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
+ EXPECT_EQ(
+ " #00 pc ffffe430 vdso.so (__kernel_vsyscall+16)\n"
+ " #01 pc 00082a4b libc.so (__epoll_pwait+43)\n"
+ " #02 pc 000303a3 libc.so (epoll_pwait+115)\n"
+ " #03 pc 000303ed libc.so (epoll_wait+45)\n"
+ " #04 pc 00010ea2 tombstoned (epoll_dispatch+226)\n"
+ " #05 pc 0000c5e7 tombstoned (event_base_loop+1095)\n"
+ " #06 pc 0000c193 tombstoned (event_base_dispatch+35)\n"
+ " #07 pc 00005c77 tombstoned (main+884)\n"
+ " #08 pc 00015f66 libc.so (__libc_init+102)\n"
+ " #09 pc 0000360e tombstoned (_start+98)\n"
+ " #10 pc 00000001 <unknown>\n",
+ frame_info);
+
+ EXPECT_EQ(0xffffe430ULL, unwinder.frames()[0].pc);
+ EXPECT_EQ(0xfffe1a30ULL, unwinder.frames()[0].sp);
+ EXPECT_EQ(0xeb585a4bULL, unwinder.frames()[1].pc);
+ EXPECT_EQ(0xfffe1a40ULL, unwinder.frames()[1].sp);
+ EXPECT_EQ(0xeb5333a3ULL, unwinder.frames()[2].pc);
+ EXPECT_EQ(0xfffe1a60ULL, unwinder.frames()[2].sp);
+ EXPECT_EQ(0xeb5333edULL, unwinder.frames()[3].pc);
+ EXPECT_EQ(0xfffe1ab0ULL, unwinder.frames()[3].sp);
+ EXPECT_EQ(0xeb841ea2ULL, unwinder.frames()[4].pc);
+ EXPECT_EQ(0xfffe1ae0ULL, unwinder.frames()[4].sp);
+ EXPECT_EQ(0xeb83d5e7ULL, unwinder.frames()[5].pc);
+ EXPECT_EQ(0xfffe1b30ULL, unwinder.frames()[5].sp);
+ EXPECT_EQ(0xeb83d193ULL, unwinder.frames()[6].pc);
+ EXPECT_EQ(0xfffe1bd0ULL, unwinder.frames()[6].sp);
+ EXPECT_EQ(0xeb836c77ULL, unwinder.frames()[7].pc);
+ EXPECT_EQ(0xfffe1c00ULL, unwinder.frames()[7].sp);
+ EXPECT_EQ(0xeb518f66ULL, unwinder.frames()[8].pc);
+ EXPECT_EQ(0xfffe1d00ULL, unwinder.frames()[8].sp);
+ EXPECT_EQ(0xeb83460eULL, unwinder.frames()[9].pc);
+ EXPECT_EQ(0xfffe1d40ULL, unwinder.frames()[9].sp);
+ EXPECT_EQ(0x00000001ULL, unwinder.frames()[10].pc);
+ EXPECT_EQ(0xfffe1d74ULL, unwinder.frames()[10].sp);
+}
+
} // namespace unwindstack
diff --git a/libunwindstack/tests/files/offline/eh_frame_bias_x86/libc.so b/libunwindstack/tests/files/offline/eh_frame_bias_x86/libc.so
new file mode 100644
index 0000000..f3eb615
--- /dev/null
+++ b/libunwindstack/tests/files/offline/eh_frame_bias_x86/libc.so
Binary files differ
diff --git a/libunwindstack/tests/files/offline/eh_frame_bias_x86/maps.txt b/libunwindstack/tests/files/offline/eh_frame_bias_x86/maps.txt
new file mode 100644
index 0000000..7d52483
--- /dev/null
+++ b/libunwindstack/tests/files/offline/eh_frame_bias_x86/maps.txt
@@ -0,0 +1,3 @@
+eb503000-eb5e8000 r-xp 0 00:00 0 libc.so
+eb831000-eb852000 r-xp 0 00:00 0 tombstoned
+ffffe000-fffff000 r-xp 0 00:00 0 vdso.so
diff --git a/libunwindstack/tests/files/offline/eh_frame_bias_x86/regs.txt b/libunwindstack/tests/files/offline/eh_frame_bias_x86/regs.txt
new file mode 100644
index 0000000..821928e
--- /dev/null
+++ b/libunwindstack/tests/files/offline/eh_frame_bias_x86/regs.txt
@@ -0,0 +1,9 @@
+eax: fffffffc
+ebx: 4
+ecx: eb290180
+edx: 20
+ebp: 8
+edi: 0
+esi: ffffffff
+esp: fffe1a30
+eip: ffffe430
diff --git a/libunwindstack/tests/files/offline/eh_frame_bias_x86/stack.data b/libunwindstack/tests/files/offline/eh_frame_bias_x86/stack.data
new file mode 100644
index 0000000..b95bfac
--- /dev/null
+++ b/libunwindstack/tests/files/offline/eh_frame_bias_x86/stack.data
Binary files differ
diff --git a/libunwindstack/tests/files/offline/eh_frame_bias_x86/tombstoned b/libunwindstack/tests/files/offline/eh_frame_bias_x86/tombstoned
new file mode 100644
index 0000000..aefdb6b
--- /dev/null
+++ b/libunwindstack/tests/files/offline/eh_frame_bias_x86/tombstoned
Binary files differ
diff --git a/libunwindstack/tests/files/offline/eh_frame_bias_x86/vdso.so b/libunwindstack/tests/files/offline/eh_frame_bias_x86/vdso.so
new file mode 100644
index 0000000..c71dcfb
--- /dev/null
+++ b/libunwindstack/tests/files/offline/eh_frame_bias_x86/vdso.so
Binary files differ
diff --git a/libunwindstack/tools/unwind_for_offline.cpp b/libunwindstack/tools/unwind_for_offline.cpp
index 4f67d67..64b58a8 100644
--- a/libunwindstack/tools/unwind_for_offline.cpp
+++ b/libunwindstack/tools/unwind_for_offline.cpp
@@ -275,6 +275,9 @@
if (maps_by_start.count(frame.map_start) == 0) {
map_info = maps->Find(frame.map_start);
+ if (map_info == nullptr) {
+ continue;
+ }
auto info = FillInAndGetMapInfo(maps_by_start, map_info);
bool file_copied = false;
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index 0253f2f..2251479 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -184,3 +184,10 @@
],
recovery_available: true,
}
+
+cc_fuzz {
+ name: "libziparchive_fuzzer",
+ srcs: ["libziparchive_fuzzer.cpp"],
+ static_libs: ["libziparchive", "libbase", "libz", "liblog"],
+ host_supported: true,
+}
diff --git a/libziparchive/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h
index e3ac114..391cff9 100644
--- a/libziparchive/include/ziparchive/zip_archive.h
+++ b/libziparchive/include/ziparchive/zip_archive.h
@@ -114,7 +114,7 @@
int32_t OpenArchiveFd(const int fd, const char* debugFileName, ZipArchiveHandle* handle,
bool assume_ownership = true);
-int32_t OpenArchiveFromMemory(void* address, size_t length, const char* debugFileName,
+int32_t OpenArchiveFromMemory(const void* address, size_t length, const char* debugFileName,
ZipArchiveHandle* handle);
/*
* Close archive, releasing resources associated with it. This will
diff --git a/libziparchive/libziparchive_fuzzer.cpp b/libziparchive/libziparchive_fuzzer.cpp
new file mode 100644
index 0000000..75e7939
--- /dev/null
+++ b/libziparchive/libziparchive_fuzzer.cpp
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: Apache-2.0
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <ziparchive/zip_archive.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ ZipArchiveHandle handle = nullptr;
+ OpenArchiveFromMemory(data, size, "fuzz", &handle);
+ CloseArchive(handle);
+ return 0;
+}
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index c95b035..3a552d8 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -178,7 +178,7 @@
#endif
}
-ZipArchive::ZipArchive(void* address, size_t length)
+ZipArchive::ZipArchive(const void* address, size_t length)
: mapped_zip(address, length),
close_file(false),
directory_offset(0),
@@ -471,7 +471,7 @@
return OpenArchiveInternal(archive, fileName);
}
-int32_t OpenArchiveFromMemory(void* address, size_t length, const char* debug_file_name,
+int32_t OpenArchiveFromMemory(const void* address, size_t length, const char* debug_file_name,
ZipArchiveHandle* handle) {
ZipArchive* archive = new ZipArchive(address, length);
*handle = archive;
@@ -1152,7 +1152,7 @@
return fd_;
}
-void* MappedZipFile::GetBasePtr() const {
+const void* MappedZipFile::GetBasePtr() const {
if (has_fd_) {
ALOGW("Zip: MappedZipFile doesn't have a base pointer.");
return nullptr;
@@ -1188,13 +1188,14 @@
ALOGE("Zip: invalid offset: %" PRId64 ", data length: %" PRId64 "\n", off, data_length_);
return false;
}
- memcpy(buf, static_cast<uint8_t*>(base_ptr_) + off, len);
+ memcpy(buf, static_cast<const uint8_t*>(base_ptr_) + off, len);
}
return true;
}
-void CentralDirectory::Initialize(void* map_base_ptr, off64_t cd_start_offset, size_t cd_size) {
- base_ptr_ = static_cast<uint8_t*>(map_base_ptr) + cd_start_offset;
+void CentralDirectory::Initialize(const void* map_base_ptr, off64_t cd_start_offset,
+ size_t cd_size) {
+ base_ptr_ = static_cast<const uint8_t*>(map_base_ptr) + cd_start_offset;
length_ = cd_size;
}
diff --git a/libziparchive/zip_archive_private.h b/libziparchive/zip_archive_private.h
index 30a1d72..60fdec0 100644
--- a/libziparchive/zip_archive_private.h
+++ b/libziparchive/zip_archive_private.h
@@ -95,14 +95,14 @@
explicit MappedZipFile(const int fd)
: has_fd_(true), fd_(fd), base_ptr_(nullptr), data_length_(0) {}
- explicit MappedZipFile(void* address, size_t length)
+ explicit MappedZipFile(const void* address, size_t length)
: has_fd_(false), fd_(-1), base_ptr_(address), data_length_(static_cast<off64_t>(length)) {}
bool HasFd() const { return has_fd_; }
int GetFileDescriptor() const;
- void* GetBasePtr() const;
+ const void* GetBasePtr() const;
off64_t GetFileLength() const;
@@ -117,7 +117,7 @@
const int fd_;
- void* const base_ptr_;
+ const void* const base_ptr_;
const off64_t data_length_;
};
@@ -129,7 +129,7 @@
size_t GetMapLength() const { return length_; }
- void Initialize(void* map_base_ptr, off64_t cd_start_offset, size_t cd_size);
+ void Initialize(const void* map_base_ptr, off64_t cd_start_offset, size_t cd_size);
private:
const uint8_t* base_ptr_;
@@ -177,7 +177,7 @@
ZipStringOffset* hash_table;
ZipArchive(const int fd, bool assume_ownership);
- ZipArchive(void* address, size_t length);
+ ZipArchive(const void* address, size_t length);
~ZipArchive();
bool InitializeCentralDirectory(off64_t cd_start_offset, size_t cd_size);
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 4dcb338..f164a12 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -337,13 +337,12 @@
context->eventTagMap = android_openEventTagMap(nullptr);
context->hasOpenedEventTagMap = true;
}
- err = android_log_processBinaryLogBuffer(
- &buf->entry_v1, &entry, context->eventTagMap, binaryMsgBuf,
- sizeof(binaryMsgBuf));
+ err = android_log_processBinaryLogBuffer(&buf->entry, &entry, context->eventTagMap,
+ binaryMsgBuf, sizeof(binaryMsgBuf));
// printf(">>> pri=%d len=%d msg='%s'\n",
// entry.priority, entry.messageLen, entry.message);
} else {
- err = android_log_processLogBuffer(&buf->entry_v1, &entry);
+ err = android_log_processLogBuffer(&buf->entry, &entry);
}
if ((err < 0) && !context->debug) return;
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index 5c43e18..ec81933 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -245,9 +245,9 @@
}
log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, bool lastSame) {
- struct logger_entry_v4 entry = {};
+ struct logger_entry entry = {};
- entry.hdr_size = sizeof(struct logger_entry_v4);
+ entry.hdr_size = sizeof(struct logger_entry);
entry.lid = mLogId;
entry.pid = mPid;
entry.tid = mTid;
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp
index f19e7b0..0cc7886 100644
--- a/logd/LogTags.cpp
+++ b/logd/LogTags.cpp
@@ -311,9 +311,7 @@
if (log_msg.entry.len <= sizeof(uint32_t)) continue;
uint32_t Tag = get4LE(msg);
if (Tag != TAG_DEF_LOG_TAG) continue;
- uid_t uid = (log_msg.entry.hdr_size >= sizeof(logger_entry_v4))
- ? log_msg.entry.uid
- : AID_ROOT;
+ uid_t uid = log_msg.entry.uid;
std::string Name;
std::string Format;
diff --git a/adb/daemon/reboot_service.h b/logd/fuzz/Android.bp
similarity index 62%
rename from adb/daemon/reboot_service.h
rename to logd/fuzz/Android.bp
index f68913e..299242d 100644
--- a/adb/daemon/reboot_service.h
+++ b/logd/fuzz/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 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.
@@ -13,13 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#pragma once
-
-#include <string>
-
-#include "adb_unique_fd.h"
-
-#if defined(__ANDROID__)
-void reboot_service(unique_fd fd, const std::string& arg);
-#endif
+cc_fuzz {
+ name: "log_buffer_log_fuzzer",
+ srcs: [
+ "log_buffer_log_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libbase",
+ "libcutils",
+ "libselinux",
+ "liblog",
+ "liblogd",
+ "libcutils",
+ ],
+ cflags: ["-Werror"],
+}
diff --git a/logd/fuzz/log_buffer_log_fuzzer.cpp b/logd/fuzz/log_buffer_log_fuzzer.cpp
new file mode 100644
index 0000000..4d1589b
--- /dev/null
+++ b/logd/fuzz/log_buffer_log_fuzzer.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright 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.
+ */
+#include <string>
+
+#include "../LogBuffer.h"
+#include "../LogTimes.h"
+
+// We don't want to waste a lot of entropy on messages
+#define MAX_MSG_LENGTH 5
+
+// Tag IDs usually start at 1000, we only want to try 1000 through 1009
+#define MIN_TAG_ID 1000
+#define TAG_MOD 10
+
+namespace android {
+struct LogInput {
+ public:
+ log_id_t log_id;
+ log_time realtime;
+ uid_t uid;
+ pid_t pid;
+ pid_t tid;
+ unsigned int log_mask;
+};
+
+int write_log_messages(const uint8_t** pdata, size_t* data_left, LogBuffer* log_buffer) {
+ const uint8_t* data = *pdata;
+ const LogInput* logInput = reinterpret_cast<const LogInput*>(data);
+ data += sizeof(LogInput);
+ *data_left -= sizeof(LogInput);
+
+ uint32_t tag = MIN_TAG_ID + data[0] % TAG_MOD;
+ uint8_t msg_length = data[1] % MAX_MSG_LENGTH;
+ if (msg_length < 2) {
+ // Not enough data for message
+ return 0;
+ }
+
+ data += 2 * sizeof(uint8_t);
+ *data_left -= 2 * sizeof(uint8_t);
+
+ if (*data_left < msg_length) {
+ // Not enough data for tag and message
+ *pdata = data;
+ return 0;
+ }
+
+ // We need nullterm'd strings
+ char msg[sizeof(uint32_t) + MAX_MSG_LENGTH + sizeof(char)];
+ char* msg_only = msg + sizeof(uint32_t);
+ memcpy(msg, &tag, sizeof(uint32_t));
+ memcpy(msg_only, data, msg_length);
+ msg_only[msg_length] = '\0';
+ data += msg_length;
+ *data_left -= msg_length;
+
+ // Other elements not in enum.
+ log_id_t log_id = static_cast<log_id_t>(unsigned(logInput->log_id) % (LOG_ID_MAX + 1));
+ log_buffer->log(log_id, logInput->realtime, logInput->uid, logInput->pid, logInput->tid, msg,
+ sizeof(uint32_t) + msg_length + 1);
+ log_buffer->formatStatistics(logInput->uid, logInput->pid, logInput->log_mask);
+ *pdata = data;
+ return 1;
+}
+
+// Because system/core/logd/main.cpp redefines these.
+void prdebug(char const* fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+char* uidToName(uid_t) {
+ return strdup("fake");
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ // We want a random tag length and a random remaining message length
+ if (data == nullptr || size < sizeof(LogInput) + 2 * sizeof(uint8_t)) {
+ return 0;
+ }
+
+ LastLogTimes times;
+ LogBuffer log_buffer(×);
+ size_t data_left = size;
+ const uint8_t** pdata = &data;
+
+ log_buffer.enableStatistics();
+ log_buffer.initPrune(nullptr);
+ // We want to get pruning code to get called.
+ log_id_for_each(i) { log_buffer.setSize(i, 10000); }
+
+ while (data_left >= sizeof(LogInput) + 2 * sizeof(uint8_t)) {
+ if (!write_log_messages(pdata, &data_left, &log_buffer)) {
+ return 0;
+ }
+ }
+
+ log_id_for_each(i) { log_buffer.clear(i); }
+ return 0;
+}
+} // namespace android
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 80625a7..f47bee1 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -241,47 +241,18 @@
static void caught_signal(int /* signum */) {
}
-static void dump_log_msg(const char* prefix, log_msg* msg, unsigned int version,
- int lid) {
+static void dump_log_msg(const char* prefix, log_msg* msg, int lid) {
std::cout << std::flush;
std::cerr << std::flush;
fflush(stdout);
fflush(stderr);
- switch (msg->entry.hdr_size) {
- case 0:
- version = 1;
- break;
+ EXPECT_EQ(sizeof(logger_entry), msg->entry.hdr_size);
- case sizeof(msg->entry_v2): /* PLUS case sizeof(msg->entry_v3): */
- if (version == 0) {
- version = (msg->entry_v3.lid < LOG_ID_MAX) ? 3 : 2;
- }
- break;
-
- case sizeof(msg->entry_v4):
- if (version == 0) {
- version = 4;
- }
- break;
- }
-
- fprintf(stderr, "%s: v%u[%u] ", prefix, version, msg->len());
- if (version != 1) {
- fprintf(stderr, "hdr_size=%u ", msg->entry.hdr_size);
- }
- fprintf(stderr, "pid=%u tid=%u %u.%09u ", msg->entry.pid, msg->entry.tid,
- msg->entry.sec, msg->entry.nsec);
- switch (version) {
- case 1:
- break;
- case 2:
- fprintf(stderr, "euid=%u ", msg->entry_v2.euid);
- break;
- case 3:
- default:
- lid = msg->entry.lid;
- break;
- }
+ fprintf(stderr, "%s: [%u] ", prefix, msg->len());
+ fprintf(stderr, "hdr_size=%u ", msg->entry.hdr_size);
+ fprintf(stderr, "pid=%u tid=%u %u.%09u ", msg->entry.pid, msg->entry.tid, msg->entry.sec,
+ msg->entry.nsec);
+ lid = msg->entry.lid;
switch (lid) {
case 0:
@@ -584,11 +555,11 @@
}
if (content_wrap) {
- dump_log_msg("wrap", &msg_wrap, 3, -1);
+ dump_log_msg("wrap", &msg_wrap, -1);
}
if (content_timeout) {
- dump_log_msg("timeout", &msg_timeout, 3, -1);
+ dump_log_msg("timeout", &msg_timeout, -1);
}
EXPECT_TRUE(written);
@@ -721,11 +692,11 @@
}
if (content_wrap) {
- dump_log_msg("wrap", &msg_wrap, 3, -1);
+ dump_log_msg("wrap", &msg_wrap, -1);
}
if (content_timeout) {
- dump_log_msg("timeout", &msg_timeout, 3, -1);
+ dump_log_msg("timeout", &msg_timeout, -1);
}
if (content_wrap || !content_timeout) {
@@ -776,7 +747,7 @@
EXPECT_TRUE(read_one);
if (read_one) {
- dump_log_msg("user", &msg, 3, -1);
+ dump_log_msg("user", &msg, -1);
}
fprintf(stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo);
@@ -794,7 +765,7 @@
EXPECT_EQ(0, recv_ret);
if (recv_ret > 0) {
- dump_log_msg("user", &msg, 3, -1);
+ dump_log_msg("user", &msg, -1);
}
EXPECT_EQ(0, save_errno);
diff --git a/reboot/Android.bp b/reboot/Android.bp
index 805fd9a..cc71723 100644
--- a/reboot/Android.bp
+++ b/reboot/Android.bp
@@ -5,4 +5,5 @@
srcs: ["reboot.c"],
shared_libs: ["libcutils"],
cflags: ["-Werror"],
+ recovery_available: true,
}
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index e1bb02f..5241730 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -326,7 +326,7 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_SAMEPROCESS_LIBRARIES),.vendor)
+$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_SAMEPROCESS_LIBRARIES),.com.android.vndk.current)
$(LOCAL_BUILT_MODULE):
@echo "Generate: $@"
@mkdir -p $(dir $@)
@@ -342,7 +342,7 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_CORE_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_CORE_LIBRARIES),.vendor)
+$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_CORE_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_CORE_LIBRARIES),.com.android.vndk.current)
$(LOCAL_BUILT_MODULE):
@echo "Generate: $@"
@mkdir -p $(dir $@)
@@ -358,7 +358,7 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_PRIVATE_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_PRIVATE_LIBRARIES),.vendor)
+$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_PRIVATE_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_PRIVATE_LIBRARIES),.com.android.vndk.current)
$(LOCAL_BUILT_MODULE):
@echo "Generate: $@"
@mkdir -p $(dir $@)
diff --git a/set-verity-state/.clang-format b/set-verity-state/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/set-verity-state/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/set-verity-state/Android.bp b/set-verity-state/Android.bp
new file mode 100644
index 0000000..cd8c8c5
--- /dev/null
+++ b/set-verity-state/Android.bp
@@ -0,0 +1,24 @@
+// Copyright 2019 The Android Open Source Project
+
+cc_binary {
+ name: "set-verity-state",
+ srcs: ["set-verity-state.cpp"],
+ shared_libs: [
+ "libbase",
+ "libcrypto",
+ "libcrypto_utils",
+ "libcutils",
+ "libfec",
+ "libfs_mgr",
+ "liblog",
+ ],
+ static_libs: [
+ "libavb_user",
+ ],
+
+ cflags: ["-Werror"],
+ symlinks: [
+ "enable-verity",
+ "disable-verity",
+ ],
+}
diff --git a/set-verity-state/set-verity-state.cpp b/set-verity-state/set-verity-state.cpp
new file mode 100644
index 0000000..0a26aba
--- /dev/null
+++ b/set-verity-state/set-verity-state.cpp
@@ -0,0 +1,274 @@
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libavb_user/libavb_user.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <fs_mgr.h>
+#include <fs_mgr_overlayfs.h>
+#include <fstab/fstab.h>
+#include <log/log_properties.h>
+
+#include "fec/io.h"
+
+#ifdef ALLOW_DISABLE_VERITY
+static const bool kAllowDisableVerity = true;
+#else
+static const bool kAllowDisableVerity = false;
+#endif
+
+using android::base::unique_fd;
+
+static void suggest_run_adb_root() {
+ if (getuid() != 0) printf("Maybe run adb root?\n");
+}
+
+static bool make_block_device_writable(const std::string& dev) {
+ unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC));
+ if (fd == -1) {
+ return false;
+ }
+
+ int OFF = 0;
+ bool result = (ioctl(fd.get(), BLKROSET, &OFF) != -1);
+ return result;
+}
+
+/* Turn verity on/off */
+static bool set_verity_enabled_state(const char* block_device, const char* mount_point,
+ bool enable) {
+ if (!make_block_device_writable(block_device)) {
+ printf("Could not make block device %s writable (%s).\n", block_device, strerror(errno));
+ return false;
+ }
+
+ fec::io fh(block_device, O_RDWR);
+
+ if (!fh) {
+ printf("Could not open block device %s (%s).\n", block_device, strerror(errno));
+ suggest_run_adb_root();
+ return false;
+ }
+
+ fec_verity_metadata metadata;
+
+ if (!fh.get_verity_metadata(metadata)) {
+ printf("Couldn't find verity metadata!\n");
+ return false;
+ }
+
+ if (!enable && metadata.disabled) {
+ printf("Verity already disabled on %s\n", mount_point);
+ return false;
+ }
+
+ if (enable && !metadata.disabled) {
+ printf("Verity already enabled on %s\n", mount_point);
+ return false;
+ }
+
+ if (!fh.set_verity_status(enable)) {
+ printf("Could not set verity %s flag on device %s with error %s\n",
+ enable ? "enabled" : "disabled", block_device, strerror(errno));
+ return false;
+ }
+
+ auto change = false;
+ errno = 0;
+ if (enable ? fs_mgr_overlayfs_teardown(mount_point, &change)
+ : fs_mgr_overlayfs_setup(nullptr, mount_point, &change)) {
+ if (change) {
+ printf("%s overlayfs for %s\n", enable ? "disabling" : "using", mount_point);
+ }
+ } else if (errno) {
+ int expected_errno = enable ? EBUSY : ENOENT;
+ if (errno != expected_errno) {
+ printf("Overlayfs %s for %s failed with error %s\n", enable ? "teardown" : "setup",
+ mount_point, strerror(errno));
+ }
+ }
+ printf("Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point);
+ return true;
+}
+
+/* Helper function to get A/B suffix, if any. If the device isn't
+ * using A/B the empty string is returned. Otherwise either "_a",
+ * "_b", ... is returned.
+ */
+static std::string get_ab_suffix() {
+ return android::base::GetProperty("ro.boot.slot_suffix", "");
+}
+
+static bool is_avb_device_locked() {
+ return android::base::GetProperty("ro.boot.vbmeta.device_state", "") == "locked";
+}
+
+static bool overlayfs_setup(bool enable) {
+ auto change = false;
+ errno = 0;
+ if (enable ? fs_mgr_overlayfs_teardown(nullptr, &change)
+ : fs_mgr_overlayfs_setup(nullptr, nullptr, &change)) {
+ if (change) {
+ printf("%s overlayfs\n", enable ? "disabling" : "using");
+ }
+ } else if (errno) {
+ printf("Overlayfs %s failed with error %s\n", enable ? "teardown" : "setup", strerror(errno));
+ suggest_run_adb_root();
+ }
+ return change;
+}
+
+/* Use AVB to turn verity on/off */
+static bool set_avb_verity_enabled_state(AvbOps* ops, bool enable_verity) {
+ std::string ab_suffix = get_ab_suffix();
+ bool verity_enabled;
+
+ if (is_avb_device_locked()) {
+ printf("Device is locked. Please unlock the device first\n");
+ return false;
+ }
+
+ if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
+ printf("Error getting verity state. Try adb root first?\n");
+ return false;
+ }
+
+ if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) {
+ printf("verity is already %s\n", verity_enabled ? "enabled" : "disabled");
+ return false;
+ }
+
+ if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) {
+ printf("Error setting verity\n");
+ return false;
+ }
+
+ overlayfs_setup(enable_verity);
+ printf("Successfully %s verity\n", enable_verity ? "enabled" : "disabled");
+ return true;
+}
+
+int main(int argc, char* argv[]) {
+ if (argc == 0) {
+ LOG(FATAL) << "set-verity-state called with empty argv";
+ }
+
+ std::optional<bool> enable_opt;
+ std::string procname = android::base::Basename(argv[0]);
+ if (procname == "enable-verity") {
+ enable_opt = true;
+ } else if (procname == "disable-verity") {
+ enable_opt = false;
+ }
+
+ if (!enable_opt.has_value()) {
+ if (argc != 2) {
+ printf("usage: %s [1|0]\n", argv[0]);
+ return 1;
+ }
+
+ if (strcmp(argv[1], "1") == 0) {
+ enable_opt = true;
+ } else if (strcmp(argv[1], "0") == 0) {
+ enable_opt = false;
+ } else {
+ printf("usage: %s [1|0]\n", argv[0]);
+ return 1;
+ }
+ }
+
+ bool enable = enable_opt.value();
+
+ bool any_changed = false;
+
+ // Figure out if we're using VB1.0 or VB2.0 (aka AVB) - by
+ // contract, androidboot.vbmeta.digest is set by the bootloader
+ // when using AVB).
+ bool using_avb = !android::base::GetProperty("ro.boot.vbmeta.digest", "").empty();
+
+ // If using AVB, dm-verity is used on any build so we want it to
+ // be possible to disable/enable on any build (except USER). For
+ // VB1.0 dm-verity is only enabled on certain builds.
+ if (!using_avb) {
+ if (!kAllowDisableVerity) {
+ printf("%s only works for userdebug builds\n", argv[0]);
+ }
+
+ if (!android::base::GetBoolProperty("ro.secure", false)) {
+ overlayfs_setup(enable);
+ printf("verity not enabled - ENG build\n");
+ return 0;
+ }
+ }
+
+ // Should never be possible to disable dm-verity on a USER build
+ // regardless of using AVB or VB1.0.
+ if (!__android_log_is_debuggable()) {
+ printf("verity cannot be disabled/enabled - USER build\n");
+ return 0;
+ }
+
+ if (using_avb) {
+ // Yep, the system is using AVB.
+ AvbOps* ops = avb_ops_user_new();
+ if (ops == nullptr) {
+ printf("Error getting AVB ops\n");
+ return 1;
+ }
+ if (set_avb_verity_enabled_state(ops, enable)) {
+ any_changed = true;
+ }
+ avb_ops_user_free(ops);
+ } else {
+ // Not using AVB - assume VB1.0.
+
+ // read all fstab entries at once from all sources
+ android::fs_mgr::Fstab fstab;
+ if (!android::fs_mgr::ReadDefaultFstab(&fstab)) {
+ printf("Failed to read fstab\n");
+ suggest_run_adb_root();
+ return 0;
+ }
+
+ // Loop through entries looking for ones that verity manages.
+ for (const auto& entry : fstab) {
+ if (entry.fs_mgr_flags.verify) {
+ if (set_verity_enabled_state(entry.blk_device.c_str(), entry.mount_point.c_str(), enable)) {
+ any_changed = true;
+ }
+ }
+ }
+ }
+ if (!any_changed) any_changed = overlayfs_setup(enable);
+
+ if (any_changed) {
+ printf("Now reboot your device for settings to take effect\n");
+ }
+
+ return 0;
+}