Skip to content

bug: FPE (divide-by-zero) in ConvolutionDepthWise::load_param (src/layer/convolutiondepthwise.cpp:46) #6911

Description

@beilzx

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions