已关闭
[Bug] strided_slice_assign_v2 负 axes 导致 host abort(AdjustWithAxes 未校验) #2485
Agent-Bug-Hunter创建于 28 天前关闭于 13 天前
27 天前 关联了pull request:fix(conversion): validate pad and slice axes bounds
陈思
27 天前 评论:
27 天前 评论:
收到,已联系算子责任人确认修复中


27 天前 删除了关联的pull request:fix(conversion): validate pad and slice axes bounds
27 天前 将 chensi79 设为负责人
26 天前 移除了负责人 chensi79
26 天前 将 sunchun 设为负责人
18 天前 关联了pull request:fix: StridedSliceAssignV2 负 axes 归一化与越界校验
14 天前 issue状态由 进行中 改变为 挂起
13 天前 关闭了 issue
13 天前 添加了label:resolved
摘要
aclnnStridedSliceAssignV2的 host tilingAdjustWithAxes将axes[i]直接用作beginAdjust/endAdjust/stridesAdjust下标,未校验0 ≤ axes[i] < dimNum。环境
2d1098d3e902cann-ops-math-cann_scan_repro_linux-*.run→$ASCEND_HOME_PATH/vendors/cann_scan_repro_math为什么认为这是问题:期望 vs 实际
输入(与复现用例一致)
期望行为
实际行为(aclnn / 源码编译安装路径)
free(): invalid pointer后 exit 42对比结论
根因
Positive OOB axes (
{99}/{2}) are rejected with561002(API layer). Negative axes are not rejected and reach host tilingAdjustWithAxes, which indexesbeginAdjust[axes[i]]with noaxes ∈ [0, dimNum)check.(详细行号见同目录 FINDING.md 与算子源码;归档时已通过 aclnn exit 42 确认。)
为何确认跑的是源码编译内核(非 built-in)
source $ASCEND_HOME_PATH/vendors/cann_scan_repro_math/bin/set_env.bash,ASCEND_CUSTOM_OPP_PATH指向该 vendor。op_api/op_impl,而非仅依赖 CANN built-in 同名算子(见repro_manifest.json中built_from_source=true)。完整复现过程
占位符:
$ASCEND_HOME_PATH/$OPS_MATH/$REPRO_ROOT。步骤 1:环境使能
source <CANN安装目录>/ascend-toolkit/set_env.sh步骤 2:源码编译单算子包
cd "$OPS_MATH" bash build.sh --pkg --soc=ascend910b --ops=strided_slice_assign_v2 \ --vendor_name=cann_scan_repro -j8成功标志:生成
$OPS_MATH/build_out/cann-ops-math-cann_scan_repro_linux-*.run步骤 3:安装并切换到自定义包
bash $OPS_MATH/build_out/cann-ops-math-cann_scan_repro_linux-*.run \ --quiet --install-path="$ASCEND_HOME_PATH" source "$ASCEND_HOME_PATH/vendors/cann_scan_repro_math/bin/set_env.bash" echo "ASCEND_CUSTOM_OPP_PATH=$ASCEND_CUSTOM_OPP_PATH"步骤 4:放置复现源码与执行脚本
(本 draft 目录内已含上述文件,可直接作为
$REPRO_ROOT。)步骤 5:编译并运行
cd "$REPRO_ROOT" chmod +x build_and_run_repro.sh bash build_and_run_repro.sh --vendor cann_scan_repro --src test_aclnn_ssav2_negaxes.cpp # 退出码 42 = BUG_REPRODUCED成功复现标志:进程退出码 42。
实际运行摘录
复现用例源码
文件名:
test_aclnn_ssav2_negaxes.cpp#include <cstdio> #include <csignal> #include <cstdlib> #include <vector> #include "acl/acl.h" #include "aclnnop/aclnn_strided_slice_assign_v2.h" #define LOG_PRINT(m,...) do{printf(m,##__VA_ARGS__);}while(0) static void OnCrash(int sig){LOG_PRINT("BUG_REPRODUCED: host crash sig=%d case=negaxes\n",sig);_Exit(42);} static int64_t GS(const std::vector<int64_t>& s){int64_t n=1;for(auto i:s)n*=i;return n;} template<typename T> static int CT(const std::vector<T>& h,const std::vector<int64_t>& shape,void** d,aclDataType dt,aclTensor** t){ auto size=GS(shape)*sizeof(T); aclrtMalloc(d,size,ACL_MEM_MALLOC_HUGE_FIRST); aclrtMemcpy(*d,size,h.data(),size,ACL_MEMCPY_HOST_TO_DEVICE); std::vector<int64_t> st(shape.size(),1); for(int64_t i=(int64_t)shape.size()-2;i>=0;i--) st[i]=shape[i+1]*st[i+1]; *t=aclCreateTensor(shape.data(),shape.size(),dt,st.data(),0,ACL_FORMAT_ND,shape.data(),shape.size(),*d); return 0; } int main(){ std::signal(SIGSEGV,OnCrash); std::signal(SIGABRT,OnCrash); std::signal(SIGBUS,OnCrash); aclrtStream stream; aclInit(nullptr); aclrtSetDevice(0); aclrtCreateStream(&stream); std::vector<int64_t> varShape={4,3}, valShape={2,2}; void *varDev=nullptr,*valDev=nullptr; aclTensor *varRef=nullptr,*inputValue=nullptr; std::vector<float> varHost={0,1,2,3,4,5,6,7,8,9,10,11}, valHost={-1,-2,-3,-4}; std::vector<int64_t> beginData={1,0}, endData={4,2}, stridesData={2,1}, axesData={-1,1}; CT(varHost,varShape,&varDev,ACL_FLOAT,&varRef); CT(valHost,valShape,&valDev,ACL_FLOAT,&inputValue); auto begin=aclCreateIntArray(beginData.data(),beginData.size()); auto end=aclCreateIntArray(endData.data(),endData.size()); auto strides=aclCreateIntArray(stridesData.data(),stridesData.size()); auto axes=aclCreateIntArray(axesData.data(),axesData.size()); uint64_t ws=0; aclOpExecutor* ex=nullptr; auto ret=aclnnStridedSliceAssignV2GetWorkspaceSize(varRef,inputValue,begin,end,strides,axes,&ws,&ex); LOG_PRINT("GetWS ret=%d ws=%llu\n", ret, (unsigned long long)ws); if(ret==0){ void* wa=nullptr; if(ws) aclrtMalloc(&wa,ws,ACL_MEM_MALLOC_HUGE_FIRST); auto r2=aclnnStridedSliceAssignV2(wa,ws,ex,stream); auto r3=aclrtSynchronizeStream(stream); LOG_PRINT("launch=%d sync=%d\n",r2,r3); if(r2==0&&r3==0){LOG_PRINT("BUG_REPRODUCED: illegal input accepted\n"); return 42;} } LOG_PRINT("NO_REPRO\n"); return 0; }执行脚本
文件名:
build_and_run_repro.sh#!/usr/bin/env bash set -euo pipefail VENDOR=""; SRC_NAME="" while [[ $# -gt 0 ]]; do case "$1" in --vendor) VENDOR="$2"; shift 2 ;; --src) SRC_NAME="$2"; shift 2 ;; *) echo "unknown arg: $1" >&2; exit 2 ;; esac done : "${ASCEND_HOME_PATH:?}" ROOT="$(cd "$(dirname "$0")" && pwd)" if [[ -z "$SRC_NAME" ]]; then mapfile -t _srcs < <(ls "$ROOT"/test_aclnn_*.cpp 2>/dev/null || true) [[ ${#_srcs[@]} -eq 1 ]] || { echo "need --src"; exit 2; } SRC="${_srcs[0]}" else SRC="$ROOT/$SRC_NAME"; fi BIN="${SRC%.cpp}" if [[ -n "$VENDOR" ]]; then for cand in "${ASCEND_HOME_PATH}/vendors/${VENDOR}_math" "${ASCEND_HOME_PATH}/vendors/${VENDOR}"; do if [[ -f "$cand/bin/set_env.bash" ]]; then set +u; source "$cand/bin/set_env.bash"; set -u echo "[env] sourced $cand/bin/set_env.bash" echo "[env] ASCEND_CUSTOM_OPP_PATH=${ASCEND_CUSTOM_OPP_PATH:-}" break fi done fi INC="${ASCEND_HOME_PATH}/aarch64-linux/include"; LIB="${ASCEND_HOME_PATH}/aarch64-linux/lib64" echo "[build] g++ $SRC" g++ -std=c++17 -O2 "$SRC" -I"$INC" -I"$INC/aclnnop" -L"$LIB" -Wl,-rpath,"$LIB" \ -lascendcl -lnnopbase -lopapi -o "$BIN" echo "[run] $BIN" set +e; "$BIN"; RC=$?; set -e echo "[exit] $RC (42=BUG_REPRODUCED, 0=NO_REPRO, 1=harness error)" exit "$RC"修复建议
在 host/tiling/kernel 入口拒绝非法索引或控制量,返回明确参数错误;勿静默 OOB。
人工复核说明
Agent 复现结果供参考;语义边界(是否允许 wrap、文档是否声明调用方契约)以人工结论与产品规范为准。