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

Commit cbf799ec authored by Aayush Gupta's avatar Aayush Gupta Committed by Bruno Martins
Browse files

vendor: Drop verity tool

Disabling AVB (1.0 & 2.0) is now done with flags in board and in kernel.
In both cases, it's done device-side by default.
Henceforth, drop the tool as isn't even built nor shipped.

Reference:
[0]: https://review.lineageos.org/q/If1d641c8ce4598864a9aa6f23dbf2ac7bdddd4cf
[1]: https://review.lineageos.org/q/I381feef8f6fefc8449ca50d85d704b67bcc8a77e
[2]: https://review.lineageos.org/q/I97f1169a7cfccc78530b9869a407b3a9eade31ab



Signed-off-by: default avatarAayush Gupta <aayushgupta219@gmail.com>
Change-Id: If39f2b943b8af83ded6b183738f2f4e91cab13be
parent 5061962d
Loading
Loading
Loading
Loading

verity_tool/Android.bp

deleted100644 → 0
+0 −28
Original line number Diff line number Diff line
// Copyright 2018 The LineageOS Project

cc_library {
    name: "libveritytool",
    srcs: ["verity_tool.cpp"],
    local_include_dirs: ["include"],
    export_include_dirs: ["include"],
    cflags: ["-Werror"],
    shared_libs: [
        "libbase",
        "libcrypto",
        "libcrypto_utils",
        "libfec",
    ],
    static_libs: [
        "libfs_mgr",
    ],
    whole_static_libs: [
        "libavb_user",
    ],
}

cc_binary {
    name: "veritytool",
    srcs: ["main.cpp"],
    shared_libs: ["libveritytool"],
    cflags: ["-Werror"],
}

verity_tool/include/verity_tool.h

deleted100644 → 0
+0 −51
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The LineageOS 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 <string>

typedef enum {
    VERITY_STATE_UNKNOWN,
    VERITY_STATE_NO_DEVICE,
    VERITY_STATE_DISABLED,
    VERITY_STATE_ENABLED,
    VERITY_STATE_MAX = VERITY_STATE_ENABLED
} verity_state_t;

/*
 * Return codes:
 *
 *    true: verity state set
 *    false: verity state not set
 */
bool set_block_device_verity_enabled(const std::string& block_device,
                                     bool enable);

/*
 * Return codes:
 *
 *    verity state (unknown, disabled, enabled)
 */
verity_state_t get_verity_state();

/*
 * Return codes:
 *
 *    true: verity state set for all block devices
 *    false: verity state not for set all block devices
 */
bool set_verity_enabled(bool enable);

verity_tool/main.cpp

deleted100644 → 0
+0 −87
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The LineageOS 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 "verity_tool.h"

#include <getopt.h>
#include <stdio.h>
#include <string.h>

static void print_usage() {
    printf("veritytool - toggle block device verification\n"
           "    --help        show this help\n"
           "    --enable      enable dm-verity\n"
           "    --disable     disable dm-verity\n"
           "    --show        show current dm-verity state\n");
}

int main(int argc, char** argv) {
    int c, rc;
    int enable = 0;
    int show = 0;
    bool flag_set = false;
    struct option long_opts[] = {
        {"disable", no_argument, &enable, 0},
        {"enable", no_argument, &enable, 1},
        {"show", no_argument, &show, 1},
        {NULL, 0, NULL, 0},
    };

    while ((c = getopt_long(argc, argv, "des", long_opts, NULL)) != -1) {
        switch (c) {
            case 0:
                flag_set = true;
                break;
            default:
                print_usage();
                exit(0);
        }
    }

    if (!flag_set) {
        print_usage();
        exit(0);
    }

    if (show) {
        printf("dm-verity state: ");
        switch (get_verity_state()) {
            case VERITY_STATE_NO_DEVICE:
                printf("NO DEVICE");
                break;
            case VERITY_STATE_DISABLED:
                printf("DISABLED");
                break;
            case VERITY_STATE_ENABLED:
                printf("ENABLED");
                break;
            default:
                printf("UNKNOWN");
                break;
        }
        printf("\n");
        return 0;
    }

    if (!set_verity_enabled(enable)) {
        printf("Error occurred in set_verity_enable\n");
        exit(EXIT_FAILURE);
    }

    printf("Set verity mode to: %s\n", enable ? "enabled" : "disabled");
    printf("Now reboot your device for settings to take effect\n");
    return 0;
}

verity_tool/verity_tool.cpp

deleted100644 → 0
+0 −255
Original line number Diff line number Diff line
/*
 * 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.
 */

#include "verity_tool.h"

#include <android-base/logging.h>
#include <android-base/properties.h>
#include <fs_mgr.h>
#include <fec/io.h>
#include <libavb_user/libavb_user.h>

#include <linux/fs.h>

#include <errno.h>

static int make_block_device_writable(const std::string& block_device) {
    int fd = open(block_device.c_str(), O_RDONLY | O_CLOEXEC);
    if (fd < 0) {
        return -errno;
    }

    int OFF = 0;
    int rc = ioctl(fd, BLKROSET, &OFF);
    if (rc < 0) {
        rc = -errno;
        goto out;
    }
    rc = 0;
out:
    close(fd);
    return rc;
}

/* Turn verity on/off */
bool set_block_device_verity_enabled(const std::string& block_device,
        bool enable) {
    int rc = make_block_device_writable(block_device);
    if (rc) {
        LOG(ERROR) << "Could not make block device "
                   << block_device << " writable:" << rc;
        return false;
    }

    fec::io fh(block_device, O_RDWR);
    if (!fh) {
        PLOG(ERROR) << "Could not open block device " << block_device;
        return false;
    }

    fec_verity_metadata metadata;
    if (!fh.get_verity_metadata(metadata)) {
        LOG(ERROR) << "Couldn't find verity metadata!";
        return false;
    }

    if (!enable && metadata.disabled) {
        LOG(ERROR) << "Verity already disabled on " << block_device;
        return false;
    }

    if (enable && !metadata.disabled) {
        LOG(WARNING) << "Verity already enabled on " << block_device;
        return false;
    }

    if (!fh.set_verity_status(enable)) {
        PLOG(ERROR) << "Could not set verity "
                    << (enable ? "enabled" : "disabled")
                    << " flag on device " << block_device;
        return false;
    }

    LOG(DEBUG) << "Verity " << (enable ? "enabled" : "disabled")
               << " on " << block_device;
    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.
 *
 * Note that since sometime in O androidboot.slot_suffix is deprecated
 * and androidboot.slot should be used instead. Since bootloaders may
 * be out of sync with the OS, we check both and for extra safety
 * prepend a leading underscore if there isn't one already.
 */
static std::string get_ab_suffix() {
    std::string ab_suffix = android::base::GetProperty("ro.boot.slot_suffix", "");
    if (ab_suffix.empty()) {
        ab_suffix = android::base::GetProperty("ro.boot.slot", "");
    }
    if (ab_suffix.size() > 0 && ab_suffix[0] != '_') {
        ab_suffix = std::string("_") + ab_suffix;
    }
    return ab_suffix;
}

verity_state_t get_verity_state() {
    verity_state_t rc = VERITY_STATE_NO_DEVICE;
    std::string ab_suffix = get_ab_suffix();

    // 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) {
        // Yep, the system is using AVB.
        AvbOps* ops = avb_ops_user_new();
        if (ops == nullptr) {
            LOG(ERROR) << "Error getting AVB ops";
            avb_ops_user_free(ops);
            return VERITY_STATE_UNKNOWN;
        }
        bool verity_enabled;
        if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
            LOG(ERROR) << "Error getting verity state";
            avb_ops_user_free(ops);
            return VERITY_STATE_UNKNOWN;
        }
        rc = verity_enabled ? VERITY_STATE_ENABLED : VERITY_STATE_DISABLED;
        avb_ops_user_free(ops);
    } else {
        // Not using AVB - assume VB1.0.

        // read all fstab entries at once from all sources
        struct fstab* fstab = fs_mgr_read_fstab_default();
        if (!fstab) {
            LOG(ERROR) << "Failed to read fstab";
            fs_mgr_free_fstab(fstab);
            return VERITY_STATE_UNKNOWN;
        }

        // Loop through entries looking for ones that vold manages.
        for (int i = 0; i < fstab->num_entries; i++) {
            if (fs_mgr_is_verified(&fstab->recs[i])) {
                std::string block_device = fstab->recs[i].blk_device;
                fec::io fh(block_device, O_RDONLY);
                if (!fh) {
                    PLOG(ERROR) << "Could not open block device " << block_device;
                    rc = VERITY_STATE_UNKNOWN;
                    break;
                }

                fec_verity_metadata metadata;
                if (!fh.get_verity_metadata(metadata)) {
                    LOG(ERROR) << "Couldn't find verity metadata!";
                    rc = VERITY_STATE_UNKNOWN;
                    break;
                }

                rc = metadata.disabled ? VERITY_STATE_DISABLED : VERITY_STATE_ENABLED;
            }
        }
        fs_mgr_free_fstab(fstab);
    }

    return rc;
}

/* 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 (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
        LOG(ERROR) << "Error getting verity state";
        return false;
    }

    if ((verity_enabled && enable_verity) ||
        (!verity_enabled && !enable_verity)) {
        LOG(WARNING) << "verity is already "
                     << verity_enabled ? "enabled" : "disabled";
        return false;
    }

    if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) {
        LOG(ERROR) << "Error setting verity";
        return false;
    }

    LOG(DEBUG) << "Successfully " << (enable_verity ? "enabled" : "disabled")
               << " verity";
    return true;
}

bool set_verity_enabled(bool enable) {
    bool rc = true;

    // Do not allow changing verity on user builds
    bool is_user = (android::base::GetProperty("ro.build.type", "") == "user");
    if (is_user) {
        LOG(ERROR) << "Cannot disable verity - USER BUILD";
        return 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) {
        // Yep, the system is using AVB.
        AvbOps* ops = avb_ops_user_new();
        if (ops == nullptr) {
            LOG(ERROR) << "Error getting AVB ops";
            return false;
        }
        rc = set_avb_verity_enabled_state(ops, enable);
        avb_ops_user_free(ops);
    } else {
        // Not using AVB - assume VB1.0.

        // read all fstab entries at once from all sources
        struct fstab* fstab = fs_mgr_read_fstab_default();
        if (!fstab) {
            LOG(ERROR) << "Failed to read fstab";
            return false;
        }

        // Loop through entries looking for ones that vold manages.
        for (int i = 0; i < fstab->num_entries; i++) {
            if (fs_mgr_is_verified(&fstab->recs[i])) {
                bool result = set_block_device_verity_enabled(
                        fstab->recs[i].blk_device, enable);
                if (!result) {
                    // Warn, but continue if failure occurred
                    LOG(WARNING) << "Failed to set state "
                                 << (enable ? "enabled" : "disabled")
                                 << " on " << fstab->recs[i].mount_point;
                }
                rc = rc && result;
            }
        }
    }

    return rc;
}