合并受阻
开始进行AI检视!
AI review has been started, please wait...


| check type | result | report |
|---|---|---|
| start ai_review | pass | - |


感谢提交 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.


⚠️ 🤖 AI 代码检视报告 ⚠️
总体评估: NEEDS_ATTENTION
问题统计:
- 总问题数: 1
- 严重问题: 0
- 高危问题: 0
摘要:
本次PR补充了execCmd接口的设备能力管控,整体逻辑清晰,但在互斥锁内进行日志打印可能引发死锁风险,建议优化。
📊 详细报告
查看完整的审查详情,包括具体的问题描述、建议和代码位置:
🔗 查看详细报告
此评论由 OpenHarmony Insight 代码审查系统自动生成


🤖 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: }


感谢提交 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.


代码检视报告 — 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 AppUtils → IsSupportExecCmd() 走真实 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_cmd 为 const.(受信、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:55 得 ERROR_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-82(IsPermissionGateResult不含 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,未设置该系统参数、未 mockAppUtils。故标准测试环境下system::GetBoolParameter(..., false)返回 false → 门禁返回AAFwk::ERR_CAPABILITY_NOT_SUPPORT→ 经 JS 层CreateCliJsErrorByNativeErr映射为业务码 801。 - 影响:既有
ExecCmd_0100..0600的EXPECT_TRUE使用||容错集(如result==ERR_NO_INIT || result==ERR_NOT_HAP || result==ERR_INVALID_PARAM || IsPermissionGateResult(result)),均不含 801;IsPermissionGateResult(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 不命中 → 失败 - 建议:三选一或组合——
- 测试夹具使能:在
SetUpTestCase/SetUp中通过system::SetParameter("const.abilityms.support_exec_cmd", "true")或 mockAppUtils::IsSupportExecCmd返回 true,使既有用例绕过门禁、保持原语义; - 既有用例
||容错集补result == AAFwk::ERR_CAPABILITY_NOT_SUPPORT分支(或新增IsCapabilityGateResulthelper); - 新增专项用例: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不同,非阻断)。


静态检查:
| # | check type | result | report |
|---|---|---|---|
| 1 | codeCheck | pass | >>> |


[次要] 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 存在同样问题。


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


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


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


[重要] 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 管控逻辑。


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


补充execCmd接口的ccm管控
https://gitcode.com/openharmony/ability_ability_runtime/issues/16085?ref=&did=4287576#tid-4287576