Android源码:init

2024-03-01 1763阅读

温馨提示:这篇文章已超过393天没有更新,请注意相关的内容是否还可用!

/*
 * Copyright (C) 2022 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 
#include 
#include 
#include 
#include 
using namespace android;
using namespace android::init;
const std::vector kValidInputs[] = {
        {"", "cpu", "10", "10"}, {"", "RLIM_CPU", "10", "10"},  {"", "12", "unlimited", "10"},
        {"", "13", "-1", "10"},  {"", "14", "10", "unlimited"}, {"", "15", "10", "-1"},
};
const std::string kValidPaths[] = {
        "/system/etc/init/hw/init.rc",
        "/system/etc/init",
};
const int32_t kMaxBytes = 256;
const std::string kValidInterfaces = "android.frameworks.vr.composer@2.0::IVrComposerClient";
class InitParserFuzzer {
  public:
    InitParserFuzzer(const uint8_t* data, size_t size) : fdp_(data, size){};
    void Process();
  private:
    void InvokeParser();
    void InvokeLimitParser();
    void InvokeInterfaceUtils();
    InterfaceInheritanceHierarchyMap GenerateHierarchyMap();
    std::vector GenerateInterfaceMetadata();
    FuzzedDataProvider fdp_;
};
void InitParserFuzzer::InvokeLimitParser() {
    if (fdp_.ConsumeBool()) {
        std::vector input;
        input.push_back("");
        input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
        input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
        input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
        ParseRlimit(input);
    } else {
        ParseRlimit(fdp_.PickValueInArray(kValidInputs));
    }
}
std::vector InitParserFuzzer::GenerateInterfaceMetadata() {
    std::vector random_interface;
    for (size_t idx = 0; idx  

源码路径:

Android源码:init
(图片来源网络,侵删)

https://cs.android.com/android/platform/superproject/main/+/main:system/core/init/fuzzer/init_parser_fuzzer.cpp?hl=zh-cn

代码分析:

根据提供的代码,我分析了其逻辑和总结了代码的主要作用:

  1. 这是一个针对Android init解析器的Fuzz测试代码。

  2. 定义了相关的输入样本空间,包括init配置语句、init文件路径等。

  3. InitParserFuzzer类封装了Fuzz测试逻辑。

  4. Process()方法是主要的Fuzz逻辑,它会随机调用不同的解析组件进行测试。

  5. InvokeParser()方法对init配置文件解析器进行Fuzz测试。

  6. InvokeLimitParser()方法对rlimit解析进行测试。

  7. InvokeInterfaceUtils()对AIDL接口分析代码进行测试。

  8. GenerateHierarchyMap()随机生成接口继承关系。

  9. GenerateInterfaceMetadata()随机生成接口元数据。

  10. LLVMFuzzerTestOneInput()是LibFuzzer入口,将测试数据传入InitParserFuzzer。

总结:这是一段针对Android init框架各组件的Fuzzing测试代码。主要对init配置文件解析、rlimit解析和AIDL接口分析代码进行安全性Fuzz测试,通过随机的数据探测潜在的崩溃或异常,从而提高init框架的健壮性和安全性。

const std::vector kValidInputs[] = {
        {"", "cpu", "10", "10"}, {"", "RLIM_CPU", "10", "10"},  {"", "12", "unlimited", "10"},
        {"", "13", "-1", "10"},  {"", "14", "10", "unlimited"}, {"", "15", "10", "-1"},
};

这是一段 C++ 代码,它定义了一个名为 kValidInputs 的常量数组,数组的元素类型是 std::vector,即字符串向量。¹

数组中有六个字符串向量,每个字符串向量包含四个字符串,分别表示资源限制的类型、软限制、硬限制和期望的结果。²

资源限制的类型可以是 cpu、RLIM_CPU 或一个整数,表示要设置或获取的资源的编号。³

软限制和硬限制可以是一个整数或 unlimited,表示要设置的资源使用量的上限。³

期望的结果可以是一个整数或 -1,表示要检查的资源使用量是否符合预期。⁴

这段代码可能是用于测试某个函数的输入和输出的,例如 setrlimit 或 getrlimit,这些函数可以用于控制进程的资源使用情况。.

const std::string kValidPaths[] = {
        "/system/etc/init/hw/init.rc",
        "/system/etc/init",
};

这是一段 C++ 代码,它定义了一个名为 kValidPaths 的常量数组,数组的元素类型是 std::string,即字符串。

数组中有两个字符串,分别表示两个 Android 系统的配置文件的路径。²

  • /system/etc/init/hw/init.rc 是一个用于初始化硬件相关的服务和属性的配置文件。³
  • /system/etc/init 是一个用于存放其他 init.rc 文件的目录,这些文件可以用于定义不同的服务、动作和属性。

    这段代码可能是用于测试 Parser 类的输入和输出的,Parser 类是一个用于解析 init.rc 文件的类。

    const int32_t kMaxBytes = 256;
    const std::string kValidInterfaces = "android.frameworks.vr.composer@2.0::IVrComposerClient";
    

    这是一段 C++ 代码,它定义了两个常量变量,分别是 kMaxBytes 和 kValidInterfaces。

    • kMaxBytes 是一个 int32_t 类型的变量,它表示一个 32 位的有符号整数,它的值是 256。² 这个变量可能是用于限制字符串的最大长度的。
    • kValidInterfaces 是一个 std::string 类型的变量,它表示一个字符串,它的值是 "android.frameworks.vr.composer@2.0::IVrComposerClient"。这个变量可能是用于表示一个 Android 系统的接口的名字,这个接口是一个用于虚拟现实的组件。
      class InitParserFuzzer {
        public:
          InitParserFuzzer(const uint8_t* data, size_t size) : fdp_(data, size){};
          void Process();
        private:
          void InvokeParser();
          void InvokeLimitParser();
          void InvokeInterfaceUtils();
          InterfaceInheritanceHierarchyMap GenerateHierarchyMap();
          std::vector GenerateInterfaceMetadata();
          FuzzedDataProvider fdp_;
      };
      

      这段代码的逻辑和作用是:

      • 这段代码是一个用于测试 Android 系统初始化程序的模糊器¹,它使用了 FuzzedDataProvider² 这个库来生成随机的输入数据。
      • 这段代码定义了一个 InitParserFuzzer 类,它有一个构造函数,一个 Process 方法,和四个私有方法。
      • 构造函数接受一个指向数据的指针和一个数据的大小,然后用它们初始化一个 FuzzedDataProvider 对象,用于后续的数据生成。
      • Process 方法是模糊器的主要入口,它调用了三个私有方法:InvokeParser,InvokeLimitParser,和 InvokeInterfaceUtils,分别用于测试不同的功能。
      • InvokeParser 方法用于测试 Parser 类,它是一个用于解析 init.rc 文件的类,init.rc 文件是 Android 系统的配置文件³。这个方法创建了一个 Parser 对象,然后根据随机生成的名字和路径,调用了 AddSectionParser 和 ParseConfigFile 方法,分别用于添加一个解析器和解析一个配置文件。
      • InvokeLimitParser 方法用于测试 ParseRlimit 函数,它是一个用于解析资源限制的函数,资源限制是一种用于控制进程的资源使用的机制。这个方法根据随机生成的布尔值,选择了一个随机的或者预定义的字符串向量作为输入,然后调用了 ParseRlimit 函数。
      • InvokeInterfaceUtils 方法用于测试一些与接口相关的函数,接口是一种用于定义 Android 系统服务的规范。这个方法首先调用了 GenerateHierarchyMap 方法,生成了一个接口继承关系的映射,然后调用了 SetKnownInterfaces 和 IsKnownInterface 函数,分别用于设置和检查已知的接口。然后,这个方法生成了一个随机的或者预定义的接口集合,然后调用了 CheckInterfaceInheritanceHierarchy 函数,用于检查接口的继承关系是否正确。
      • GenerateHierarchyMap 方法用于生成一个接口继承关系的映射,它根据随机生成的布尔值,选择了一个随机的或者预定义的接口元数据向量,然后遍历每个接口元数据,提取它的名字和继承的接口,然后将它们存储在一个映射中。
      • GenerateInterfaceMetadata 方法用于生成一个接口元数据向量,它根据随机生成的大小,生成了一些随机的接口元数据,每个接口元数据包含一个名字和一些继承的接口,然后将它们存储在一个向量中。
        void InitParserFuzzer::InvokeLimitParser() {
            if (fdp_.ConsumeBool()) {
                std::vector input;
                input.push_back("");
                input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
                input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
                input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
                ParseRlimit(input);
            } else {
                ParseRlimit(fdp_.PickValueInArray(kValidInputs));
            }
        }
        

        这段代码的逻辑和作用是:

        • 这段代码是 InitParserFuzzer 类的一个私有方法,它用于测试 ParseRlimit 函数,这个函数是一个用于解析资源限制的函数,资源限制是一种用于控制进程的资源使用的机制。¹
        • 这段代码首先调用了 fdp_.ConsumeBool() 方法,这个方法是 FuzzedDataProvider 类的一个方法,它用于从数据中随机消耗一个布尔值。²
        • 如果这个布尔值为真,那么这段代码创建了一个空的字符串向量,然后分别调用了 fdp_.ConsumeRandomLengthString(kMaxBytes) 方法,这个方法用于从数据中随机消耗一个最大长度为 kMaxBytes 的字符串,然后将这个字符串添加到字符串向量中。这样,这段代码生成了一个包含四个随机字符串的字符串向量,然后将这个字符串向量作为输入,调用了 ParseRlimit 函数。
        • 如果这个布尔值为假,那么这段代码调用了 fdp_.PickValueInArray(kValidInputs) 方法,这个方法用于从 kValidInputs 数组中随机选择一个字符串向量,然后将这个字符串向量作为输入,调用了 ParseRlimit 函数。
        • 这样,这段代码可以用于测试 ParseRlimit 函数在不同的输入下的行为和结果,以检查是否有错误或异常。
          InterfaceInheritanceHierarchyMap InitParserFuzzer::GenerateHierarchyMap() {
              InterfaceInheritanceHierarchyMap result;
              std::vector random_interface;
              if (fdp_.ConsumeBool()) {
                  random_interface = GenerateInterfaceMetadata();
              } else {
                  random_interface = HidlInterfaceMetadata::all();
              }
              for (const HidlInterfaceMetadata& iface : random_interface) {
                  std::set inherited_interfaces;
                  for (const std::string& intf : iface.inherited) {
                      FQName fqname;
                      (void)fqname.setTo(intf);
                      inherited_interfaces.insert(fqname);
                  }
                  FQName fqname;
                  (void)fqname.setTo(iface.name);
                  result[fqname] = inherited_interfaces;
              }
              return result;
          }
          

          这段代码的逻辑和作用是:

          • 这段代码是 InitParserFuzzer 类的一个私有方法,它用于生成一个接口继承关系的映射,接口继承关系是一种用于表示 Android 系统服务之间的层次结构的数据结构¹。
          • 这段代码首先创建了一个空的接口继承关系的映射,然后根据 fdp_.ConsumeBool() 方法,这个方法是 FuzzedDataProvider 类的一个方法,它用于从数据中随机消耗一个布尔值,选择了一个随机的或者预定义的接口元数据向量,接口元数据是一种用于描述 Android 系统服务的规范的结构体²。
          • 然后,这段代码用一个 for 循环,遍历每个接口元数据,提取它的名字和继承的接口,然后将它们转换为 FQName 类型,FQName 是一种用于表示接口的完全限定名的类³,然后将它们存储在一个集合和一个映射中。
          • 最后,这段代码返回这个映射,这个映射可以用于测试一些与接口相关的函数,例如 SetKnownInterfaces 和 CheckInterfaceInheritanceHierarchy 等。
            void InitParserFuzzer::InvokeInterfaceUtils() {
                InterfaceInheritanceHierarchyMap hierarchy_map = GenerateHierarchyMap();
                SetKnownInterfaces(hierarchy_map);
                IsKnownInterface(fdp_.ConsumeRandomLengthString(kMaxBytes));
                std::set interface_set;
                for (size_t idx = 0; idx  
            

            这段代码的逻辑和作用是:

            • 这段代码是 InitParserFuzzer 类的一个私有方法,它用于测试一些与接口相关的函数,接口是一种用于定义 Android 系统服务的规范。
            • 这段代码首先调用了 GenerateHierarchyMap 方法,生成了一个接口继承关系的映射,这个映射表示了不同的接口之间的层次结构。
            • 然后,这段代码调用了 SetKnownInterfaces 函数,将这个映射作为参数传入,这个函数用于设置已知的接口,以便后续的检查。
            • 接着,这段代码调用了 IsKnownInterface 函数,将一个随机生成的字符串作为参数传入,这个函数用于检查这个字符串是否是一个已知的接口的名字。
            • 然后,这段代码创建了一个空的接口集合,然后根据一个随机生成的大小,循环添加一些随机的或者预定义的接口的名字到这个集合中,这些接口的名字可以是 aidl 类型的,也可以是 hidl 类型的,也可以是 kValidInterfaces 这个常量变量的值。
            • 最后,这段代码调用了 CheckInterfaceInheritanceHierarchy 函数,将这个接口集合和这个映射作为参数传入,这个函数用于检查这个接口集合中的每个接口是否符合这个映射中的继承关系。

              这段代码的作用是用于测试 Android 系统服务的接口的正确性和效率。

              void InitParserFuzzer::InvokeParser() {
                  Parser parser;
                  std::string name = fdp_.ConsumeBool() ? fdp_.ConsumeRandomLengthString(kMaxBytes) : "import";
                  parser.AddSectionParser(name, std::make_unique(&parser));
                  std::string path = fdp_.ConsumeBool() ? fdp_.PickValueInArray(kValidPaths)
                                                        : fdp_.ConsumeRandomLengthString(kMaxBytes);
                  parser.ParseConfig(path);
                  parser.ParseConfigFileInsecure(path, false /* follow_symlinks */);
              }
              

              这段代码的逻辑和作用是:

              • 这段代码是 InitParserFuzzer 类的一个私有方法,它用于测试 Parser 类,这个类是一个用于解析 init.rc 文件的类,init.rc 文件是 Android 系统的配置文件¹。
              • 这段代码首先创建了一个 Parser 对象,然后根据 fdp_.ConsumeBool() 方法,这个方法是 FuzzedDataProvider 类的一个方法,它用于从数据中随机消耗一个布尔值,选择了一个随机的或者预定义的字符串作为解析器的名字,这个名字可以是 “import” 或者其他的²。
              • 然后,这段代码调用了 parser.AddSectionParser 方法,将这个名字和一个 ImportParser 对象作为参数传入,这个方法用于添加一个解析器到 Parser 对象中,ImportParser 是一个用于解析 import 语句的解析器,import 语句是一种用于导入其他 init.rc 文件的语句³。
              • 接着,这段代码再根据 fdp_.ConsumeBool() 方法,选择了一个随机的或者预定义的字符串作为配置文件的路径,这个路径可以是 kValidPaths 数组中的一个或者其他的²。
              • 然后,这段代码调用了 parser.ParseConfig 方法,将这个路径作为参数传入,这个方法用于解析一个配置文件,并将其中的服务、动作和属性添加到 Parser 对象中。
              • 最后,这段代码调用了 parser.ParseConfigFileInsecure 方法,将这个路径和一个布尔值作为参数传入,这个方法用于以不安全的方式解析一个配置文件,即不检查文件的权限和所有者,这个布尔值表示是否跟随符号链接。
              • 这样,这段代码可以用于测试 Parser 类在不同的输入下的行为和结果,以检查是否有错误或异常。
                void InitParserFuzzer::Process() {
                    while (fdp_.remaining_bytes()) {
                        auto invoke_parser_fuzzer = fdp_.PickValueInArray({
                                [&]() { InvokeParser(); },
                                [&]() { InvokeInterfaceUtils(); },
                                [&]() { InvokeLimitParser(); },
                        });
                        invoke_parser_fuzzer();
                    }
                }
                

                这段代码的逻辑和作用是:

                • 这段代码是 InitParserFuzzer 类的一个公有方法,它是模糊器的主要入口,用于测试 Android 系统初始化程序的不同功能¹。
                • 这段代码用一个 while 循环,循环执行直到数据被消耗完,每次循环中,它调用了 fdp_.PickValueInArray 方法,这个方法是 FuzzedDataProvider 类的一个方法,它用于从一个数组中随机选择一个元素,这个数组中的元素是一些函数对象,分别对应了 InitParserFuzzer 类的三个私有方法:InvokeParser,InvokeInterfaceUtils,和 InvokeLimitParser²。
                • 然后,这段代码将这个随机选择的函数对象赋值给一个变量 invoke_parser_fuzzer,然后调用这个变量,这相当于调用了 InitParserFuzzer 类的其中一个私有方法,这些私有方法分别用于测试 Parser 类,ParseRlimit 函数,和一些与接口相关的函数¹。
                • 这样,这段代码可以用于随机地测试 Android 系统初始化程序的不同功能,以检查是否有错误或异常。
                  extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
                      InitParserFuzzer init_parser_fuzzer(data, size);
                      init_parser_fuzzer.Process();
                      return 0;
                  }
                  

                  这段代码的逻辑和作用是:

                  • 这段代码是一个 C 函数,它的名字是 LLVMFuzzerTestOneInput,它是 libFuzzer 库的一个接口,用于将随机生成的数据传递给被测对象¹。
                  • 这个函数接受两个参数,一个是指向数据的指针,另一个是数据的大小,它们的类型分别是 const uint8_t* 和 size_t。
                  • 这个函数的函数体中,首先创建了一个 InitParserFuzzer 对象,它是一个用于测试 Android 系统初始化程序的模糊器²,然后将数据和大小作为参数传递给它的构造函数。
                  • 然后,这个函数调用了 init_parser_fuzzer.Process() 方法,这个方法是模糊器的主要入口,它用于随机地测试 Android 系统初始化程序的不同功能,例如解析配置文件,设置资源限制,和检查接口继承关系等²。
                  • 最后,这个函数返回 0,表示成功执行,这个返回值是 libFuzzer 库的要求¹。
                  • 这样,这段代码可以用于将 libFuzzer 库和 InitParserFuzzer 类结合起来,用于对 Android 系统初始化程序进行模糊测试,以检查是否有错误或异常。
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]