ITADN
liuliu/ccv/Issues

Out-of-bounds read in ccv_move when creating an offset view with non-zero x/y

#269Openhgarrereyn 创建于 2025-09-29
H
hgarrereyncommented
Hi, it seems like there is a trivial buffer overflow (read) in `ccv_move`. As far as I can tell, this overflow happens in most uses with nonzero `x` and `y` values for the offsets. It looks like `ccv_move` is not used anywhere else, so perhaps this API is just incomplete. (found via automated fuzzing) See the following testcase: **testcase.cpp** ```cpp #include <cstdlib> extern "C" { #include "/fuzz/install/include/ccv.h" } int main() { // 2x2, 3 channels (8U C3) ccv_dense_matrix_t* a = ccv_dense_matrix_new(2, 2, CCV_8U | CCV_C3, 0, 0); if (!a) return 0; ccv_matrix_t* b = 0; // Non-zero x offset triggers OOB read inside ccv_move ccv_move((ccv_matrix_t*)a, &b, 0, /*y=*/0, /*x=*/1); // Clean up (not reached if it crashes under ASan) if (b) ccv_matrix_free(b); ccv_matrix_free((ccv_matrix_t*)a); return 0; } ``` **crash report** ```json { "Date": "2025-09-29T02:13:53.522821+00:00", "Uname": "Linux e98b1e44d7b2 5.15.0-156-generic #166-Ubuntu SMP Sat Aug 9 00:02:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux", "OS": "Ubuntu", "OSRelease": "22.04", "Architecture": "amd64", "ExecutablePath": "/tmp/tmpnviyeqc0/reproducer", "ProcEnviron": [ "LIBAFL_EDGES_MAP_SIZE=800000", "PWD=/fuzz/workspace", "CXX=gf_libafl_cxx", "GRAPHFUZZ_USE_ASAN=1", "HOME=/root", "ASAN_OPTIONS=hard_rss_limit_mb=1024:detect_leaks=0", "TERM=xterm-256color", "SHLVL=1", "LD_LIBRARY_PATH=/fuzz/install/lib", "PATH=/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "CC=gf_libafl_cc", "DEBIAN_FRONTEND=noninteractive", "OLDPWD=/fuzz/src/lib", "_=/usr/local/bin/agfi" ], "ProcCmdline": "/tmp/tmpnviyeqc0/reproducer", "Stdin": "", "ProcStatus": [], "ProcMaps": [], "ProcFiles": [], "NetworkConnections": [], "CrashSeverity": { "Type": "NOT_EXPLOITABLE", "ShortDescription": "heap-buffer-overflow(read)", "Description": "Heap buffer overflow", "Explanation": "The target reads data past the end, or before the beginning, of the intended heap buffer." }, "Stacktrace": [ " #0 0x555555695ad5 in ccv_move /fuzz/src/lib/ccv_util.c:1356:3", " #1 0x55555565c4e8 in main /tmp/tmpnviyeqc0/reproducer.cpp:11:3", " #2 0x7ffff5619d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16", " #3 0x7ffff5619e3f in __libc_start_main csu/../csu/libc-start.c:392:3", " #4 0x5555555812f4 in _start (/tmp/tmpnviyeqc0/reproducer+0x2d2f4) (BuildId: dc06ba8ce9aca5b9eaea2d972e7769f1a52f3776)" ], "Registers": {}, "Disassembly": [], "Package": "", "PackageVersion": "", "PackageArchitecture": "", "PackageDescription": "", "AsanReport": [ "==219==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50d0000000d0 at pc 0x555555695ad6 bp 0x7fffffffe970 sp 0x7fffffffe968", "READ of size 1 at 0x50d0000000d0 thread T0", " #0 0x555555695ad5 in ccv_move /fuzz/src/lib/ccv_util.c:1356:3", " #1 0x55555565c4e8 in main /tmp/tmpnviyeqc0/reproducer.cpp:11:3", " #2 0x7ffff5619d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16", " #3 0x7ffff5619e3f in __libc_start_main csu/../csu/libc-start.c:392:3", " #4 0x5555555812f4 in _start (/tmp/tmpnviyeqc0/reproducer+0x2d2f4) (BuildId: dc06ba8ce9aca5b9eaea2d972e7769f1a52f3776)", "", "0x50d0000000d0 is located 0 bytes after 144-byte region [0x50d000000040,0x50d0000000d0)", "allocated by thread T0 here:", " #0 0x55555561d69e in malloc (/tmp/tmpnviyeqc0/reproducer+0xc969e) (BuildId: dc06ba8ce9aca5b9eaea2d972e7769f1a52f3776)", " #1 0x55555565c925 in ccv_dense_matrix_new /fuzz/src/lib/ccv_memory.c:38:45", " #2 0x55555565c499 in main /tmp/tmpnviyeqc0/reproducer.cpp:7:27", " #3 0x7ffff5619d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16", "", "SUMMARY: AddressSanitizer: heap-buffer-overflow /fuzz/src/lib/ccv_util.c:1356:3 in ccv_move", "Shadow bytes around the buggy address:", " 0x50cffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", " 0x50cffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", " 0x50cfffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", " 0x50cfffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", " 0x50d000000000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00", "=>0x50d000000080: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa", " 0x50d000000100: fa fa 00 00 00 00 00 00 00 00 00 00 00 00 00 00", " 0x50d000000180: 00 00 00 00 fa fa fa fa fa fa fa fa fa fa fa fa", " 0x50d000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa", " 0x50d000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa", " 0x50d000000300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa", "Shadow byte legend (one shadow byte represents 8 application bytes):", " Addressable: 00", " Partially addressable: 01 02 03 04 05 06 07", " Heap left redzone: fa", " Freed heap region: fd", " Stack left redzone: f1", " Stack mid redzone: f2", " Stack right redzone: f3", " Stack after return: f5", " Stack use after scope: f8", " Global redzone: f9", " Global init order: f6", " Poisoned by user: f7", " Container overflow: fc", " Array cookie: ac", " Intra object redzone: bb", " ASan internal: fe", " Left alloca redzone: ca", " Right alloca redzone: cb", "==219==ABORTING" ], "MsanReport": [], "UbsanReport": [], "LuaReport": [], "PythonReport": [], "GoReport": [], "JavaReport": [], "RustReport": [], "JsReport": [], "CSharpReport": [], "CrashLine": "/fuzz/src/lib/ccv_util.c:1356:3", "Source": [ " 1352 \t\t\t} \\", " 1353 \t\t\ta_ptr += da->step; \\", " 1354 \t\t\tb_ptr += db->step; \\", " 1355 \t\t}", "--->1356 \t\tccv_matrix_setter(db->type, ccv_matrix_getter, da->type, for_block);", " 1357 #undef for_block", " 1358 \t} else if (type & CCV_MATRIX_SPARSE) {", " 1359 \t}", " 1360 }", " 1361 " ] } ```
0 条评论