error log
AddressSanitizer:DEADLYSIGNAL
=================================================================
==3215629==ERROR: AddressSanitizer: FPE on unknown address 0x5648463adbbb (pc 0x5648463adbbb bp 0x7ffd3666aa50 sp 0x7ffd3666a890 T0)
#0 0x5648463adbbb in ncnn::ConvolutionDepthWise::load_param(ncnn::ParamDict const&) /src/test/results/fuzzing_ncnn/test/ncnn/src/layer/convolutiondepthwise.cpp:46:20
#1 0x564844c40abc in ncnn::Net::load_param(ncnn::DataReader const&) /src/test/results/fuzzing_ncnn/test/ncnn/src/net.cpp:1524:35
#2 0x564844c69fee in ncnn::Net::load_param(_IO_FILE*) /src/test/results/fuzzing_ncnn/test/ncnn/src/net.cpp:2177:22
#3 0x564844c1dbdb in main /src/test/fuzzing_ncnn/harness.cpp:17:9
#4 0x7ff2814461c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
#5 0x7ff28144628a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
#6 0x564844b3a194 in _start (/src/test/results/fuzzing_ncnn/test/ncnn/build/ncnn_param+0x13e194) (BuildId: 8489885d434959364ed3a3e9d6ed984798b5dc8d)
==3215629==Register values:
rax = 0x000000000000003a rbx = 0x0000519000001980 rcx = 0x000052100012ca80 rdx = 0x0000000000000000
rdi = 0x0000519000001af0 rsi = 0x0000000000000980 rbp = 0x00007ffd3666aa50 rsp = 0x00007ffd3666a890
r8 = 0x0000000000000001 r9 = 0x0000000000000001 r10 = 0x0000000000000028 r11 = 0x0000000000000000
r12 = 0x00007ff27f71d140 r13 = 0x00007ff27fb001c0 r14 = 0x00007ff27f71d000 r15 = 0x00000ffe4fee3a00
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE /src/test/results/fuzzing_ncnn/test/ncnn/src/layer/convolutiondepthwise.cpp:46:20 in ncnn::ConvolutionDepthWise::load_param(ncnn::ParamDict const&)
==3215629==ABORTING
how to reproduce
git clone https://github.com/Tencent/ncnn.git
cd ncnn
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer -g" \
-DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer -g" \
-DNCNN_BUILD_TOOLS=OFF \
-DNCNN_BUILD_EXAMPLES=OFF
make -j$(nproc)
# Build the harness test program (calls ncnn library's load_param entry)
cat > harness.cpp << 'EOF'
#include <cstdio>
#include "net.h"
int main(int argc, char** argv) {
if (argc < 2) return 0;
ncnn::Net net;
net.opt.use_vulkan_compute = false;
FILE* fp = fopen(argv[1], "rb");
if (!fp) return 0;
net.load_param(fp);
fclose(fp);
return 0;
}
EOF
g++ -fsanitize=address -I../src -Isrc harness.cpp src/libncnn.a -fopenmp -o ncnn_param
# Run PoC reproduction
./ncnn_param poc.param
Observe FPE (floating-point exception / integer divide-by-zero).
Root Cause Analysis
In src/layer/convolutiondepthwise.cpp:46:
group = pd.get(7, 1);
...
if (num_output % group != 0) // <-- FPE when group == 0
The param parser (ParamDict::load_param) treats 7=51,58 as an integer array because of the comma. When pd.get(7, 1) is called on an array-typed parameter, it returns the union member .i. However, .i is never updated when an array is stored (only Mat v is populated), and it remains 0 from the preceding clear(). Consequently group becomes 0, causing an integer division-by-zero (58 % 0).
The same pattern exists in src/layer/convolutiondepthwise1d.cpp:40.
more
This vulnerability was discovered via AFL++ fuzzing on the ncnn_param text parser entry point (load_param).
The Vulkan backend (convolutiondepthwise_vulkan.cpp:597) already has a group == 0 || num_output % group != 0 check, but the CPU backend (convolutiondepthwise.cpp) and 1D variant (convolutiondepthwise1d.cpp) are missing the group == 0 guard.
poc
poc.zip
error log
how to reproduce
Observe FPE (floating-point exception / integer divide-by-zero).
Root Cause Analysis
In
src/layer/convolutiondepthwise.cpp:46:The param parser (
ParamDict::load_param) treats7=51,58as an integer array because of the comma. Whenpd.get(7, 1)is called on an array-typed parameter, it returns the union member.i. However,.iis never updated when an array is stored (onlyMat vis populated), and it remains0from the precedingclear(). Consequentlygroupbecomes0, causing an integer division-by-zero (58 % 0).The same pattern exists in
src/layer/convolutiondepthwise1d.cpp:40.more
This vulnerability was discovered via AFL++ fuzzing on the
ncnn_paramtext parser entry point (load_param).The Vulkan backend (
convolutiondepthwise_vulkan.cpp:597) already has agroup == 0 || num_output % group != 0check, but the CPU backend (convolutiondepthwise.cpp) and 1D variant (convolutiondepthwise1d.cpp) are missing thegroup == 0guard.poc
poc.zip