android11.0(R) data分区节点加密控制分析

简介: android11.0(R) data分区节点加密控制分析

前情提要


androidQ(10.0) 预装集成apk到data分区

Android O、P、Q 版本如何预装 APK


遇到问题


当然是和之前一样啦,开机并不能正常启动,而是


自动进入了 recovery 界面,且界面显示


Can’t load Android system. You’r data may be corrupt.If you continue to get this message, you may


need to perform a factory data reset and erase all user data stored on this devices.


按照提示我进行了恢复出厂操作,恢复出厂后能正常开机。但是预装的app没了,很明显预装app会没了。


按照之前 Q 版本的经验去修改代码后,问题依旧,还是不能正常开机,这就离谱,难道谷歌把这个地方给


堵死了???这还能难倒我么,上才艺。


解决办法


跳过 data 分区下 app 目录加密策略读取和设置即可

system/core/init/util.cpp

@@ -88,7 +88,7 @@ static FscryptAction FscryptInferAction(const std::string& dir)
// Special case various directories that must not be encrypted,
    // often because their subdirectories must be encrypted.
    // This isn't a nice way to do this, see b/26641735
    std::vector<std::string> directories_to_exclude = {
            "lost+found", "system_ce", "system_de", "misc_ce",     "misc_de",
            "vendor_ce",  "vendor_de", "media",     "data",        "user",
-     "user_de",    "apex",      "preloads",  "app-staging", "gsi",
+            "user_de",    "apex",      "preloads",  "app-staging", "gsi", "app",
    };
    for (const auto& d : directories_to_exclude) {
        if ((prefix + d) == dir) {
            return FscryptAction::kNone;
        }
    }

跳过 init.rc 中 /data/app 节点加密

system/core/rootdir/init.rc

+++ b/alps/system/core/rootdir/init.rc
@@ -658,7 +658,7 @@ on post-fs-data
     mkdir /data/app-ephemeral 0771 system system encryption=Require
     mkdir /data/app-asec 0700 root root encryption=Require
     mkdir /data/app-lib 0771 system system encryption=Require
-    mkdir /data/app 0771 system system encryption=Require
+    mkdir /data/app 0771 system system encryption=None
     mkdir /data/property 0700 root root encryption=Require
     mkdir /data/tombstones 0771 system system encryption=Require
     mkdir /data/vendor/tombstones 0771 root root

分析过程


当然要打开串口 Log 记录呀,它又不是那么简单的。R 版本的串口打开修改地方如下

kernel-4.19\drivers\misc\mediatek\mtprintk\mtk_printk_ctrl.c


@@ -43,7 +43,7 @@ module_param_named(disable_uart, printk_ctrl, int, 0644);
 bool mt_get_uartlog_status(void)
 {
        if (printk_ctrl == 1)
-               return false;
+               return true;
        else if ((printk_ctrl == 0) || (printk_ctrl == 2))
                return true;
        return true;
@@ -53,7 +53,7 @@ void mt_disable_uart(void)
 {
        /* uart print not always enable */
        if (printk_ctrl != 2)
-               printk_ctrl = 1;
+               printk_ctrl = 0;
 }
 EXPORT_SYMBOL_GPL(mt_disable_uart);

vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c

@@ -1345,7 +1345,7 @@ int boot_linux_fdt(void *kernel, unsigned *tags,
 #endif
                                cmdline_append("mtk_printk_ctrl.disable_uart=0");
                        else
-                               cmdline_append("mtk_printk_ctrl.disable_uart=1");
+                               cmdline_append("mtk_printk_ctrl.disable_uart=0");
                        break;
                case BUILD_TYPE_USERDEBUG:
@@ -1355,13 +1355,13 @@ int boot_linux_fdt(void *kernel, unsigned *tags,
 #else
                            (is_meta_log_disable() == 1))
 #endif
-                               cmdline_append("mtk_printk_ctrl.disable_uart=1 slub_debug=O");
+                               cmdline_append("mtk_printk_ctrl.disable_uart=0 slub_debug=O");
 #ifdef LOG_STORE_SUPPORT
                        else if (boot_ftrace && g_boot_arg->log_dynamic_switch == 0)
 #else
                        else if (boot_ftrace)
 #endif
-                               cmdline_append("mtk_printk_ctrl.disable_uart=1 slub_debug=-");
+                               cmdline_append("mtk_printk_ctrl.disable_uart=0 slub_debug=-");
                        else
                                cmdline_append("mtk_printk_ctrl.disable_uart=0");
                        break;
@@ -1369,7 +1369,7 @@ int boot_linux_fdt(void *kernel, unsigned *tags,
                case BUILD_TYPE_ENG:
                        if ((g_boot_mode == META_BOOT) && is_meta_log_disable &&
                            (is_meta_log_disable() == 1))
-                               cmdline_append("mtk_printk_ctrl.disable_uart=1 slub_debug=O");
+                               cmdline_append("mtk_printk_ctrl.disable_uart=0 slub_debug=O");
                        else
                                cmdline_append("mtk_printk_ctrl.disable_uart=0 ddebug_query=\"file *mediatek* +p ; file *gpu* =_\"");
                        break;


重新编译烧写开机得到如下串口日志

[   13.654157] <4>.(4)[1:init]init 21: [13623][0]Switched to default mount namespace
[   13.655223] <4>.(4)[1:init]init 21: [13624][0]Not setting encryption policy on: /data/apex
[   13.663218] <4>.(4)[1:init]init 21: [13632][0]Not setting encryption policy on: /data/app-staging
[   13.666087] <4>.(4)[1:init]init 21: [13635][0]starting service 'apexd'...
) failed: No such file or directory
[   13.677980] <4>.(4)[1:init]init 25: [13644][0]Encryption policy of /data/misc set to d27f72eaf61213e463b2a9ec48dae65d v2 modes 1/4 flags 0x2
d input file '/data/misc/recovery/ro.build.fingerprint': open() failed: No such file or directory
ata/misc/recovery/proc/version': open() failed: No such file or directory
[   13.692959] <7>.(7)[456:apexd]apexd: Scanning /system/apex for preinstalled data
[   13.698614] <1>.(1)[456:apexd]apexd: Scanning /system_ext/apex for preinstalled data
[   13.699725] <1>.(1)[456:apexd]apexd: ... does not exist. Skipping
path.utils.link]=[stopped]13507 [init.svc_debug_pid.mtk.plpath.utils.link]=[]13507 [dev.mnt.blk.data]=[dm-7]13509 [init.svc.apexd]=[running]13639 [ro.boottime.apexd]=[13638876462]13640 [init.svc_debug_pid.apexd]=[456]13641 Done
[   13.700519] <1>.(1)[456:apexd]apexd: Scanning /product/apex for preinstalled data
[   13.706583] <1>.(1)[456:apexd]apexd: ... does not exist. Skipping
[   13.707396] <1>.(1)[456:apexd]apexd: Scanning /vendor/apex for preinstalled data
[   13.708382] <1>.(1)[456:apexd]apexd: ... does not exist. Skipping
[   13.709166] <1>.(1)[456:apexd]apexd: Populating APEX database from mounts...
[   13.710720] <1>.(1)[456:apexd]apexd: 0 packages restored.
[   13.711617] <1>.(1)[456:apexd]apexd: Marking APEXd as starting
[   13.730259] <3>.(3)[1:init]init 25: [13698][0]Encryption policy of /data/local set to d27f72eaf61213e463b2a9ec48dae65d v2 modes 1/4 flags 0x2
[   13.745616] <1>.(1)[456:apexd]EXT4-fs (loop6): mounted filesystem without journal. Opts: (null)
[   13.758344] <3>.(3)[1:init]init 25: [13727][0]Not setting encryption policy on: /data/preloads
[   13.762309] <3>.(3)[1:init]init 25: [13730][0]Encryption policy of /data/vendor set to d27f72eaf61213e463b2a9ec48dae65d v2 modes 1/4 flags 0x2
[   13.764161] <3>.(3)[1:init]init 25: [13733][0]Not setting encryption policy on: /data/vendor_ce
[   13.766555] <3>.(3)[1:init]init 25: [13735][0]Not setting encryption policy on: /data/vendor_de
[   13.773079] <3>.(3)[1:init]init 25: [13742][0]Not setting encryption policy on: /data/data
[   13.776787] <1>.(1)[456:apexd]EXT4-fs (loop7): mounted filesystem without journal. Opts: (null)
[   13.777475] <3>.(3)[1:init]init 21: [13745][0]Encryption policy of /data/app-private set to d27f72eaf61213e463b2a9ec48dae65d v2 modes 1/4 flags 0x2
[   13.781923] <0>.(0)[1:init]init 21: [13749][0]Encryption policy of /data/app-ephemeral set to d27f72eaf61213e463b2a9ec48dae65d v2 modes 1/4 flags 0x2
[   13.785340] <0>.(0)[1:init]init 21: [13753][0]Encryption policy of /data/app-asec set to d27f72eaf61213e463b2a9ec48dae65d v2 modes 1/4 flags 0x2
[   13.788729] <0>.(0)[1:init]init 21: [13756][0]Encryption policy of /data/app-lib set to d27f72eaf61213e463b2a9ec48dae65d v2 modes 1/4 flags 0x2
[   13.790485] <0>.(0)[1:init]init 21: [13759][0]Inferred action different from explicit one, expected 0 but got 2
[   13.792434] <0>.(0)[1:init]init 21: [13759][0]Failed to set encryption policy of /data/app to d27f72eaf61213e463b2a9ec48dae65d v2 modes 1/4 flags 0x2: Directory not empty
:s0 tclass=file permissive=1
[   13.800279] <2>.(2)[1:init]ls 21: [13759][0]executing ls failed: No such file or directory
[   13.800313] <2>.(1)[462:init]logwrapper 21: executing ls failed: No such file or directory
[   13.800321] <2>.(1)[462:init]logwrapper 21: 
[   13.805673] <2>.(2)[1:init]ls 21: [13759][0]ls terminated by exit(255)
[   13.806716] <2>.(2)[1:init]init: 1 output lines suppressed due to ratelimiting
[   13.807641] <2>.(2)[1:init]init 25: [13759][0]ls -laZ /data/app returned failure: 255
[   13.808723] <2>.(2)[1:init]init 25: [13759][0]Setting d27f72eaf61213e463b2a9ec48dae65d policy on /data/app failed!
[   13.809210] <0>.(0)[456:apexd]EXT4-fs (loop8): mounted filesystem without journal. Opts: (null)
[   13.810098] <2>.(2)[1:init]init 25: [13759][0]Rebooting into recovery


和原来还是一样的配方,错误提示


Failed to set encryption policy of /data/app to d27f72eaf61213e463b2a9ec48dae65d v2 modes 1/4 flags 0x2: Directory not empty


R 版本上谷歌对 libfscrypt 这块进行了重构,代码移到了 system/core/init/util.cpp 中


现在来看下整体的流程,切入点从 init.rc 开始


mkdir /data/app 0771 system system encryption=Require


相比较 Q 版本的 init.rc R 多出了 encryption=Require 属性,就是这个属性决定了 boot


阶段需要检查文件加密情况。mkdir 指令应该调用 builtins 中 do_mkdir(args) 方法


system\core\init\builtins.cpp

// mkdir <path> [mode] [owner] [group] [<option> ...]
static Result<void> do_mkdir(const BuiltinArguments& args) {
    auto options = ParseMkdir(args.args);
    if (!options.ok()) return options.error();
    return make_dir_with_options(*options);
}
static Result<void> make_dir_with_options(const MkdirOptions& options) {
    std::string ref_basename;
    if (options.ref_option == "ref") {
        ref_basename = fscrypt_key_ref;
    } else if (options.ref_option == "per_boot_ref") {
        ref_basename = fscrypt_key_per_boot_ref;
    } else {
        return Error() << "Unknown key option: '" << options.ref_option << "'";
    }
    struct stat mstat;
    if (lstat(options.target.c_str(), &mstat) != 0) {
        if (errno != ENOENT) {
            return ErrnoError() << "lstat() failed on " << options.target;
        }
        if (!make_dir(options.target, options.mode)) {
            return ErrnoErrorIgnoreEnoent() << "mkdir() failed on " << options.target;
        }
        if (lstat(options.target.c_str(), &mstat) != 0) {
            return ErrnoError() << "lstat() failed on new " << options.target;
        }
    }
    if (!S_ISDIR(mstat.st_mode)) {
        return Error() << "Not a directory on " << options.target;
    }
    bool needs_chmod = (mstat.st_mode & ~S_IFMT) != options.mode;
    if ((options.uid != static_cast<uid_t>(-1) && options.uid != mstat.st_uid) ||
        (options.gid != static_cast<gid_t>(-1) && options.gid != mstat.st_gid)) {
        if (lchown(options.target.c_str(), options.uid, options.gid) == -1) {
            return ErrnoError() << "lchown failed on " << options.target;
        }
        // chown may have cleared S_ISUID and S_ISGID, chmod again
        needs_chmod = true;
    }
    if (needs_chmod) {
        if (fchmodat(AT_FDCWD, options.target.c_str(), options.mode, AT_SYMLINK_NOFOLLOW) == -1) {
            return ErrnoError() << "fchmodat() failed on " << options.target;
        }
    }
    if (fscrypt_is_native()) {
        if (!FscryptSetDirectoryPolicy(ref_basename, options.fscrypt_action, options.target)) {
            return reboot_into_recovery(
                    {"--prompt_and_wipe_data", "--reason=set_policy_failed:"s + options.target});
        }
    }
    return {};
}


可以看到其中调用 ParseMkdir(args.args) 获取 options,然后根据 options 创建文件夹,


如果过程中没遇到问题,则 return {} 可以看到出问题的时候进入 recovery 界面,应该是走的


reboot_into_recovery(

{"–prompt_and_wipe_data", "–reason=set_policy_failed:"s + options.target})


那么来看下 FscryptSetDirectoryPolicy() 方法是如何判断的


system\core\init\fscrypt_init_extensions.cpp

bool FscryptSetDirectoryPolicy(const std::string& ref_basename, FscryptAction action,
                               const std::string& dir) {
    if (action == FscryptAction::kNone) {
        return true;
    }
    if (SetPolicyOn(ref_basename, dir) || action == FscryptAction::kAttempt) {
        return true;
    }
    if (action == FscryptAction::kDeleteIfNecessary) {
        LOG(ERROR) << "Setting policy failed, deleting: " << dir;
        delete_dir_contents(dir);
        return SetPolicyOn(ref_basename, dir);
    }
    return false;
}

可以看到要想不进入 recovery 界面,action 为 FscryptAction::kNone 即可,也就是跳过


action 的取值 options.fscrypt_action,回到 builtins.cpp 中关注 auto options = ParseMkdir(args.args);


system\core\init\util.cpp

Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args) {
    mode_t mode = 0755;
    Result<uid_t> uid = -1;
    Result<gid_t> gid = -1;
  //第一次赋值 fscrypt_action,FscryptInferAction() 和之前一样有白名单可跳过
    FscryptAction fscrypt_inferred_action = FscryptInferAction(args[1]);
    FscryptAction fscrypt_action = fscrypt_inferred_action;
    std::string ref_option = "ref";
    bool set_option_encryption = false;
    bool set_option_key = false;
    for (size_t i = 2; i < args.size(); i++) {
        switch (i) {
            case 2:
                mode = std::strtoul(args[2].c_str(), 0, 8);
                break;
            case 3:
                uid = DecodeUid(args[3]);
                if (!uid.ok()) {
                    return Error()
                           << "Unable to decode UID for '" << args[3] << "': " << uid.error();
                }
                break;
            case 4:
                gid = DecodeUid(args[4]);
                if (!gid.ok()) {
                    return Error()
                           << "Unable to decode GID for '" << args[4] << "': " << gid.error();
                }
                break;
            default:
                auto parts = android::base::Split(args[i], "=");
                if (parts.size() != 2) {
                    return Error() << "Can't parse option: '" << args[i] << "'";
                }
                auto optname = parts[0];
                auto optval = parts[1];
        //第二次赋值 fscrypt_action,根据 optval 值再次判断
        //这里增加 log 打印后发现 optname = encryption  optval = Require/None 在init.rc中配置
                if (optname == "encryption") {
                    if (set_option_encryption) {
                        return Error() << "Duplicated option: '" << optname << "'";
                    }
                    if (optval == "Require") {
                        fscrypt_action = FscryptAction::kRequire;
                    } else if (optval == "None") {
                        fscrypt_action = FscryptAction::kNone;
                    } else if (optval == "Attempt") {
                        fscrypt_action = FscryptAction::kAttempt;
                    } else if (optval == "DeleteIfNecessary") {
                        fscrypt_action = FscryptAction::kDeleteIfNecessary;
                    } else {
                        return Error() << "Unknown encryption option: '" << optval << "'";
                    }
                    set_option_encryption = true;
                } else if (optname == "key") {
                    if (set_option_key) {
                        return Error() << "Duplicated option: '" << optname << "'";
                    }
                    if (optval == "ref" || optval == "per_boot_ref") {
                        ref_option = optval;
                    } else {
                        return Error() << "Unknown key option: '" << optval << "'";
                    }
                    set_option_key = true;
                } else {
                    return Error() << "Unknown option: '" << args[i] << "'";
                }
        }
    }
    if (set_option_key && fscrypt_action == FscryptAction::kNone) {
        return Error() << "Key option set but encryption action is none";
    }
    const std::string prefix = "/data/";
    if (StartsWith(args[1], prefix) &&
        args[1].find_first_of('/', prefix.size()) == std::string::npos) {
        if (!set_option_encryption) {
            LOG(WARNING) << "Top-level directory needs encryption action, eg mkdir " << args[1]
                         << " <mode> <uid> <gid> encryption=Require";
        }
        if (fscrypt_action == FscryptAction::kNone) {
            LOG(INFO) << "Not setting encryption policy on: " << args[1];
        }
    }
    if (fscrypt_action != fscrypt_inferred_action) {
        LOG(WARNING) << "Inferred action different from explicit one, expected "
                     << static_cast<int>(fscrypt_inferred_action) << " but got "
                     << static_cast<int>(fscrypt_action);
    }
  //构建 options 返回
    return MkdirOptions{args[1], mode, *uid, *gid, fscrypt_action, ref_option};
}
static FscryptAction FscryptInferAction(const std::string& dir) {
    const std::string prefix = "/data/";
    if (!android::base::StartsWith(dir, prefix)) {
        return FscryptAction::kNone;
    }
    // Special-case /data/media/obb per b/64566063
    if (dir == "/data/media/obb") {
        // Try to set policy on this directory, but if it is non-empty this may fail.
        return FscryptAction::kAttempt;
    }
    // Only set policy on first level /data directories
    // To make this less restrictive, consider using a policy file.
    // However this is overkill for as long as the policy is simply
    // to apply a global policy to all /data folders created via makedir
    if (dir.find_first_of('/', prefix.size()) != std::string::npos) {
        return FscryptAction::kNone;
    }
    // Special case various directories that must not be encrypted,
    // often because their subdirectories must be encrypted.
    // This isn't a nice way to do this, see b/26641735
    std::vector<std::string> directories_to_exclude = {
            "lost+found", "system_ce", "system_de", "misc_ce",     "misc_de",
            "vendor_ce",  "vendor_de", "media",     "data",        "user",
            "user_de",    "apex",      "preloads",  "app-staging", "gsi", 
    };
  //在 directories_to_exclude 集合中则跳过
    for (const auto& d : directories_to_exclude) {
        if ((prefix + d) == dir) {
            return FscryptAction::kNone;
        }
    }
    // Empty these directories if policy setting fails.
    std::vector<std::string> wipe_on_failure = {
            "rollback", "rollback-observer",  // b/139193659
            "connsyslog", "debuglogger", "ramdump",
            "mdlog", "log_temp", "aee_exp", "mdl",
    };
    for (const auto& d : wipe_on_failure) {
        if ((prefix + d) == dir) {
            return FscryptAction::kDeleteIfNecessary;
        }
    }
    return FscryptAction::kRequire;
}

可以看到这样正常的流程就走完了,接下来看下错误的流程

回到 fscrypt_init_extensions.cpp 中

bool FscryptSetDirectoryPolicy(const std::string& ref_basename, FscryptAction action,
                               const std::string& dir) {
    if (action == FscryptAction::kNone) {
        return true;
    }
    if (SetPolicyOn(ref_basename, dir) || action == FscryptAction::kAttempt) {
        return true;
    }
    if (action == FscryptAction::kDeleteIfNecessary) {
        LOG(ERROR) << "Setting policy failed, deleting: " << dir;
        delete_dir_contents(dir);
        return SetPolicyOn(ref_basename, dir);
    }
    return false;
}
static bool SetPolicyOn(const std::string& ref_basename, const std::string& dir) {
    EncryptionPolicy policy;
    if (!LookupPolicy(ref_basename, &policy)) return false;
    if (!EnsurePolicyOrLog(policy, dir)) return false;
    return true;
}
static bool EnsurePolicyOrLog(const EncryptionPolicy& policy, const std::string& dir) {
    if (!EnsurePolicy(policy, dir)) {
        std::string ref_hex;
        BytesToHex(policy.key_raw_ref, &ref_hex);
        LOG(ERROR) << "Setting " << ref_hex << " policy on " << dir << " failed!";
        return false;
    }
    return true;
}


最终调用到 system\extras\libfscrypt\fscrypt.cpp

bool EnsurePolicy(const EncryptionPolicy& policy, const std::string& directory) {
    union {
        fscrypt_policy_v1 v1;
        fscrypt_policy_v2 v2;
    } kern_policy;
    memset(&kern_policy, 0, sizeof(kern_policy));
    switch (policy.options.version) {
        case 1:
            if (policy.key_raw_ref.size() != FSCRYPT_KEY_DESCRIPTOR_SIZE) {
                LOG(ERROR) << "Invalid key descriptor length for v1 policy: "
                           << policy.key_raw_ref.size();
                return false;
            }
            // Careful: FSCRYPT_POLICY_V1 is actually 0 in the API, so make sure
            // to use it here instead of a literal 1.
            kern_policy.v1.version = FSCRYPT_POLICY_V1;
            kern_policy.v1.contents_encryption_mode = policy.options.contents_mode;
            kern_policy.v1.filenames_encryption_mode = policy.options.filenames_mode;
            kern_policy.v1.flags = policy.options.flags;
            policy.key_raw_ref.copy(reinterpret_cast<char*>(kern_policy.v1.master_key_descriptor),
                                    FSCRYPT_KEY_DESCRIPTOR_SIZE);
            break;
        case 2:
            if (policy.key_raw_ref.size() != FSCRYPT_KEY_IDENTIFIER_SIZE) {
                LOG(ERROR) << "Invalid key identifier length for v2 policy: "
                           << policy.key_raw_ref.size();
                return false;
            }
            kern_policy.v2.version = FSCRYPT_POLICY_V2;
            kern_policy.v2.contents_encryption_mode = policy.options.contents_mode;
            kern_policy.v2.filenames_encryption_mode = policy.options.filenames_mode;
            kern_policy.v2.flags = policy.options.flags;
            policy.key_raw_ref.copy(reinterpret_cast<char*>(kern_policy.v2.master_key_identifier),
                                    FSCRYPT_KEY_IDENTIFIER_SIZE);
            break;
        default:
            LOG(ERROR) << "Invalid encryption policy version: " << policy.options.version;
            return false;
    }
    android::base::unique_fd fd(open(directory.c_str(), O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC));
    if (fd == -1) {
        PLOG(ERROR) << "Failed to open directory " << directory;
        return false;
    }
    bool already_encrypted = fscrypt_is_encrypted(fd);
    // FS_IOC_SET_ENCRYPTION_POLICY will set the policy if the directory is
    // unencrypted; otherwise it will verify that the existing policy matches.
    // Setting the policy will fail if the directory is already nonempty.
    if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, &kern_policy) != 0) {
        std::string reason;
        switch (errno) {
            case EEXIST:
                reason = "The directory already has a different encryption policy.";
                break;
            default:
                reason = strerror(errno);
                break;
        }
        LOG(ERROR) << "Failed to set encryption policy of " << directory << " to "
                   << PolicyDebugString(policy) << ": " << reason;
        if (errno == ENOTEMPTY) {
            log_ls(directory.c_str());
        }
        return false;
    }
    if (already_encrypted) {
        LOG(INFO) << "Verified that " << directory << " has the encryption policy "
                  << PolicyDebugString(policy);
    } else {
        LOG(INFO) << "Encryption policy of " << directory << " set to "
                  << PolicyDebugString(policy);
    }
    return true;
}

重新编译烧写后成功开机的log,可以看到打印了跳过 /data/app/ 相关

[   14.186668] <0>.(0)[1:init]init 16: [14155][0]ccz ParseMkdir encryption policy on: /data/app-lib
[   14.187866] <0>.(0)[1:init]init 16: [14155][0]ccz ParseMkdir encryption optname: encryption
[   14.189007] <0>.(0)[1:init]init 19: [14155][0]ccz ParseMkdir encryption optval: Require
[   14.191729] <0>.(0)[1:init]init 19: [14155][0]Encryption policy of /data/app-lib set to ef2067add1858706a84cc01d25260ea5 v2 modes 1/4 flags 0x2
[   14.193467] <0>.(0)[1:init]init 19: [14162][0]ccz ParseMkdir encryption policy on: /data/app
[   14.194557] <0>.(0)[1:init]init 19: [14162][0]ccz ParseMkdir encryption optname: encryption
[   14.195651] <0>.(0)[1:init]init 19: [14162][0]ccz ParseMkdir encryption optval: None
[   14.196637] <0>.(0)[1:init]init 19: [14162][0]ccz ParseMkdir encryption hook: 
[   14.197555] <0>.(0)[1:init]init 19: [14162][0]Not setting encryption policy on: /data/app
[   14.198574] <5>.(5)[317:init]init 16: [14167][200]ReapLogT PropSet [apexd.status]=[starting]13967 Done
[   14.198737] <0>.(0)[1:init]init 19: [14167][0]ccz ParseMkdir encryption policy on: /data/property
[   14.200913] <0>.(0)[1:init]init 19: [14167][0]ccz ParseMkdir encryption optname: encryption
[   14.201996] <0>.(0)[1:init]init 25: [14167][0]ccz ParseMkdir encryption optval: Require
[   14.204488] <0>.(0)[1:init]init 25: [14167][0]Encryption policy of /data/property set to ef2067add1858706a84cc01d25260ea5 v2 modes 1/4 flags 0x2
[   14.206220] <0>.(0)[1:init]init 25: [14175][0]ccz ParseMkdir encryption policy on: /data/tombstones
[   14.207437] <0>.(0)[1:init]init 25: [14175][0]ccz ParseMkdir encryption optname: encryption
[   14.208516] <0>.(0)[1:init]init 25: [14175][0]ccz ParseMkdir encryption optval: Require
[   14.211116] <0>.(0)[1:init]init 25: [14175][0]Encryption policy of /data/tombstones set to ef2067add1858706a84cc01d25260ea5 v2 modes 1/4 flags 0x2
[   14.212936] <0>.(0)[1:init]init 25: [14181][0]ccz ParseMkdir encryption policy on: /data/vendor/tombstones
[   14.215671] <0>.(0)[1:init]init 25: [14184][0]ccz ParseMkdir encryption policy on: /data/vendor/tombstones/wifi

关于 init.rc 启动可以参考下面

Android Q 开机启动流程

Android的init过程(二):初始化语言(init.rc)解析

目录
相关文章
|
10天前
|
Java Android开发 iOS开发
深入探讨移动操作系统的性能优化:安卓与iOS的对比分析
在现代移动设备中,操作系统的性能优化至关重要。本文从系统架构、内存管理、电池续航和应用程序运行效率等多个维度,深入探讨了安卓(Android)和iOS两大主流移动操作系统的优化策略及其实际效果,旨在为开发者和用户提供更清晰的了解和选择依据。
20 0
|
3天前
|
JavaScript 前端开发 安全
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
|
1天前
|
人工智能 监控 安全
未来金融将如何借助加密货币发展,可以从以下几个方面进行清晰的分析和归纳
**区块链与加密货币推动金融革命:降低交易成本,提高安全,扩大服务范围,赋能智能合约与DeFi,及改变监管方式。加密经济助力金融效率与普惠性,但也伴随风险,需平衡发展与监管。**
|
5天前
|
存储 SQL 安全
网络安全与信息安全:漏洞分析与加密技术探讨
在当今数字化时代,网络安全与信息安全日益成为全球关注的焦点。本文深入探讨了网络安全中的常见漏洞类型及其影响,并介绍了当前流行的加密技术和提升安全意识的方法,旨在为读者提供系统的知识分享与技术探讨。
14 3
|
8天前
|
安全 Android开发 iOS开发
探索Android与iOS开发的差异:平台特性与用户体验的对比分析
在移动应用开发的广阔天地中,Android和iOS两大阵营各据一方。本文将深入探讨这两个操作系统在开发环境、编程语言、用户界面设计及市场分布等方面的主要区别。通过比较分析,我们将揭示各自平台的特有优势,并讨论如何根据目标受众和业务需求选择适合的开发平台。
|
1天前
|
Java Linux API
微信API:探究Android平台下Hook技术的比较与应用场景分析
微信API:探究Android平台下Hook技术的比较与应用场景分析
|
1天前
|
安全 Android开发 iOS开发
探索安卓与iOS开发的差异:平台特性与用户体验的对比分析
移动应用开发的两大阵营——安卓与iOS,各自拥有独特的开发环境、用户群体和市场定位。本文将深入探讨这两个操作系统在应用开发过程中的主要差异,包括编程语言、开发工具、用户界面设计、性能优化、安全性考量以及发布流程等方面。通过比较分析,旨在为开发者提供跨平台开发的见解和策略,以优化应用性能和提升用户体验。
7 0
|
1天前
|
缓存 Java Linux
Android 匿名内存深入分析
Android 匿名内存深入分析
6 0
|
10天前
|
搜索推荐 安全 Android开发
安卓与iOS操作系统的对比分析
在移动设备市场上,安卓和iOS操作系统一直是主要竞争对手。本文将从用户界面、应用生态系统、定制化程度和安全性等方面对安卓和iOS进行对比分析,并探讨两者在不同场景下的适用性。
|
1月前
|
存储 缓存 Android开发
Android系统分区与升级
Android系统分区与升级
48 4