feat(axruntime): add compiler-backed stack protector support#1239
Conversation
There was a problem hiding this comment.
审查结论:APPROVE
PR 概览
此 PR 为项目增加了编译器支持的栈帧级 stack protector 支持,是现有 stack-canary(任务栈底 canary)的补充——后者仅检查栈底是否被覆盖,而编译器插入的 canary 可以发现函数局部栈溢出。
实现逻辑
-
运行时支持 (
os/arceos/modules/axruntime/src/stack_protector.rs):提供__stack_chk_guard(全局 canary 值)和__stack_chk_fail(溢出失败时的 panic 处理)。cfg条件为feature = "stack-protector"且target_os = "none"或target_env = "musl",正确覆盖了 bare-metal 和 std-compat 两种构建目标。 -
特性传播:
stack-protector特性从axruntime→axfeat→axstd/axlibc→starry-kernel/starryos/axvisor的传播链完整且一致。 -
构建系统 (
scripts/axbuild/src/build.rs):新增features_enable_stack_protector()和toolchain_rustflags_for_features(),在特性启用时注入-Zstack-protector=strong。该函数同时替换了 ArceOS C app 构建和 std 构建中的调用点,Axvisor 构建路径也通过apply_makefile_features_with_metadata正确处理了 MakefileFEATURES环境变量的合并。 -
文档:在
docs/docs/debug/check-mechanisms-summary.md中新增了 Linux 参考机制说明、项目当前差距分析、四架构支持评估及分阶段实施计划。
验证结果
| 检查项 | 结果 |
|---|---|
cargo fmt --check |
✅ 通过 |
cargo clippy --manifest-path scripts/axbuild/Cargo.toml --all-features -- -D warnings |
✅ 通过 |
cargo clippy --manifest-path os/arceos/modules/axruntime/Cargo.toml --all-features -- -D warnings |
✅ 通过 |
cargo test --manifest-path scripts/axbuild/Cargo.toml --all-features |
✅ 633/634 通过(1 个预存失败 checked_in_build_configs_do_not_declare_default_dynamic_builds 与本次变更无关) |
cargo test --manifest-path os/arceos/modules/axruntime/Cargo.toml --all-features |
✅ 8/8 通过 |
[patch.crates-io] 检查 |
✅ 未发现 |
CI 状态
Run sync-lint / run_container: ✅ successDetect changed paths: ✅ successCancel stale CI runs: ✅ successCheck formatting / run_host: ⏳ queued(等待 runner,本地cargo fmt --check已通过)- 其余
skipped的 job(run_hostsync-lint、run_containerformatting、容器镜像发布)均为预期的矩阵/路径过滤行为,非 PR 引起
mergeable_state: unstable 是因 formatting 检查尚未完成所致,非合并冲突。
重复/重叠分析
- 搜索
stack-protector、stack_chk、__stack_chk关键字,base 分支无现有实现。 - 同名 open PR 搜索仅返回 #1239 自身,无重复或重叠 PR。
- PR #1237(同一作者的 Starry fd/wait/timerfd 修复)改动范围与此 PR 完全无交集,无冲突风险。
注意事项(非阻塞)
__stack_chk_guard 当前为硬编码常量 0x57AC_CE11_5A7A_CE11。文档中已明确将此作为"第一阶段全局 guard 方案",后续再评估 per-task/per-cpu guard。这一设计在当前阶段是合理的第一步,建议在第二阶段实现时增加启动时随机化。
Powered by deepseek-v4-pro
ZR233
left a comment
There was a problem hiding this comment.
审查当前 head 5be05adba01b98d408237fa713f1825de1d01751,批准。
本次改动的合入条件逐项检查如下:
- 变更范围:
axruntime提供__stack_chk_guard/__stack_chk_fail,stack-protectorfeature 从ax-runtime向axfeat、axstd/axlibc、StarryOS 和 Axvisor 传播,axbuild在启用相关 feature 时注入-Zstack-protector=strong。实现链路和 PR 目标一致。 - 运行时约束:模块只在
feature = "stack-protector"且target_os = "none"或target_env = "musl"、非 test 构建下启用,避免影响普通 host test;当前阶段使用全局 guard,与文档中的阶段性方案一致。 - 重复/重叠检查:base 分支没有已有
stack-protector/__stack_chk实现;open PR 中未发现重复实现。#1076 虽也触及axruntime,但不是 stack protector 运行时和 axbuild feature 注入这条路径,未构成阻塞重叠。 - 本地验证:
cargo fmt --check通过;git diff --check origin/dev...HEAD通过;未发现新增[patch.crates-io]。 - 本地验证:
cargo test --manifest-path scripts/axbuild/Cargo.toml --all-features stack_protector -- --nocapture通过,覆盖 stack protector feature 检测、rustflags 注入、std build config、Axvisor Makefile FEATURES 合并路径。 - 本地验证:
cargo clippy --manifest-path os/arceos/modules/axruntime/Cargo.toml --all-features -- -D warnings通过;cargo xtask clippy --package axbuild通过;cargo xtask clippy --package ax-runtime通过。 - 实际构建验证:使用显式临时 config 运行
FEATURES=stack-protector cargo xtask arceos build --config /tmp/pr1239-arceos-build.toml --package arceos-helloworld --target x86_64-unknown-none通过;生成的 axbuild config 含-Zstack-protector=strong;产物 ELF 定义了__stack_chk_fail和__stack_chk_guard,且没有未解析的 stack check 符号。 - CI 状态:当前 head 上
Detect changed paths、Run sync-lint / run_container、Cancel stale CI runs已通过;Check formatting / run_host仍在 runner 队列中。本地 fmt/diff check 已覆盖格式风险,其余 skipped job 符合当前 CI 矩阵/路径过滤。
默认本地 --arch x86_64 build config 在该 worktree 中不存在,因此实际构建验证改用了等价的显式 config;这不是本 PR 引入的问题。当前不需要额外 reviewer 指派。
5be05ad to
a1d0471
Compare
There was a problem hiding this comment.
审查结论:APPROVE
PR 概览
为 axruntime 增加编译器栈帧级 stack protector 支持:提供 __stack_chk_guard / __stack_chk_fail 运行时符号,并将 stack-protector 特性沿 ArceOS → StarryOS → Axvisor 构建链路传播,在启用时注入 -Zstack-protector=strong。当前阶段使用四架构通用全局 guard,文档中已明确分阶段实施计划。
审查要点
运行时实现 (stack_protector.rs):
__stack_chk_guard为硬编码常量0x57AC_CE11_5A7A_CE11,与文档中「第一阶段全局 guard」的描述一致__stack_chk_fail在溢出时 panic,符合预期cfg条件正确覆盖target_os = "none"(bare-metal) 和target_env = "musl"(std-compat),且排除 test 构建
特性传播链路:
axruntime/stack-protector→axfeat/stack-protector→axstd/axlibc→starry-kernel/starryos/axvisor,完整且一致- Axvisor 路径通过
apply_makefile_features_with_metadata正确合并 MakefileFEATURES环境变量
构建系统 (build.rs):
features_enable_stack_protector()检测四个已知特征表面名toolchain_rustflags_for_features()替换了 ArceOS C app 和 std 构建路径的调用点- 新增测试覆盖 feature 检测、rustflags 注入、std build config、Axvisor Makefile FEATURES 合并
本地验证
| 检查项 | 结果 |
|---|---|
cargo fmt --check |
✅ 通过 |
cargo clippy --manifest-path os/arceos/modules/axruntime/Cargo.toml --all-features -- -D warnings |
✅ 通过 |
cargo clippy --manifest-path scripts/axbuild/Cargo.toml --all-features -- -D warnings |
✅ 通过 |
cargo test --manifest-path scripts/axbuild/Cargo.toml --all-features |
✅ 650/651 通过,1 个预存失败 (checked_in_build_configs_do_not_declare_default_dynamic_builds,与本次变更无关) |
[patch.crates-io] 检查 |
✅ 未发现 |
CI 状态
Detect changed paths: ✅ successTest arceos aarch64 qemu / run_host: ✅ successTest arceos riscv64 qemu / run_container: skipped(预期,host 变体已通过)Test arceos loongarch64 qemu / run_container: skipped(预期,host 变体已通过)Test axvisor self-hosted board phytiumpi-linux / run_host: ✅ successTest axvisor self-hosted board roc-rk3568-pc-linux / run_host: ✅ successTest axvisor x86_64 svm hosted / run_host: ✅ successTest starry loongarch64 qemu / run_container: ✅ successTest starry self-hosted board orangepi-5-plus / run_host: ✅ successTest with std / run_container: skipped(路径过滤)Publish base container image: skipped(路径过滤)
mergeable_state: unstable 状态由部分 CI matrix job 的 skipped/queued 状态引起,非合并冲突。所有实际执行的 CI job 均通过。
重复/重叠分析
- base 分支无现有
stack-protector/__stack_chk实现 - open PR 中未发现重复或重叠实现(#1148 为 HTTP bootloader、#1135 为 ASUS board 支持、#1266 为 Wi-Fi AP/STA 切换、#1265 为 serial 重构,均无交集)
- 无
[patch.crates-io]引入
备注(非阻塞)
__stack_chk_guard 当前为编译时常量,文档已明确第二阶段再评估 per-task / per-cpu guard 及启动时随机化。当前设计作为四架构通用的第一阶段方案是合理的。
Powered by mimo-v2.5-pro
There was a problem hiding this comment.
审查结论:APPROVE
PR 概览
此 PR 为项目增加编译器栈帧级 stack protector 支持,作为现有 stack-canary(任务栈底 canary)的补充。编译器插入的 canary 可以发现函数局部栈溢出,而现有机制仅检查栈底覆盖。
实现逻辑
运行时 (stack_protector.rs):
- 提供
__stack_chk_guard(全局 canary 值0x57AC_CE11_5A7A_CE11)和__stack_chk_fail(溢出 panic) cfg条件正确覆盖target_os = "none"(bare-metal)和target_env = "musl"(std-compat),且排除 test 构建- 使用
#[unsafe(no_mangle)](Rust 2024 edition 语法)和#[used]保证符号不被优化
特性传播:
axruntime/stack-protector→axfeat/stack-protector→axstd/axlibc→starry-kernel→starryos/axvisor,链路完整一致- StarryOS:
starryos/stack-protector→ax-std/stack-protector+starry-kernel/stack-protector - Axvisor:
axvisor/stack-protector→ax-std/stack-protector
构建系统 (build.rs):
features_enable_stack_protector()检测四个已知特征表面名toolchain_rustflags_for_features()替换 ArceOS C app 和 std 构建路径调用点,注入-Zstack-protector=strong- Axvisor 构建路径通过
apply_makefile_features_with_metadata正确合并 MakefileFEATURES环境变量 is_known_axstd_feature列表已更新包含stack-protector
文档:新增 Linux 参考机制说明、项目当前差距分析、四架构支持评估及分阶段实施计划。
CI 状态
所有实际执行的 CI job 均已通过(本地无需重复测试):
Detect changed paths: ✅ successTest arceos aarch64 qemu / run_host: ✅ successTest axvisor self-hosted board phytiumpi-linux / run_host: ✅ successTest axvisor self-hosted board roc-rk3568-pc-linux / run_host: ✅ successTest axvisor x86_64 svm hosted / run_host: ✅ successTest starry loongarch64 qemu / run_container: ✅ successTest starry self-hosted board orangepi-5-plus / run_host: ✅ success
skipped job(riscv64/loongarch64 container 变体、Test with std、Publish base container image)均为预期的矩阵/路径过滤行为。
mergeable_state: unstable 由部分 CI matrix job 的 queued/skipped 状态引起,非合并冲突。
重复/重叠分析
- base 分支无现有
stack-protector/__stack_chk实现 - open PR 中未发现重复或重叠实现(#1266 为 Wi-Fi AP/STA 切换、#1265 为 serial IRQ 重构,均无交集)
- 未引入
[patch.crates-io]
之前审查意见
已有 3 个 APPROVE 审查(ZR233 人工审查 + 2 次自动审查),均确认实现正确。无未解决的 review thread。
非阻塞备注
__stack_chk_guard 当前为编译时常量,文档已明确将此作为「第一阶段全局 guard 方案」,第二阶段再评估 per-task / per-cpu guard 及启动时随机化。当前设计作为四架构通用的第一阶段方案是合理的。
新增测试覆盖了 feature 检测、rustflags 注入、std build config 生成、Axvisor Makefile FEATURES 合并路径,验证充分。
Powered by mimo-v2.5-pro
…s#1239) * docs(debug): document stack protector plan * feat(axruntime): add stack protector runtime support * feat(axbuild): enable stack protector rustflags
…FI boot 1. Remove __stack_chk_fail workarounds (PR rcore-os#1239 provides proper runtime): - lang_items.rs: remove duplicate __stack_chk_fail stub - build.rs: remove cross-arch-broken libgcc_s.a/__stack_chk_fail.o generation - build.rs: revert -lgcc_s|-lgcc linker wrapper to upstream (drop flag) 2. Align x86_64 guest build with dynamic platform (ax-plat-x86-pc removed): - prebuild.sh: update _generate_minimal_axconfig to use platform="x86_64-qemu" instead of the removed package="ax-plat-x86-pc" - prebuild.sh: add plat-dyn,axplat-dyn/efi features for x86_64 inner build 3. Implement UEFI/OVMF boot for self-compiled x86_64 kernel: - run-selfbuilt-kernel.sh x86_64: objcopy ELF→raw binary, create ESP with EFI/BOOT/BOOTX64.EFI, boot via OVMF firmware (pflash + fat:rw:esp) - Matches ostool's UEFI boot path used for seed kernel Co-Authored-By: Claude <noreply@anthropic.com>
…FI boot 1. Remove __stack_chk_fail workarounds (PR rcore-os#1239 provides proper runtime): - lang_items.rs: remove duplicate __stack_chk_fail stub - build.rs: remove cross-arch-broken libgcc_s.a/__stack_chk_fail.o generation - build.rs: revert -lgcc_s|-lgcc linker wrapper to upstream (drop flag) 2. Align x86_64 guest build with dynamic platform (ax-plat-x86-pc removed): - prebuild.sh: update _generate_minimal_axconfig to use platform="x86_64-qemu" instead of the removed package="ax-plat-x86-pc" - prebuild.sh: add plat-dyn,axplat-dyn/efi features for x86_64 inner build 3. Implement UEFI/OVMF boot for self-compiled x86_64 kernel: - run-selfbuilt-kernel.sh x86_64: objcopy ELF→raw binary, create ESP with EFI/BOOT/BOOTX64.EFI, boot via OVMF firmware (pflash + fat:rw:esp) - Matches ostool's UEFI boot path used for seed kernel Co-Authored-By: Claude <noreply@anthropic.com>
…FI boot 1. Remove __stack_chk_fail workarounds (PR rcore-os#1239 provides proper runtime): - lang_items.rs: remove duplicate __stack_chk_fail stub - build.rs: remove cross-arch-broken libgcc_s.a/__stack_chk_fail.o generation - build.rs: revert -lgcc_s|-lgcc linker wrapper to upstream (drop flag) 2. Align x86_64 guest build with dynamic platform (ax-plat-x86-pc removed): - prebuild.sh: update _generate_minimal_axconfig to use platform="x86_64-qemu" instead of the removed package="ax-plat-x86-pc" - prebuild.sh: add plat-dyn,axplat-dyn/efi features for x86_64 inner build 3. Implement UEFI/OVMF boot for self-compiled x86_64 kernel: - run-selfbuilt-kernel.sh x86_64: objcopy ELF→raw binary, create ESP with EFI/BOOT/BOOTX64.EFI, boot via OVMF firmware (pflash + fat:rw:esp) - Matches ostool's UEFI boot path used for seed kernel Co-Authored-By: Claude <noreply@anthropic.com>
…FI boot 1. Remove __stack_chk_fail workarounds (PR rcore-os#1239 provides proper runtime): - lang_items.rs: remove duplicate __stack_chk_fail stub - build.rs: remove cross-arch-broken libgcc_s.a/__stack_chk_fail.o generation - build.rs: revert -lgcc_s|-lgcc linker wrapper to upstream (drop flag) 2. Align x86_64 guest build with dynamic platform (ax-plat-x86-pc removed): - prebuild.sh: update _generate_minimal_axconfig to use platform="x86_64-qemu" instead of the removed package="ax-plat-x86-pc" - prebuild.sh: add plat-dyn,axplat-dyn/efi features for x86_64 inner build 3. Implement UEFI/OVMF boot for self-compiled x86_64 kernel: - run-selfbuilt-kernel.sh x86_64: objcopy ELF→raw binary, create ESP with EFI/BOOT/BOOTX64.EFI, boot via OVMF firmware (pflash + fat:rw:esp) - Matches ostool's UEFI boot path used for seed kernel Co-Authored-By: Claude <noreply@anthropic.com>
…FI boot 1. Remove __stack_chk_fail workarounds (PR rcore-os#1239 provides proper runtime): - lang_items.rs: remove duplicate __stack_chk_fail stub - build.rs: remove cross-arch-broken libgcc_s.a/__stack_chk_fail.o generation - build.rs: revert -lgcc_s|-lgcc linker wrapper to upstream (drop flag) 2. Align x86_64 guest build with dynamic platform (ax-plat-x86-pc removed): - prebuild.sh: update _generate_minimal_axconfig to use platform="x86_64-qemu" instead of the removed package="ax-plat-x86-pc" - prebuild.sh: add plat-dyn,axplat-dyn/efi features for x86_64 inner build 3. Implement UEFI/OVMF boot for self-compiled x86_64 kernel: - run-selfbuilt-kernel.sh x86_64: objcopy ELF→raw binary, create ESP with EFI/BOOT/BOOTX64.EFI, boot via OVMF firmware (pflash + fat:rw:esp) - Matches ostool's UEFI boot path used for seed kernel Co-Authored-By: Claude <noreply@anthropic.com>
* docs(debug): document stack protector plan * feat(axruntime): add stack protector runtime support * feat(axbuild): enable stack protector rustflags
Problem
The existing stack canary mechanism mainly protects kernel stack boundaries, but it does not cover per-function stack frame
corruption. Linux stack protector support relies on compiler-inserted canary checks in function prologues/epilogues, while the kernel provides the runtime guard and failure handler symbols. This change adds the missing compiler-side and runtime-side integration.
Changes
axruntime, including__stack_chk_guardand__stack_chk_fail.stack-protectorfeature through ArceOS, StarryOS, and Axvisor related crates.axbuildto inject-Zstack-protector=strongwhen the feature is enabled.docs/docs/debug/check-mechanisms-summary.md.