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

Commit 9de748f7 authored by Sandeep Patil's avatar Sandeep Patil
Browse files

fs_mgr: add a generic fs_mgr_get_boot_config internal API

depending on when fs_mgr is trying to read the configuration passed into
the kernel commandline, it may be able to read it successfully.
Specially in the case when init has not initialized properties.

This change adds a new fs_mgr_get_boot_config() API to be used by all
fs_mgr code in order to get filesystem parameters specified in kernel
command line or device tree. This way the fs_mgr code doesn't have to
handle the "early" cases separately anywhere.

Test:
Tested angler boot with both /system and /vendor mounted in init
first stage.
Tested sailfish to make sure /vendor can be continued to be
mounted early without verity

Change-Id: I9a44cdfc32681f714c5d73ae55c3deda95c02545
parent e9da79bd
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -25,7 +25,8 @@ LOCAL_SRC_FILES:= \
    fs_mgr_slotselect.cpp \
    fs_mgr_verity.cpp \
    fs_mgr_avb.cpp \
    fs_mgr_avb_ops.cpp
    fs_mgr_avb_ops.cpp \
    fs_mgr_boot_config.cpp
LOCAL_C_INCLUDES := \
    $(LOCAL_PATH)/include \
    system/vold \
+15 −9
Original line number Diff line number Diff line
@@ -441,19 +441,24 @@ static bool get_hashtree_descriptor(const std::string& partition_name,

static bool init_is_avb_used() {
    // When AVB is used, boot loader should set androidboot.vbmeta.{hash_alg,
    // size, digest} in kernel cmdline. They will then be imported by init
    // process to system properties: ro.boot.vbmeta.{hash_alg, size, digest}.
    // size, digest} in kernel cmdline or in device tree. They will then be
    // imported by init process to system properties: ro.boot.vbmeta.{hash_alg, size, digest}.
    //
    // In case of early mount, init properties are not initialized, so we also
    // ensure we look into kernel command line and device tree if the property is
    // not found
    //
    // Checks hash_alg as an indicator for whether AVB is used.
    // We don't have to parse and check all of them here. The check will
    // be done in fs_mgr_load_vbmeta_images() and FS_MGR_SETUP_AVB_FAIL will
    // be returned when there is an error.

    std::string hash_alg = android::base::GetProperty("ro.boot.vbmeta.hash_alg", "");

    std::string hash_alg;
    if (fs_mgr_get_boot_config("vbmeta.hash_alg", &hash_alg) == 0) {
        if (hash_alg == "sha256" || hash_alg == "sha512") {
            return true;
        }
    }

    return false;
}
@@ -483,9 +488,10 @@ int fs_mgr_load_vbmeta_images(struct fstab* fstab) {
    // of HASH partitions into fs_mgr_avb_verify_data, which is not required as
    // fs_mgr only deals with HASHTREE partitions.
    const char *requested_partitions[] = {nullptr};
    const char* ab_suffix = android::base::GetProperty("ro.boot.slot_suffix", "").c_str();
    std::string ab_suffix;
    fs_mgr_get_boot_config("slot_suffix", &ab_suffix);
    AvbSlotVerifyResult verify_result =
        avb_slot_verify(fs_mgr_avb_ops, requested_partitions, ab_suffix,
        avb_slot_verify(fs_mgr_avb_ops, requested_partitions, ab_suffix.c_str(),
                        fs_mgr_vbmeta_prop.allow_verification_error, &fs_mgr_avb_verify_data);

    // Only allow two verify results:
+71 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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 <android-base/file.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/properties.h>

#include "fs_mgr_priv.h"

// Tries to get the boot config value in properties, kernel cmdline and
// device tree (in that order).  returns 'true' if successfully found, 'false'
// otherwise
bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) {
    FS_MGR_CHECK(out_val != nullptr);

    // first check if we have "ro.boot" property already
    *out_val = android::base::GetProperty("ro.boot." + key, "");
    if (!out_val->empty()) {
        return true;
    }

    // fallback to kernel cmdline, properties may not be ready yet
    std::string cmdline;
    std::string cmdline_key("androidboot." + key);
    if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
        for (const auto& entry : android::base::Split(android::base::Trim(cmdline), " ")) {
            std::vector<std::string> pieces = android::base::Split(entry, "=");
            if (pieces.size() == 2) {
                if (pieces[0] == cmdline_key) {
                    *out_val = pieces[1];
                    return true;
                }
            }
        }
    }

    // lastly, check the device tree
    static const std::string android_dt_dir("/proc/device-tree/firmware/android");
    std::string file_name = android_dt_dir + "/compatible";
    std::string dt_value;
    if (android::base::ReadFileToString(file_name, &dt_value)) {
        if (dt_value != "android,firmware") {
            LERROR << "Error finding compatible android DT node";
            return false;
        }

        file_name = android_dt_dir + "/" + key;
        // DT entries terminate with '\0' but so do the properties
        if (android::base::ReadFileToString(file_name, out_val)) {
            return true;
        }

        LERROR << "Error finding '" << key << "' in device tree";
    }

    return false;
}
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <android-base/logging.h>
#include <fs_mgr.h>
#include "fs_mgr_priv_boot_config.h"

/* The CHECK() in logging.h will use program invocation name as the tag.
 * Thus, the log will have prefix "init: " when libfs_mgr is statically
+25 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#ifndef __CORE_FS_MGR_PRIV_BOOTCONFIG_H
#define __CORE_FS_MGR_PRIV_BOOTCONFIG_H

#include <sys/cdefs.h>
#include <string>

bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val);

#endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */
Loading