已开启
补充execCmd接口的ccm管控 #20321
补充execCmd接口的ccm管控 #20321
已开启
SKY2001创建于 3 天前
合并受阻
SSKY2001
3 天前 关联了issue:[Bug]: 补充execCmd接口的ccm管控
afwk_helper成员
3 天前 评论:

开始进行AI检视!

AI review has been started, please wait...

likedislike
afwk_helper成员
3 天前 评论:
check type result report
start ai_review pass -
likedislike
openharmony_ciopenharmony_ci成员
3 天前 添加了label:waiting_on_author
openharmony_ci
openharmony_ci成员
3 天前 评论:

感谢提交 Pull Requests!如果您提交的PR已经开发完毕,请评论 "start build" 触发门禁,更多交互操作,请访问OpenHarmony社区支持命令清单。如果需要调整订阅PR、Issue的变更状态,请访问订阅链接


Thanks for submitting the pull request. If your Pull Request has already been developed, you can leave a "start build" comment to trigger the gated system. For more commands, please visit OpenHarmony Command List. If you need to change the subscription of a Pull Request or Issue, please visit the link.

likedislike
openharmony_ciopenharmony_ci成员
3 天前 添加了label:dco检查成功
afwk_helper成员
3 天前 评论:

⚠️ 🤖 AI 代码检视报告 ⚠️

总体评估: NEEDS_ATTENTION

问题统计:

  • 总问题数: 1
  • 严重问题: 0
  • 高危问题: 0

摘要:
本次PR补充了execCmd接口的设备能力管控,整体逻辑清晰,但在互斥锁内进行日志打印可能引发死锁风险,建议优化。

📊 详细报告
查看完整的审查详情,包括具体的问题描述、建议和代码位置:
🔗 查看详细报告


此评论由 OpenHarmony Insight 代码审查系统自动生成

likedislike
afwk_helper成员3 天前进行代码检视1
services/common/src/app_utils.cpp
@@ -90,6 +90,7 @@ constexpr const char* IS_ENTERPRISE_DEVICE_TYPE = "const.edm.is_enterprise_devic
9090constexpr const char* IS_EDM_ENABLE = "persist.edm.edm_enable";
9191constexpr const char* IS_DEVELOPER_MODE = "security.developermode.state";
9292constexpr const char* SUPPORT_AUTO_STARTUP = "const.abilityms.enable_auto_startup";
93+constexpr const char* SUPPORT_EXEC_CMD = "const.abilityms.support_exec_cmd";
9394constexpr const char* SUPPORT_DELAYED_PROCESS_EXIT = "const.abilityms.support_delayed_process_exit";
9495// Support prepare terminate
9596constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
@@ -905,6 +906,17 @@ bool AppUtils::IsAutoStartupSupported()
905906 return isAutoStartupSupported_.value;
906907}
907908 
909+bool AppUtils::IsSupportExecCmd()
afwk_helper3 天前评论:

🤖 AI 代码检视意见(回复本评论可解决检视意见,点击被检视代码行左侧的小头像可收起检视意见)


🟡 在互斥锁内进行日志打印可能引发死锁

位置: L909-L918 | 严重程度: Medium

❓ 问题描述

IsSupportExecCmd 方法中,TAG_LOGD 被置于 std::lock_guard 保护的临界区内执行。HiLog 等日志系统内部通常会获取自身的锁来写入日志缓冲区。如果在持有业务锁(isSupportExecCmdMutex_)的状态下调用日志接口获取日志锁,而另一处代码以相反的顺序获取这两个锁,将导致锁顺序倒置并引发死锁。此外,在锁内执行耗时的I/O或日志操作会降低系统的并发性能。

💡 修复建议

修改建议:将日志打印移出临界区。先将需要记录的值保存到局部变量中,释放互斥锁后再执行日志打印。

909: bool AppUtils::IsSupportExecCmd()
910: {
911: bool value = false;
912: {
913: std::lock_guard lock(isSupportExecCmdMutex_);
914: if (!isSupportExecCmd_.isLoaded) {
915: isSupportExecCmd_.value = system::GetBoolParameter(SUPPORT_EXEC_CMD, false);
916: isSupportExecCmd_.isLoaded = true;
917: }
918: value = isSupportExecCmd_.value;
919: }
920: TAG_LOGD(AAFwkTag::DEFAULT, "SupportExecCmd: %{public}d", value);
921: return value;
922: }


likedislike
SSKY2001
2 天前 审查状态已重置,审查人: afwk_helper
SSKY2001
2 天前 强制推送  1 个提交:daad7558-补充execCmd接口的ccm管控
openharmony_ci
openharmony_ci成员
2 天前 评论:

感谢提交 Pull Requests!如果您提交的PR已经开发完毕,请评论 "start build" 触发门禁,更多交互操作,请访问OpenHarmony社区支持命令清单。如果需要调整订阅PR、Issue的变更状态,请访问订阅链接


Thanks for submitting the pull request. If your Pull Request has already been developed, you can leave a "start build" comment to trigger the gated system. For more commands, please visit OpenHarmony Command List. If you need to change the subscription of a Pull Request or Issue, please visit the link.

likedislike
SKY2001
2 天前 评论:

代码检视报告 — cli_tool ExecCmd capability gate (20321)(Round 1 / 最新提交)

统一报告由 codecheck 工作台生成,用于门禁管控。所有 codecheck 报告必须遵循本模板:章节顺序、字段名、报告元数据块、评分与门禁规则均为固定格式
生成入口:skills/codecheck/README.md → Step 5;合并逻辑见 skills/codecheck/orchestrator/SKILL.md
权威评分与门禁规则为通用规则,不在输出报告中呈现;生成时已按 conventions.md §7/§8/§9 计算。


报告元数据

门禁脚本只读取本 YAML 块。字段名与取值域为固定合约,禁止改名、增删或自定义取值。

codecheck_report:
  schema_version: "1.0"
  scope: "cli_tool ExecCmd capability gate (20321)"
  round: 1
  commit_id: "daad75585c91b8b995435fa9226d11046a6c80ed"
  change_id: "N/A"
  report_id: "80d41817-R1"
  date: "2026-08-28"
  gate_decision: "conditional"
  risk_level: "medium"
  score: 86
  dimensions_required: ["security-scanner", "logic-scanner", "api-scanner", "input-scanner"]
  dimensions_executed: ["security-scanner", "logic-scanner", "api-scanner(轻量内联)", "input-scanner(N/A)"]
  findings_total: 2
  findings_by_severity: {P0: 0, P1: 1, P2: 0, P3: 1}
  gate_blockers: []
  must_fix: ["TEST-01"]
  followups: ["API-01"]

1. 门禁结论

项目 结论
决策 conditional
风险等级 🟡 medium
评分 86/100
阻塞项 无(无 P0)
必须修复(P0/P1) 1 项(TEST-01)
建议跟进(P2/P3) 1 项(API-01)

一句话结论:补丁的产品逻辑正确(能力门禁置于权限校验之前、错误码 801=标准 ERROR_CODE_CAPABILITY_NOT_SUPPORT、native→业务错误映射完整、IsSupportExecCmd() 沿用正确的 per-field mutex 加锁模式、const. 参数安全默认 false),但门禁缺测试集成——标准测试环境下新参数未设置使门禁先返回 801,既有 ExecCmd_0100..0600 用例的 || 断言不覆盖 801(IsPermissionGateResult 仅含 ERR_NOT_SYSTEM_APP/ERR_PERMISSION_DENIED)将集体失败,且未为 disabled→801 路径与 801 错误映射新增用例;处理测试集成后可上库。


3. 必须立即处理(P0/P1)

ID 优先级 Scanner 问题 file:line 触发路径 影响
TEST-01 P1 logic+security+api ExecCmd 能力门禁缺测试集成:既有用例回归 + 新路径无覆盖 cli_tool_framework/services/climgr/src/cli_tool_manager_service.cpp:1091(门禁)/ cli_tool_framework/test/unittest/cli_tool_mgr_service_test/cli_tool_mgr_service_test.cpp:2241-2372(既有 ExecCmd 用例) 标准测试环境:SetUpTestCase(test:113-127)未设置 const.abilityms.support_exec_cmd、未 mock AppUtilsIsSupportExecCmd() 走真实 system::GetBoolParameter(...,false) 返回 false → ExecCmd 在权限/调度器/校验/会话上限之前返回 AAFwk::ERR_CAPABILITY_NOT_SUPPORT(service:1091-1094),经 JS CreateCliJsErrorByNativeErr 映射为 801 既有 ExecCmd_0100..0600 断言(ERR_NO_INIT|ERR_NOT_HAP|ERR_INVALID_PARAM|ERR_SESSION_LIMIT_EXCEEDED|IsPermissionGateResult)均不含 801(IsPermissionGateResult test:79-82 仅覆盖 ERR_NOT_SYSTEM_APP/ERR_PERMISSION_DENIED)→ EXPECT_TRUE(false) 集体失败 → CI 阻断上库;同时 disabled→801 路径与 801 错误映射无任何用例

无 P0 项。


4. 建议本轮或下一补档处理(P2/P3)

ID 优先级 问题 建议行动 排期
API-01 P3 补丁为 execCmd 新增 801(ERROR_NOT_SUPPORTED)错误码与映射,但本仓未检出对应 .d.ts;需核实 SDK 仓 execCmd.d.ts 是否在 @throws/错误码表声明 801(docs×d.ts×framework 一致性) 在 SDK 仓核实/补声明 execCmd 的 801 错误码;同时确认错误消息措辞是否需与标准 801 对齐 下一补档/SDK 同步

5. 分维度速览

维度 结果 关键说明
security-scanner 🟡 命中 1(TEST-01 安全视角) 能力门禁安全视角正向:const.abilityms.support_exec_cmdconst.(受信、boot 期、应用不可改),默认 false(安全默认禁用);门禁置于权限校验之前(service:1091 在 :1095 前),符合"不支持能力先于权限拒绝"约定;ExecCmd(任意 shell 命令→CreateShellProcess service:1130)被门禁,而 ExecTool(运行已注册/经 ValidateAndPrepareTool 校验的配置工具 service:1029-1084)不被门禁——设计正确,非绕过。无内存安全/资源生命周期缺陷引入。
logic-scanner 🟡 命中 1(TEST-01 逻辑视角) 错误传播链正确:service 返回 AAFwk::ERR_CAPABILITY_NOT_SUPPORT → 客户端 CliToolMGRClient::ExecCmd → JS DispatchCliCmd(js_cli_manager.cpp:226-228 同步返回 + :72-88 replyCallback 两路径均 CreateCliJsErrorByNativeErr)→ GetBusinessErrorCode 经新映射项 cli_manager_error_utils.cpp:55ERROR_NOT_SUPPORTED→801 + 消息;映射项必要(缺则 fallthrough 至 ERROR_INNER 35600050,错误)。错误码 801 与 ability_business_error.h:37 ERROR_CODE_CAPABILITY_NOT_SUPPORT=801 一致。NATIVE_TO_BUSINESS_ERROR_MAP 无键冲突。IsSupportExecCmd() 实现(app_utils.cpp:906-916)沿用正确的 per-field lock_guard 模式(无 race、无重入死锁)。缺陷仅在测试集成(TEST-01)。
api-scanner 🟢 轻量内联(1 项 P3 跟进) 801 数值与标准一致 ✓;错误消息措辞("Capability not supported. Failed to call the API due to limited device capabilities.")与 ability_business_error.cpp:31 "Capability not support." 不同,但 801 数值为程序化契约、措辞为模块本地化,影响有限(P3 观察项,未单列);.d.ts 不在本仓 → API-01(P3)待 SDK 仓核实 execCmd 的 801 声明。
input-scanner N/A 改动行未引入"外部输入→持久化"链路:ExecCmd 门禁仅读 const.(受信)系统参数并返回错误码;app_utils 仅对受信系统参数缓存读取加锁;无 IPC Parcel 读/DB/文件写 sink。

6. 关键发现详情

[TEST-01] ExecCmd 能力门禁缺测试集成:既有用例回归 + 新路径无覆盖 (P1, scanner=logic+security+api)

  • 位置cli_tool_framework/services/climgr/src/cli_tool_manager_service.cpp:1091-1094(门禁);cli_tool_framework/test/unittest/cli_tool_mgr_service_test/cli_tool_mgr_service_test.cpp:113-127(夹具未使能)、:79-82IsPermissionGateResult 不含 801)、:2241-2372(既有 ExecCmd_0100..0600 用例)
  • 触发路径:补丁在 ExecCmd 首部插入 if (!AAFwk::AppUtils::GetInstance().IsSupportExecCmd()) return AAFwk::ERR_CAPABILITY_NOT_SUPPORT;(service:1091-1094),早于权限校验(:1095)、调度器设置(:1100)、会话上限(:1103)、参数校验(:1109)。IsSupportExecCmd()(app_utils.cpp:906)读取 const.abilityms.support_exec_cmd,默认 false。测试夹具 SetUpTestCase(test:113-127)仅设置 NativeTokenInfo,设置该系统参数、 mock AppUtils。故标准测试环境下 system::GetBoolParameter(..., false) 返回 false → 门禁返回 AAFwk::ERR_CAPABILITY_NOT_SUPPORT → 经 JS 层 CreateCliJsErrorByNativeErr 映射为业务码 801。
  • 影响:既有 ExecCmd_0100..0600EXPECT_TRUE 使用 || 容错集(如 result==ERR_NO_INIT || result==ERR_NOT_HAP || result==ERR_INVALID_PARAM || IsPermissionGateResult(result)),均不含 801IsPermissionGateResult(test:79-82)仅覆盖 ERR_NOT_SYSTEM_APP/ERR_PERMISSION_DENIED。故门禁返回的 801 不命中任何分支 → EXPECT_TRUE(false) → 用例集体失败 → CI 阻断上库。同时补丁未为"disabled→801"路径与 ERROR_NOT_SUPPORTED(801) 错误映射新增任何用例(新安全相关路径无覆盖)。注:补丁未改任何测试文件。
  • 证据
    // cli_tool_manager_service.cpp — 门禁插入在最前,默认禁用
    1086: int32_t CliToolManagerService::ExecCmd(...) {
    1089:     InterfaceCallCounter counter(interfaceCalledCount_);
    1090:     TAG_LOGI(...);
    1091:     if (!AAFwk::AppUtils::GetInstance().IsSupportExecCmd()) {   // 默认 false
    1092:         TAG_LOGE(AAFwkTag::CLI_TOOL, "Disabled ExecCmd");
    1093:         return AAFwk::ERR_CAPABILITY_NOT_SUPPORT;                // → JS 映射 801
    1094:     }
    1095:     if (auto ret = ValidateExecToolPermissions(); ret != ERR_OK) {  // 既有用例预期在此及之后
    
    // app_utils.cpp — 默认 false
    95: bool AppUtils::IsSupportExecCmd() {
    97:     std::lock_guard lock(isSupportExecCmdMutex_);
    98:     if (!isSupportExecCmd_.isLoaded) {
    99:         isSupportExecCmd_.value = system::GetBoolParameter(SUPPORT_EXEC_CMD, false);  // 未设置→false
    ...
    
    // cli_tool_mgr_service_test.cpp — 夹具未使能;IsPermissionGateResult 不含 801
    79: bool IsPermissionGateResult(int32_t result) {
    81:     return result == ERR_NOT_SYSTEM_APP || result == ERR_PERMISSION_DENIED;  // 不含 801
    82: }
    113: void CliToolManagerServiceTest::SetUpTestCase(void) { ... SetSelfTokenID(tokenId); }  // 未设系统参数/未 mock AppUtils
    2251: EXPECT_TRUE(result == ERR_NO_INIT || result == ERR_NOT_HAP ||
    2252:     result == ERR_INVALID_PARAM || IsPermissionGateResult(result));  // 801 不命中 → 失败
    
  • 建议:三选一或组合——
    1. 测试夹具使能:在 SetUpTestCase/SetUp 中通过 system::SetParameter("const.abilityms.support_exec_cmd", "true") 或 mock AppUtils::IsSupportExecCmd 返回 true,使既有用例绕过门禁、保持原语义;
    2. 既有用例 || 容错集补 result == AAFwk::ERR_CAPABILITY_NOT_SUPPORT 分支(或新增 IsCapabilityGateResult helper);
    3. 新增专项用例:mock IsSupportExecCmd()=false,断言 ExecCmd 返回 AAFwk::ERR_CAPABILITY_NOT_SUPPORT 且 JS 层 CreateCliJsErrorByNativeErr 产生 801 错误码(覆盖新路径 + 新映射)。
      推荐组合 1+3:使能既有用例 + 新增 disabled→801 专项用例,既不回归又覆盖新行为。请作者先跑 cli_tool_mgr_service_test 验证回归假设。

[API-01] execCmd 的 .d.ts 错误码声明需在 SDK 仓核实 (P3, scanner=api)

  • 位置cli_tool_framework/frameworks/js/napi/cli_tool_manager/src/cli_manager_error_utils.cpp:39,55(新增 801 映射);SDK 仓 execCmd .d.ts(不在本仓)
  • 触发路径:N/A(文档一致性,非运行期)。
  • 影响:若 SDK 仓 execCmd.d.ts 未在 @throws/错误码表声明 801,则 docs×d.ts×framework 不一致;801 数值已核对与 ability_business_error.h:37 一致,程序化契约不受影响,故 P3。
  • 证据:本仓 cli_tool_framework 下未检出 execCmd/801.d.ts(grep 无匹配);801 数值与标准一致(ability_business_error.h:37 ERROR_CODE_CAPABILITY_NOT_SUPPORT=801)。
  • 建议:在 SDK 仓核实/补声明 execCmd 的 801 错误码;顺带确认错误消息措辞是否需与标准 801 对齐(当前模块本地化措辞与 ability_business_error.cpp:31 不同,非阻断)。
likedislike
SKY2001
2 天前 评论:

static-check

likedislike
openharmony_ci
openharmony_ci成员
2 天前 评论:


静态检查:

# check type result report
1 codeCheck pass >>>

likedislike
hwliujinwei1 天前进行代码检视1
cli_tool_framework/test/unittest/cli_tool_mgr_service_test/cli_tool_mgr_service_test.cpp
@@ -23,7 +23,7 @@
2323#include <mutex>
2424#include <string>
2525#include <sys/wait.h>
2626#include <thread>
hwliujinwei1 天前评论:

[次要] ExecCmd_0800 的断言过于宽松,接受 IsCapabilityGateResult、IsPermissionGateResult、ERR_NO_INIT、ERR_NOT_HAP、ERR_INVALID_PARAM 等多种结果,无法确定性验证能力门控的拒绝行为。建议通过 mock AppUtils 或设置系统参数使 IsSupportExecCmd 返回 false,从而断言 result == AAFwk::ERR_CAPABILITY_NOT_SUPPORT 且 sessionRecords_ 为空。ExecCmd_0900 存在同样问题。

likedislike
hwliujinwei1 天前进行代码检视1
services/common/src/app_utils.cpp
@@ -8,7 +8,7 @@
88 *
99 * Unless required by applicable law or agreed to in writing, software
1010 * distributed under the License is distributed on an "AS IS" BASIS,
1111 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
hwliujinwei1 天前评论:

[提示] TAG_LOGD 位于 lock_guard 作用域内,虽然 ExecCmd 调用频率不高影响有限,但建议将日志移到锁外以减少锁持有时间,与性能敏感路径的最佳实践保持一致。

likedislike
hwliujinwei1 天前进行代码检视1
services/common/src/app_utils.cpp
@@ -1,6 +1,6 @@
11/*
22 * Copyright (c) 2023-2026 Huawei Device Co., Ltd.
33 * Licensed under the Apache License, Version 2.0 (the "License");
hwliujinwei1 天前评论:

[提示] IsSupportExecCmd 默认值为 false,意味着未配置 const.abilityms.support_exec_cmd 的设备将无法使用 ExecCmd 接口。这是 CCM 管控的预期行为,但需确保产品侧在需要支持 ExecCmd 的设备上正确配置该参数为 true,避免回归。

likedislike
hwliujinwei1 天前进行代码检视1
services/common/src/app_utils.cpp
@@ -8,7 +8,7 @@
88 *
99 * Unless required by applicable law or agreed to in writing, software
1010 * distributed under the License is distributed on an "AS IS" BASIS,
1111 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
hwliujinwei1 天前评论:

[重要] IsSupportExecCmd() 中 system::GetBoolParameter(SUPPORT_EXEC_CMD, false) 默认值为 false,若 execCmd 为已有功能,未配置 const.abilityms.support_exec_cmd 的设备升级后该功能将被禁用,存在向后兼容风险。建议确认产品侧 rollout 计划,或如需保持兼容将默认值改为 true。

likedislike
hwliujinwei1 天前进行代码检视1
cli_tool_framework/test/unittest/cli_tool_mgr_service_test/cli_tool_mgr_service_test.cpp
@@ -25,7 +25,7 @@
2525#include <sys/wait.h>
2626#include <thread>
2727#include <unistd.h>
2828#include <cerrno>
hwliujinwei1 天前评论:

[重要] ExecCmd_0800 和 ExecCmd_0900 的断言使用 EXPECT_TRUE(IsCapabilityGateResult(result) || IsPermissionGateResult(result) || result == ERR_NO_INIT || ...) 接受多种错误码,无法确保 CCM 门控被真正触发。建议 mock AppUtils::IsSupportExecCmd() 返回 false,并断言返回值严格等于 AAFwk::ERR_CAPABILITY_NOT_SUPPORT,以有效验证 CCM 管控逻辑。

likedislike
hwliujinwei1 天前进行代码检视1
services/common/include/app_utils.h
@@ -1,7 +1,7 @@
11/*
22 * Copyright (c) 2023-2026 Huawei Device Co., Ltd.
33 * Licensed under the Apache License, Version 2.0 (the "License");
44 * you may not use this file except in compliance with the License.
hwliujinwei1 天前评论:

[提示] isSupportExecCmd_ 成员仍保留 volatile 限定符,但已有 isSupportExecCmdMutex_ 保护,volatile 在此处是冗余的。不过为与类内其他 DeviceConfiguration 成员保持一致可以保留,仅作提示。

likedislike