已合并
build: 回退打包期权限收紧,交回 cmake 默认值 #504
build: 回退打包期权限收紧,交回 cmake 默认值 #504
已合并
sinat_31531339创建于 24 天前
sinat_31531339
sinat_31531339成员
24 天前

描述

回退打包期对目录权限的收紧,交回 cmake 默认的 755;文件权限保持 555 不变

为什么要回退

打包声明把目录权限收紧到 555(r-xr-xr-x)后,落地的目录没有 owner 写位
而 unlink 一个条目要的是父目录的写位——父目录缺 u+w 就删不掉里面的内容。
于是 build/_CPack_Packages/ 下的 staging 子树一旦产出,rm -rf build 全程
Permission denied这与是不是 root 无关:目录属主本就是当前用户,属主自己
也删不掉。

直接后果是 CI 随机失败:流水线复用工作区,下一轮清理残留 build/ 时删不掉
即报错;而失败与否取决于上一轮是否跑到了产出 555 目录的打包阶段,所以表现为
时好时坏的随机失败,不易复现也不易定位。

权限收紧本身是后续需求要做的整改项(届时需连带解决产物目录的可删除性)。
当前先做删除处理,让产物目录恢复可删除,先把 CI 随机失败止住。

为什么只回退目录、不动文件

初版是全量回退(目录 + 文件都交回默认值)。评审(jinyingqi,major)指出:本 PR
要解决的是目录缺 owner 写位,而文件无写位并不阻塞 rm -rf,删除只看父目录的
写位;全量回退会让 profiler_tool 文件从 555 退回 644,属超出问题范围的行为回退,
且可能丢失脚本/工具文件的可执行位。

该意见成立,已按其建议收窄。收窄方案经本地实测确认不影响 build/ 的删除
(见下方"本地实测结果"),故采纳。

改动点

位置 改动 改动后
CMakeLists.txt built-in 段 删除 DIRECTORY_PERMISSIONS ... 555 目录 755;文件保留显式 440
msprofbin/CMakeLists.txt whl 段 保留 install(PROGRAMS)PERMISSIONS 555 whl 555(不变)
msprofbin/CMakeLists.txt 解包段 保留 FILE_PERMISSIONS 555,删除 DIRECTORY_PERMISSIONS 文件 555(不变)/ 目录 755

即:只放开目录的 owner 写位,文件权限一律不动。这样既修好产物目录的可删除性,
又让 --noexec --extract 旁路(不跑安装脚本)下的文件权限与运行期
msprof_install.shchange_file_mode 555 保持一致。

whl 的解包方式不变(仍是构建期 add_custom_command 解包 + install(DIRECTORY)
声明进包),本 PR 只调整权限声明。

补充事实:安装后的权限不由 cmake 声明决定

评审过程中核实了整条权限链路,一并记录,避免后续误解:

XML install_mod  →  filelist.csv 的 permission 字段  →  安装期 install_common_parser.sh
                                                        do_chmod_file_dir → change_mod_and_own_*

实测本次构建产物 filelist.csvtools/profiler/profiler_tool = 750
(来自 oam_tools.xml:107)、opp/built-in/op_impl/ai_core/tbe = 550
DetectInfo.xml:25)、.../tbe/impl/ops_oam = 555DetectInfo.xml:17)。
change_mod_and_own_dirs()common_func_v2.inc:958)只读 csv 的 mod 字段,
完全不看 cmake 的 install() 声明

所以本改动不影响 --full 正常安装后的任何权限,受影响的只有打包 staging 树与
--noexec --extract 旁路——而 staging 树里的 555 目录正是要修的问题。

用例改动

新增 test/ut/asys/testcase/common/test_build_dir_removable.py,看护"编译产物
目录在编译后可被删除",5 条用例分两层:

用例 作用
test_scan_actually_finds_cmake_files 自检:确认扫描确有产出、顶层 CMakeLists.txt 在范围内
test_no_directory_permission_decl_drops_owner_write 静态看护:任何 DIRECTORY_PERMISSIONS 声明都必须含 OWNER_WRITE
test_no_cmake_chmod_strips_owner_write 静态看护:禁止会作用到目录的 chmod 摘掉 owner 写位
test_dir_without_owner_write_blocks_removal 机制验证:555 目录下的内容确实无法 rmtree,复现根因
test_restoring_owner_write_makes_dir_removable 机制验证:补回 owner 写位后即可删除

第 3 条只查会作用到目录的两种写法——递归 chmod -R <mode>、以及
find -type d ... -exec chmod <mode>;纯文件 chmod(chmod 440 file
find -type f -exec chmod 555)放行,因为文件无写位不影响删除。

同步修改 test_msprof_whl_package.py:断言文件权限必须显式 555(FILE_PERMISSIONS
与 whl 的 PERMISSIONS),且目录权限要么不声明、要么必须含 OWNER_WRITE

实现上有几点是踩坑与评审后定下来的,一并说明:

  1. 仓库根按标记向上搜索,不按固定层级数推算。初版用
    Path(__file__).resolve().parents[5],在云端流水线的工作区布局下算到了不存在
    的路径(报"文件地址没有找到")。更隐蔽的是:路径算错时扫不到任何文件、违规
    列表恒为空,静态看护会静默通过。故改为向上搜索
    CMakeLists.txt + build.sh + cmake 三者同时存在的目录;找不到时返回
    None、由用例 skip不在模块级抛异常——那会让 pytest 在收集阶段报
    ERROR 并中断整个会话)。并新增上表第 1 条自检用例堵住"扫不到→静默通过"。

  2. test_dir_without_owner_write_blocks_removal 在 root 下 skip。root 有
    CAP_DAC_OVERRIDE,绕过权限位检查,555 目录下 rmtree 照样成功,无法复现
    普通用户的 PermissionError;而云端 UT 以 root 运行(产物路径
    /tmp/pytest-of-root/)。真正的看护由两条静态扫描承担,与运行身份无关。
    finally 里恢复写位也补了存在性判断——目录可能已被删掉,直接 chmod 会抛
    FileNotFoundError 盖住断言的真实失败原因。

  3. Path.chmod 而非调外部 chmodchmod 在不同发行版下路径不同
    /bin/usr/bin),写死绝对路径会在部分环境抛 FileNotFoundError

  4. install(DIRECTORY) 关键字表按 cmake 官方签名补全,作为权限串的终止边界,
    避免跨声明匹配(原来只列了 7 个,遗漏 TYPE/USE_SOURCE_PERMISSIONS/
    CONFIGURATIONS/EXCLUDE_FROM_ALL/REGEX/PERMISSIONS 等)。

变更类型

请选择本次引入的变更类型(勾选对应项):

如何测试

  1. 全量打包:

    bash build.sh -j16
    
  2. 核心判据——确认产物目录可删除(改动前此处会 Permission denied):

    find build -type d ! -perm -u+w | wc -l   # 期望 0
    rm -rf build && echo "build removed ok"
    
  3. 核对 staging 树权限(确认文件仍为 555、目录已放开写位):

    S=build/_CPack_Packages/makeself_staging
    find $S/tools/profiler/profiler_tool -type f -printf '%m\n' | sort | uniq -c  # 期望 555
    find $S/tools/profiler/profiler_tool -type d -printf '%m\n' | sort | uniq -c  # 期望 755
    find $S/opp/built-in/op_impl/ai_core/tbe -type d -printf '%m\n' | sort -u     # 期望 755
    find $S/opp/built-in/op_impl/ai_core/tbe -type f -printf '%m\n' | sort -u     # 期望 440
    
  4. UT:

    python3 -m pytest test/ut/asys/testcase/common/test_build_dir_removable.py -v
    python3 -m pytest test/ut/asys/testcase/common/test_msprof_whl_package.py -v
    python3 -m pytest test/ut/asys/ test/ut/msaicerr/ -q
    

本地实测结果(收窄方案)

  • bash build.sh -j16 通过(exit=0)。

  • 核心判据通过find build -type d ! -perm -u+w | wc -l = 0
    rm -rf build 成功。这是采纳收窄方案的前提条件,已确认满足。

  • staging 权限与预期一致:profiler_tool 764 个文件全为 555、135 个目录 755;
    tbe 40 个目录 755、84 个文件 440。

  • test_build_dir_removable.py 5 passed、test_msprof_whl_package.py 9 passed。

  • 静态看护有效性反向验证:

    注入的写法 期望 实测
    加回 DIRECTORY_PERMISSIONS ... 555 拦截 ✅ 转红并报出违规位置
    chmod -R 555 <dir> 拦截 ✅ 转红
    find -type d -exec chmod 555 拦截 ✅ 转红
    find -type f -exec chmod 555 放行 ✅ 通过
    chmod 440 some_file 放行 ✅ 通过
    纯注释行 # chmod -R 555 ... 忽略 ✅ 通过
  • 全量 test/ut/asys/ test/ut/msaicerr/:1213 passed / 15 skipped,
    另有 1 项 test_compile_op_ascend950.py::test_get_ub_size_not_tbe 失败,
    已在干净的 upstream/master worktree 上复现,属存量失败、与本改动无关

  • msprof gtest 未在本地跑,依赖云端 UT_Test

核对清单

其他信息

本 PR 已同步一份到 9.1.0 分支:#505。两分支权限终态一致,但实现写法不同——
9.1.0 上 whl 处理位于 msprofbin/closed/CMakeLists.txt 且为 install(CODE) +
chmod -R 555 形态(master 已重构为构建期 add_custom_command 解包 +
install(DIRECTORY)),故那边改为 find -type f -exec chmod 555(只作用文件、
目录保持 pip 解出的 755)来达到同一效果,而非直接 cherry-pick。

likedislike
Pull Request已成功合入, 合并人@CANN-robot
(感谢 sinat_31531339 的贡献)
sinat_31531339sinat_31531339成员
24 天前 创建了 pull request,commit f5456dcd
atomgit-bot
atomgit-bot
24 天前 评论:

变更摘要

本 PR 回退了打包期对文件/目录权限的显式收紧,将权限控制交回 cmake install() 的默认值:在 CMakeLists.txt 的 built-in 段删除 DIRECTORY_PERMISSIONS ... 555,在 msprofbin/CMakeLists.txt 的 whl 段删除 install(PROGRAMS)PERMISSIONS 555,并在其解包段删除 install(DIRECTORY)FILE_PERMISSIONS / DIRECTORY_PERMISSIONS 555。回退后 profiler_tool 子树的权限终态由运行期 msprof_install.sh 末尾的 change_dir_mode 555 / change_file_mode 555 收口,打包期不再重复声明。相应的看护用例 test/ut/asys/testcase/common/test_msprof_whl_package.py 也同步反向调整。

主要改动

  • built-in 段目录权限回退CMakeLists.txt 的 built-in 段删除 DIRECTORY_PERMISSIONS ... 555,使 opp/built-in/op_impl/ai_core/tbe 目录回到默认 755,文件仍保留显式 440
  • whl 段权限回退msprofbin/CMakeLists.txt 的 whl 段删除 install(PROGRAMS)PERMISSIONS 555,使 whl 回到 PROGRAMS 默认的 755
  • 解包段权限回退msprofbin/CMakeLists.txt 的解包段删除 install(DIRECTORY)FILE_PERMISSIONS / DIRECTORY_PERMISSIONS 555,使 tools/profiler/profiler_tool 子树回到文件 644 / 目录 755
  • 看护用例反向调整test_msprof_whl_package.pytest_install_directory_declares_555_permissions 改为 test_install_directory_declares_no_explicit_permissions,并断言 install(DIRECTORY) 块内不含 FILE_PERMISSIONS / DIRECTORY_PERMISSIONS
  • whl 看护用例反向调整test_install_programs_whl_declares_555_permissions 改为 test_install_programs_whl_declares_no_explicit_permissions,并断言 install(PROGRAMS) 块内不含 PERMISSIONS
likedislike
atomgit-bot
atomgit-bot
24 天前 评论:

代码审查

✅ 未发现问题

likedislike
CANN-robotCANN-robot成员
24 天前 添加了label:cann-cla/yes
CANN-robot
CANN-robot成员
24 天前 评论:

Thanks for your pull-request.
The full list of commands accepted by me can be found at here
You can get sig-info at here
For more, you also can visit HICANN


PR Approval Progress

Congratulations! All modules have met the lgtm and approve requirements.

Module Approval Details

module lgtm status approve status
repo-cann/oam-tools newstarzj, zhuliangying, 金瑛琪 (3/2) zhuliangying (1/1)

💡 Tip:

  • Committer can comment /approve or /lgtm
  • Commenting /approve implies both code review (lgtm) and intent to merge (approve)

CLA Signature Pass

sinat_31531339, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
此处折叠了114条消息 查看更多
jinyingqi成员
23 天前 评论:

/lgtm

likedislike
CANN-robotCANN-robot成员
23 天前 添加了label:lgtm
zhuliangying成员
23 天前 评论:

/approve

likedislike
CANN-robotCANN-robot成员
23 天前 添加了label:approved
CANN-robotCANN-robot成员
23 天前 合入了pull request