
# 配置代码检查任务模型集
- "模型"可以理解为是对特定编程行为或系统交互的抽象表示，它定义了分析器应该如何理解和处理特定的代码模式或API调用。
- 与规则不同的是，规则通常是描述"什么是对的，什么是错的"的检查条款，而模型则更关注"代码在特定上下文中的行为特征"。
- 模型为分析器提供了关于代码行为的知识库，使其能够更准确地进行推理。模型主要是对函数的行为或者变量进行建模，例如malloc/free系列的分配释放行为模型。
- 在配置代码检查任务模型时应遵循的[表3]，确保回复的质量、准确性和安全性。
#### 约束与限制
- 模型集为受限功能，仅[购买代码检查安全增强包](https://support.huaweicloud.com/price-devcloud/codearts_29_0016.html#section0)后才可使用该功能，任务设置启用模型集时，执行检查任务会占用增强包并发资源。
- 当前仅支持"华北-北京四"、"华南-广州一"。
- 每个租户最多可创建100个模型集和20条模型。
- 模型集当前仅支持C/C++语言和secbrella引擎。
- 新建模型时，上传的文件仅支持json后缀的文件。
 
#### 查看模型集
用户可提前查看模型集详情，根据实际需要选择对应的模型集。
1. [访问CodeArts Check服务首页](https://support.huaweicloud.com/usermanual-codecheck/devcloud_hlp_00101.html#devcloud_hlp_00101__section125631532175013)。
2. 单击"模型集"页签，进入模型集列表页面。
3. 单击模型集名称，进入该模型集详情页面，可查看模型集中的模型使用详情。
 
#### 配置代码检查任务使用模型集
1. 进入代码检查页面，在任务列表中，单击任务名称。
2. 进入"代码检查详情"页面，选择"设置 \> 模型集"。
3. 在右侧区域选择使用的模型集。
4. 单击页面右上角"管理模型集"，可跳转至模型集列表页。
 
#### 新建模型集
1. [访问CodeArts Check服务首页](https://support.huaweicloud.com/usermanual-codecheck/devcloud_hlp_00101.html#devcloud_hlp_00101__section125631532175013)。
2. 单击"模型集"页签，进入模型集列表页面。
3. 单击"新建模型集"，参考[表1]配置模型集参数。然后单击"确定"，进入选择模型界面。
   
    表1新建模型集 
   | 参数    | 说明                                                                                                                                                                                                                                                                                           |
   |:---|:---|
   | 模型集名称 | 创建的模型集名称，可自定义。 - 支持中英文，数字，点，下划线"_"和连接符"-"。  - 字符长度范围为1\~128。   |
   | 检查语言  | 模型集支持的检查语言，当前仅支持C/C++语言。                                                                                                                                                                                                                                                                     |
   | 描述    | 对当前模型集的描述，字符长度范围为0\~256。                                                                                                                                                                                                                                                                     |
      
   
   
4. 勾选使用的模型后，单击"保存"即可。若无模型可选，可参考[新建模型]添加。
 
#### 修改模型集
1. 在模型集列表页，单击模型集所在行![](https://support.huaweicloud.com/usermanual-codecheck/zh-cn_image_0000002416303852.png)，进入模型集详情页。
2. 可增加或者删除模型。
3. 单击"修改基本信息"，可修改模型集名称和描述。
 
#### 删除模型集
在模型集列表页，单击模型集所在行![](https://support.huaweicloud.com/usermanual-codecheck/zh-cn_image_0000002449784453.png)，可删除模型集。
 #### 新建模型
1. 单击新建的模型集名称，进入模型集详情页面，单击"新建模型"。
2. 在新建模型页面，参考[表2]配置模型参数。
   
    表2新建模型 
   | 参数   | 说明                                                                  |
   |:---|:---|
   | 模型文件 | 在本地创建的模型文件，操作可参考[创建模型文件]。 |
   | 模型名称 | 上传模型文件后自动生成，无需手动填写。                                                 |
   | 检查语言 | 当前仅支持C/C++语言。                                                       |
   | 执行工具 | 当前仅支持secbrella引擎。                                                   |
   | 标签   | 对当前模型的标签，用于识别当前模型的分类，字符长度范围为0\~256。                                 |
   | 描述   | 对当前模型的描述，字符长度范围为0\~256。                                             |
      
   
   
3. 单击"确定"。
4. 新建完成后，在模型集下可以对模型进行如下操作。 
   - 单击模型所在行![](https://support.huaweicloud.com/usermanual-codecheck/zh-cn_image_0000002416311008.png)，可在弹框中重新上传模型文件和修改用户标签以及描述。
   
   - 单击模型所在行![](https://support.huaweicloud.com/usermanual-codecheck/zh-cn_image_0000002449749353.png)，可下载模型文件。
   
   - 单击模型所在行![](https://support.huaweicloud.com/usermanual-codecheck/zh-cn_image_0000002416310652.png)，可删除模型。
   
   
   
   
 
 #### 创建模型文件
代码示例如下：
```
{
  "RulePackage": {
    "Language": "C++" # 必填，C或者C++
  },
  "Rules": {
    "TaintSourceRule": [ # 污点源配置
      {
        "Function": { # 污点源函数配置1
          "Namespace": {
            "Value":"TestSpace" # 命令空间，如果没有可以不写
          },
          "Class": {
            "Value": "TestClass" # 类名，如果没有可以不写
          },
          "Function": {
            "Value": "TaintCase1" # 函数名，必填
          }
        },
        "Source": { # 污点源函数参数配置
          "InArgs": "0,2-3", # InArgs配置函数形参位置（参数具体配置看基本概念）
          "TaintFlags": "UntrustedSource" # 污点标识，固定值
        } 
      },
      {
        "Function": { # 污点源函数配置2
          "Namespace": {
            "Value":"TestSpace" # 命令空间，如果没有可以不写
          },
          "Class": {
            "Value": "TestClass" # 类名，如果没有可以不写
          },
          "Function": {
            "Value": "TaintCase2" # 函数名，必填
          }
        },
        "Source": { # 污点源函数参数配置
          "OutArgs": "return,2-3", # OutArgs在配置函数实参位置或者配置函数返回值
          "TaintFlags": "UntrustedSource" # 污点标识，固定值
        }
      },
      {
        "GlobalVariable": { # 污点源全局变量配置
          "Name": {
            "Value": "g_xxxx" # 全局变量名，必填
          }
        },
        "Source": {
          "TaintFlags": "UntrustedSource" # 污点标识，固定值
        }
      },
      {
        "TaintVariable": {  # 污点源局部变量配置
          "Name": {
            "Value": "local_var" # 局部变量名，必填
          }
        },
        "Source": {
          "TaintFlags": "UntrustedSource" # 污点标识，固定值
        }
      }
    ],
    "TaintSinkRule": [ # 污点爆发配置
      {
        "Function": { # 污点爆发函数配置
          "Namespace": {
            "Value":"TestSpace" # 命令空间，如果没有可以不写
          },
          "Class": {
            "Value": "TestClass" # 类名，如果没有可以不写
          },
          "Function": {
            "Value": "TaintSink" # 函数名，必填
          }
        },
        "Sink": {
          "InArgs": "0", # InArgs配置函数爆发参数位置，TaintSinkRule配置只有InArgs
          "TaintFlags": "UntrustedSink" # 污点标识，固定值
        }
      }
    ],
    "TaintPassthroughRule": [ # 污点传播配置
      {
        "Function": { # 污点传播函数配置1
          "Namespace": {
            "Value":"TestSpace" # 命令空间，如果没有可以不写
          },
          "Class": {
            "Value": "TestClass" # 类名，如果没有可以不写
          },
          "Function": {
            "Value": "TaintPass" # 函数名，必填
          }
        },
        "Passthrough": {
          "InArgs": "0", # 配置位置在InArgs的污点参数传播到位置是OutArgs的参数或者返回值
          "OutArgs": "1" 
        }
      },
      {
        "Function": { # 污点传播函数配置2
          "Function": {
            "Value": "TaintPass2" # 函数名，必填
          }
        },
        "Passthrough": {
          "InArgs": "0", # 配置位置在InArgs的污点参数传播到位置是OutArgs的参数或者返回值
          "OutArgs": "return"
        }
      }
    ],
    "TaintCleanseRule": [ # 污点净化配置
      {
        "Function": { # 污点净化函数配置
          "Namespace": {
            "Value":"TestSpace" # 命令空间，如果没有可以不写
          },
          "Class": {
            "Value": "TestClass" # 类名，如果没有可以不写
          },
          "Function": {
            "Value": "Sanitize"  # 函数名，必填
          }
        },
        "Cleanse": {
          "InArgs": "0" # InArgs配置函数净化参数位置，TaintCleanseRule配置只有InArgs
        }
      }
    ],
    "TaintAnnotations": { # 内存申请释放，空指针类配置
      "SpaceA::ClassA::test_malloc": [ # 函数名，必填, 格式： 命令空间::(没有就不写)类名::(没有就不写)函数名
        ["AllocSource::1", "InitNull"], # 第一个[], 代表返回值，没有配置就为空[],这里配置了"AllocSource::1"代表返回值有返回内存，且1代表id，该内存只能用相同id的释放函数释放;还配置了"InitNull"代表可能返回空指针
        [],   # 第二个[], 如果是类函数，代表this指针，没有配置就为空[]
        []    # 第三个[], 如果是类函数，代表第一个参数
      ],
      "malloc": [ # 函数名
        ["AllocSource::1", "InitNull"], # 第一个[], 代表返回值，没有配置就为空[],这里配置了"AllocSource::1"代表返回值有返回内存，且1代表id，该内存只能用相同id的释放函数释放;还配置了"InitNull"代表可能返回空指针
        [   # 第二个[], 如果是普通函数，代表第一个参数，没有配置就为空[]，这里配置了"AllocSize"代表该参数是申请内存的长度
          "AllocSize"
        ]
      ],
      "free": [ # 函数名
        [], # 第一个[], 代表返回值，没有配置就为空[]
        [   # 第二个[], 如果是普通函数，代表第一个参数，没有配置就为空[]，这里配置了"FreeSink::1"代表该参数有释放行为，且1代表id，只有用于释放来自相同id的申请内存函数的内存,如果希望该释放函数不需要用于指定的申请函数，那么可以配置"FreeSink"
          "FreeSink::1"
        ]
      ]
    }
  }
}
```
 表3模型影响的规则 
| 模型类型                       | 模型生效的规则                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
|:---|:---|
| 申请函数TaintAnnotations       | G.VAR.08：资源不再使用时应予以关闭或释放,内存不再使用时应予以释放。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| 内存释放函数TaintAnnotations     | - G.MEM.05：不访问已释放的内存,不使用已释放的内存或重复释放内存。  - G.VAR.08：资源不再使用时应予以关闭或释放,内存不再使用时应予以释放。                                                                                                                                                                                                                                                                     |
| 返回空指针TaintAnnotations      | - G.FUD.08：将字符串或指针作为函数参数时，在函数体中应检查参数是否为NULL。  - G.STD.03-CPP：禁止从空指针创建std::string，解引用空指针。                                                                                                                                                                                                                                                      |
| 污点源函数TaintSourceRule       | G.STD.08-CPP：外部数据用于容器索引或迭代器时必须确保在有效范围内。 G.STD.05-CPP：确保用于字符串操作的缓冲区有足够的空间容纳字符数据和结束符，并且字符串以null结束符结束，缓冲区越界访问。 G.STR.01：确保字符串存储有足够的空间容纳字符数据和null结束符。 G.INT.06：校验外部数据中整数值的合法性。 G.MEM.03：外部输入作为内存操作相关函数的复制长度时，需要校验其合法性。 G.FUU.18：禁止直接使用外部数据拼接SQL命令、不可信的输入可能引起命令注入、格式化注入、SQL注入等注入类问题。 G.FUU.16：禁止外部可控数据作为进程启动函数的参数。      |
| 污点净化函数TaintCleanseRule     | G.STD.08-CPP：外部数据用于容器索引或迭代器时必须确保在有效范围内。 G.STD.05-CPP：确保用于字符串操作的缓冲区有足够的空间容纳字符数据和结束符，并且字符串以null结束符结束,缓冲区越界访问。 G.STR.01：确保字符串存储有足够的空间容纳字符数据和null结束符。 G.INT.06：校验外部数据中整数值的合法性。 G.MEM.0：外部输入作为内存操作相关函数的复制长度时，需要校验其合法性。 G.FUU.18：禁止直接使用外部数据拼接SQL命令、不可信的输入可能引起命令注入、格式化注入、SQL注入等注入类问题。 G.FUU.1：禁止外部可控数据作为进程启动函数的参数。    |
| 污点传播函数TaintPassthroughRule | G.STD.08-CPP：外部数据用于容器索引或迭代器时必须确保在有效范围内。 G.STD.05-CPP：确保用于字符串操作的缓冲区有足够的空间容纳字符数据和结束符，并且字符串以null结束符结束，缓冲区越界访问。 G.STR.01：确保字符串存储有足够的空间容纳字符数据和null结束符。 G.INT.06：校验外部数据中整数值的合法性。 G.MEM.03：外部输入作为内存操作相关函数的复制长度时，需要校验其合法性。 G.FUU.18：禁止直接使用外部数据拼接SQL命令、不可信的输入可能引起命令注入、格式化注入、SQL注入等注入类问题。 G.FUU.16：禁止外部可控数据作为进程启动函数的参数。 |
| 污点爆发函数TaintSinkRule        | G.FUU.18：禁止直接使用外部数据拼接SQL命令、不可信的输入可能引起命令注入、格式化注入、SQL注入等注入类问题。 G.FUU.16：禁止外部可控数据作为进程启动函数的参数。                                                                                                                                                                                                                                                                                                                                                                                                       |
   
