Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2db51770 authored by Yi-yo Chiang's avatar Yi-yo Chiang Committed by Gerrit Code Review
Browse files

Merge "set-verity-state: Refactor & remove even more dead code"

parents f78b2d17 6bb1acb2
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -11,10 +11,7 @@ cc_binary {
        "libbase",
        "libcrypto",
        "libcrypto_utils",
        "libcutils",
        "libfs_mgr_binder",
        "liblog",
        "libutils",
    ],
    static_libs: [
        "libavb_user",
+59 −53
Original line number Diff line number Diff line
@@ -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";
  }
@@ -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) {