已关闭
[Bug-Report|缺陷反馈]: 调度器错误转义单引号内反斜杠,遗漏后续命令转换 #1022
puppy创建于  20 天前关闭于  10 天前
puppy
puppy
20 天前 创建

Describe the current behavior / 问题描述 (Mandatory / 必填)

experimental/cluster_link_diag/dispatcher/json_info.py 的 _consume_escape 在单引号内仍把反斜杠视为转义。合法命令 printf '%s' 'foo\'; sudo id 中,反斜杠本应是字面字符,后面的单引号结束参数;目前解析器却将结束单引号吃掉,忽略随后真正的 ; 连接符。

因此 split_ignoring_quotes 错误地只返回一段,sudo_cmd 不会给后续 sudo id 加上调度器的 -S -p '' 选项。其他连接符及后续 su 转换同样受到影响。dispatcher_common.exec_command_with_auth 通过此转换函数处理待执行命令;本次仅验证该纯字符串处理行为,未实际执行 sudo、su 或 SSH。

Environment / 环境信息 (Mandatory / 必填)

HCOMM master 37fe471eda95d8193e59871707e651e7041a872c;CPU / Python 3.9.6 / Paramiko 5.0.0。相同实现此前在 ARM Linux / Python 3.12.13 验证。无需 NPU、主机配置文件或 SSH 连接。

Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)

安装调度器已有的 Paramiko 依赖后,在仓库根目录运行:

python3 -B - <<'PYCODE'
import sys
sys.path.insert(0, 'experimental/cluster_link_diag/dispatcher')
import json_info
command = "printf '%s' 'foo\\'; sudo id"
print(json_info.split_ignoring_quotes(command))
print(json_info.sudo_cmd(command, ''))
PYCODE

Describe the expected behavior / 预期结果 (Mandatory / 必填)

单引号内的反斜杠按字面保留,正确识别结束单引号以及后续连接符:

["printf '%s' 'foo\\'", ';', 'sudo id']
printf '%s' 'foo\' ; sudo -S -p '' id

引号之外的转义、双引号内的现有转义处理、引号内分隔符和重定向保持原行为。

原版返回:

["printf '%s' 'foo\\'; sudo id"]
printf '%s' 'foo\'; sudo id

新增 7 个 CPU 测试方法覆盖五种连接符子场景、后续 sudo / su 转换、引号内分隔符、外部转义、双引号转义、重定向与不加载配置。原版出现 6 个失败子场景,单行修复后全部通过;标准库 shlex 交叉核对词法分隔。全过程仅处理字符串。

Special notes for this issue/备注 (Optional / 选填)

建议仅当不在单引号中时启用反斜杠转义。已按函数名、single quote / 单引号、backslash / 反斜杠等检索 issue / PR;#927 / PR #5437 修复的是实时执行器 shell=False 的 argv 空格切分,并明确不修改 SSH 转换,因此与本问题不同。

likedislike
puppy
puppy
20 天前 评论:

/assign @hanggongmao1

我来修复该字符串解析问题,回归测试和中英文测试说明已准备,将提交关联 PR。

likedislike
CANN-robotCANN-robot成员
20 天前 将 hanggongmao1 设为负责人
puppypuppy
20 天前 关联了pull request:[fix] 修正单引号内反斜杠的命令分隔解析
Leewis成员
19 天前 评论:

问题确认:属实 ✅(已在 master 37fe471ed 本地复现并验证修复方案)

1. 缺陷根因

json_info.py:383-393 的 _consume_escape 判定反斜杠转义时不感知单引号状态:_consume_command_char(json_info.py:430)的消费者链把 _consume_escape 排在最前,因此单引号内的 \ 也会置 escape_next=True,把紧随其后的结束单引号当作被转义的字面字符吃掉。

而 POSIX shell 语义中单引号内一切字符均为字面(反斜杠无特殊含义),'foo\' 是合法闭合的 foo\。

后果链:结束引号被吃 → in_single_quote 无法复位 → 其后所有字符(含 ; && || | & 分隔符)被 _consume_quoted_char 当引号内字符吞掉 → split_ignoring_quotes 返回单段 → sudo_cmd/su_cmd 只检查该段的 parts[0],后续 sudo/su 命令不会被改写。

2. 本地复现结果(Python 3.12.3,纯字符串处理,未执行任何远端命令)

场景 原版输出 期望输出
split_ignoring_quotes("printf '%s' 'foo\'; sudo id") ["printf '%s' 'foo\'; sudo id"](单段,; 丢失) ["printf '%s' 'foo\\'", ";", "sudo id"]
sudo_cmd 同命令 原样返回,sudo id 未加 -S -p '' printf '%s' 'foo\' ; sudo -S -p '' id
管道符 echo 'a\' | sudo tee /tmp/x 单段,| 丢失 三段,| 正确识别

shlex 交叉核对:shlex.split 产出 ['printf', '%s', 'foo\\;', 'sudo', 'id'],POSIX 词法确认 \ 后的单引号是闭合引号,与报告判断一致。

3. 影响面

  • 消费链入口唯一:dispatcher_common.exec_command_with_auth(dispatcher_common.py:199-200)逐级调用 sudo_cmd → su_cmd 后经 client.exec_command(cmd) 下发;调用方为 exec_cmd.py:44、exec_realtime_cmd.py:201,覆盖集群链路诊断工具的所有远端命令执行。
  • 实际后果:提权改写失效后,sudo 在未分配 tty 的 SSH exec 通道上无法读密码(exec_command_with_auth 虽仍向 stdin 写密码,但对未加 -S 的 sudo 无效),远端提权命令执行失败(NOPASSWD 场景除外)。
  • 该转义逻辑自 ef057cfd2(工具首次引入)即如此,非近期回归;仓内 escape_next 仅 json_info.py 一处,缺陷范围收敛。

4. 修复评估(本地已验证)

issue 建议的修法正确且为一行改动:_consume_escape 首个条件增加 not state["in_single_quote"],单引号内的 \ 落到 _consume_quoted_char 按字面处理。本地前后对照验证:

  • 修复后输出与 issue 期望逐字一致(见上表);
  • 回归面不变:引号外转义(a\;b 不分割)、双引号内转义("a\";b" 不分割)、</> 重定向与 & 判定、whoami && sudo whoami && whoami、su 转换均保持原行为;
  • 边界说明:修复后 escape_next 只在引号外/双引号内置位,转义恰好消费一个字符,不存在跨引号边界泄漏路径。

5. 备注

  • 报告者已 /assign 并计划提交含 7 个 CPU 测试方法的关联 PR,本分析结论与其报告一致,可作交叉确认。
  • 代码位于 experimental/cluster_link_diag/(实验性集群链路诊断工具),不涉及 src/ 架构分层约束。

本回复为 AI 结合源码深度分析生成,将同步对应责任田团队进行二次确认。

likedislike
LLeewis成员
18 天前 issue类型由 任务 改变为 缺陷
LLeewis成员
18 天前 关联了看板:HCOMM
puppy
puppy
14 天前 评论:

@Leewis 感谢此前跟进。补充当前进展:此前认领后的修复已提交为 PR #5925,当前 HEAD 8a0b511f699ad76757d8df951b3daa7b00ede7d3,社区 CI、CLA 汇总保持通过。7 个 CPU 测试方法已通过,覆盖单引号字面反斜杠、五种连接符、sudo/su 转换及原有转义/重定向行为,测试仅做字符串处理,未执行 SSH、sudo、su 或设备操作。

当前尚待正式 experimental 模块检视及批准。烦请协助转交实际评审负责人,并请确认仓库 PR 模板要求的前冒烟阶段对这项工具修复是否适用、现有 CI 对应哪些用例;若还需作者补测,请明确用例和执行方式。issue 保持开放,待 PR 合入后闭环。

likedislike
Leewis成员
14 天前 评论:

@Leewis 感谢此前跟进。补充当前进展:此前认领后的修复已提交为 PR #5925,当前 HEAD 8a0b511f699ad76757d8df951b3daa7b00ede7d3,社区 CI、CLA 汇总保持通过。7 个 CPU 测试方法已通过,覆盖单引号字面反斜杠、五种连接符、sudo/su 转换及原有转义/重定向行为,测试仅做字符串处理,未执行 SSH、sudo、su 或设备操作。

当前尚待正式 experimental 模块检视及批准。烦请协助转交实际评审负责人,并请确认仓库 PR 模板要求的前冒烟阶段对这项工具修复是否适用、现有 CI 对应哪些用例;若还需作者补测,请明确用例和执行方式。issue 保持开放,待 PR 合入后闭环。

@hanggongmao1

收到,我这边将同步给对应committer进行检视加分,感谢参与社区贡献;

likedislike
puppy
puppy
14 天前 评论:

@Leewis 感谢协调。PR #5925 已更新到 e058ee424c98913f5c1e1951f8ee35e7faa4a6e3:已移除新增的测试 Python 脚本及两份 README 中的入口,最终差异仅保留 json_info.py 的一行修复。原始 7 项 CPU 回归已在仓外重跑通过,pre-commit / OAT 通过;新提交已单独请求 /compile,旧提交的 CI 结果不用于本轮。详细变更和验证已同步 PR 描述,烦请转交对应 committer 检视。issue 保持开放,待修复合入后闭环。

likedislike
CANN-robotCANN-robot成员
10 天前 关闭了 issue
CANN-robotCANN-robot成员
10 天前 添加了label:resolved