Loading set-verity-state/Android.bp +0 −3 Original line number Diff line number Diff line Loading @@ -11,10 +11,7 @@ cc_binary { "libbase", "libcrypto", "libcrypto_utils", "libcutils", "libfs_mgr_binder", "liblog", "libutils", ], static_libs: [ "libavb_user", Loading set-verity-state/set-verity-state.cpp +59 −53 Original line number Diff line number Diff line Loading @@ -14,85 +14,105 @@ * limitations under the License. */ #include <errno.h> #include <libavb_user/libavb_user.h> #include <stdio.h> #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/properties.h> #include <fs_mgr_overlayfs.h> #include <log/log_properties.h> #include <libavb_user/libavb_user.h> using namespace std::string_literals; namespace { #ifdef ALLOW_DISABLE_VERITY static const bool kAllowDisableVerity = true; const bool kAllowDisableVerity = true; #else static const bool kAllowDisableVerity = false; const bool kAllowDisableVerity = false; #endif static void suggest_run_adb_root() { if (getuid() != 0) printf("Maybe run adb root?\n"); } /* 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() { std::string get_ab_suffix() { return android::base::GetProperty("ro.boot.slot_suffix", ""); } static bool is_avb_device_locked() { bool is_avb_device_locked() { return android::base::GetProperty("ro.boot.vbmeta.device_state", "") == "locked"; } static bool overlayfs_setup(bool enable) { bool is_debuggable() { return android::base::GetBoolProperty("ro.debuggable", false); } bool is_using_avb() { // 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). return !android::base::GetProperty("ro.boot.vbmeta.digest", "").empty(); } 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"); LOG(INFO) << (enable ? "disabling" : "using") << " overlayfs"; } } else if (errno) { printf("Overlayfs %s failed with error %s\n", enable ? "teardown" : "setup", strerror(errno)); suggest_run_adb_root(); PLOG(ERROR) << "Failed to " << (enable ? "teardown" : "setup") << " overlayfs"; } return change; } /* Use AVB to turn verity on/off */ static bool set_avb_verity_enabled_state(AvbOps* ops, bool enable_verity) { 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"); LOG(ERROR) << "Device is locked. Please unlock the device first"; return false; } if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) { printf("Error getting verity state. Try adb root first?\n"); LOG(ERROR) << "Error getting verity state"; return false; } if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) { printf("verity is already %s\n", verity_enabled ? "enabled" : "disabled"); LOG(INFO) << "verity is already " << (verity_enabled ? "enabled" : "disabled"); return false; } if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) { printf("Error setting verity\n"); LOG(ERROR) << "Error setting verity state"; return false; } printf("Successfully %s verity\n", enable_verity ? "enabled" : "disabled"); LOG(INFO) << "Successfully " << (enable_verity ? "enabled" : "disabled") << " verity"; return true; } void MyLogger(android::base::LogId id, android::base::LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message) { // Hide log starting with '[fs_mgr]' unless it's an error. if (severity == android::base::ERROR || message[0] != '[') { fprintf(stderr, "%s\n", message); } static auto logd = android::base::LogdLogger(); logd(id, severity, tag, file, line, message); } } // namespace int main(int argc, char* argv[]) { android::base::InitLogging(argv, MyLogger); if (argc == 0) { LOG(FATAL) << "set-verity-state called with empty argv"; } Loading @@ -110,44 +130,30 @@ int main(int argc, char* argv[]) { return 1; } // 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 (!kAllowDisableVerity || !is_debuggable()) { errno = EPERM; PLOG(ERROR) << "Cannot disable/enable verity on user build"; return 1; } if (!android::base::GetBoolProperty("ro.secure", false)) { overlayfs_setup(enable); printf("verity not enabled - ENG build\n"); return 0; } if (getuid() != 0) { errno = EACCES; PLOG(ERROR) << "Must be running as root (adb root)"; return 1; } // 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 (!is_using_avb()) { LOG(ERROR) << "Expected AVB device, VB1.0 is no longer supported"; return 1; } bool any_changed = false; if (using_avb) { // Yep, the system is using AVB. AvbOps* ops = avb_ops_user_new(); if (ops == nullptr) { printf("Error getting AVB ops\n"); std::unique_ptr<AvbOps, decltype(&avb_ops_user_free)> ops(avb_ops_user_new(), &avb_ops_user_free); if (!ops) { LOG(ERROR) << "Error getting AVB ops"; return 1; } any_changed |= set_avb_verity_enabled_state(ops, enable); avb_ops_user_free(ops); } bool any_changed = set_avb_verity_enabled_state(ops.get(), enable); any_changed |= overlayfs_setup(enable); if (any_changed) { Loading Loading
set-verity-state/Android.bp +0 −3 Original line number Diff line number Diff line Loading @@ -11,10 +11,7 @@ cc_binary { "libbase", "libcrypto", "libcrypto_utils", "libcutils", "libfs_mgr_binder", "liblog", "libutils", ], static_libs: [ "libavb_user", Loading
set-verity-state/set-verity-state.cpp +59 −53 Original line number Diff line number Diff line Loading @@ -14,85 +14,105 @@ * limitations under the License. */ #include <errno.h> #include <libavb_user/libavb_user.h> #include <stdio.h> #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/properties.h> #include <fs_mgr_overlayfs.h> #include <log/log_properties.h> #include <libavb_user/libavb_user.h> using namespace std::string_literals; namespace { #ifdef ALLOW_DISABLE_VERITY static const bool kAllowDisableVerity = true; const bool kAllowDisableVerity = true; #else static const bool kAllowDisableVerity = false; const bool kAllowDisableVerity = false; #endif static void suggest_run_adb_root() { if (getuid() != 0) printf("Maybe run adb root?\n"); } /* 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() { std::string get_ab_suffix() { return android::base::GetProperty("ro.boot.slot_suffix", ""); } static bool is_avb_device_locked() { bool is_avb_device_locked() { return android::base::GetProperty("ro.boot.vbmeta.device_state", "") == "locked"; } static bool overlayfs_setup(bool enable) { bool is_debuggable() { return android::base::GetBoolProperty("ro.debuggable", false); } bool is_using_avb() { // 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). return !android::base::GetProperty("ro.boot.vbmeta.digest", "").empty(); } 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"); LOG(INFO) << (enable ? "disabling" : "using") << " overlayfs"; } } else if (errno) { printf("Overlayfs %s failed with error %s\n", enable ? "teardown" : "setup", strerror(errno)); suggest_run_adb_root(); PLOG(ERROR) << "Failed to " << (enable ? "teardown" : "setup") << " overlayfs"; } return change; } /* Use AVB to turn verity on/off */ static bool set_avb_verity_enabled_state(AvbOps* ops, bool enable_verity) { 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"); LOG(ERROR) << "Device is locked. Please unlock the device first"; return false; } if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) { printf("Error getting verity state. Try adb root first?\n"); LOG(ERROR) << "Error getting verity state"; return false; } if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) { printf("verity is already %s\n", verity_enabled ? "enabled" : "disabled"); LOG(INFO) << "verity is already " << (verity_enabled ? "enabled" : "disabled"); return false; } if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) { printf("Error setting verity\n"); LOG(ERROR) << "Error setting verity state"; return false; } printf("Successfully %s verity\n", enable_verity ? "enabled" : "disabled"); LOG(INFO) << "Successfully " << (enable_verity ? "enabled" : "disabled") << " verity"; return true; } void MyLogger(android::base::LogId id, android::base::LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message) { // Hide log starting with '[fs_mgr]' unless it's an error. if (severity == android::base::ERROR || message[0] != '[') { fprintf(stderr, "%s\n", message); } static auto logd = android::base::LogdLogger(); logd(id, severity, tag, file, line, message); } } // namespace int main(int argc, char* argv[]) { android::base::InitLogging(argv, MyLogger); if (argc == 0) { LOG(FATAL) << "set-verity-state called with empty argv"; } Loading @@ -110,44 +130,30 @@ int main(int argc, char* argv[]) { return 1; } // 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 (!kAllowDisableVerity || !is_debuggable()) { errno = EPERM; PLOG(ERROR) << "Cannot disable/enable verity on user build"; return 1; } if (!android::base::GetBoolProperty("ro.secure", false)) { overlayfs_setup(enable); printf("verity not enabled - ENG build\n"); return 0; } if (getuid() != 0) { errno = EACCES; PLOG(ERROR) << "Must be running as root (adb root)"; return 1; } // 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 (!is_using_avb()) { LOG(ERROR) << "Expected AVB device, VB1.0 is no longer supported"; return 1; } bool any_changed = false; if (using_avb) { // Yep, the system is using AVB. AvbOps* ops = avb_ops_user_new(); if (ops == nullptr) { printf("Error getting AVB ops\n"); std::unique_ptr<AvbOps, decltype(&avb_ops_user_free)> ops(avb_ops_user_new(), &avb_ops_user_free); if (!ops) { LOG(ERROR) << "Error getting AVB ops"; return 1; } any_changed |= set_avb_verity_enabled_state(ops, enable); avb_ops_user_free(ops); } bool any_changed = set_avb_verity_enabled_state(ops.get(), enable); any_changed |= overlayfs_setup(enable); if (any_changed) { Loading