google / google/draco

[BUG] A stack-buffer-overflow in `draco::RAnsBitDecoder::RAnsBitDecoder()` at `rans_bit_decoder.cc:23:36`

Open
#1,102 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
C++
Stars
7.5k
Forks
1.1k
Avg merge
47m
Merged PRs (30d)
1

Description

## Description

- Version: Latest commit [4e12ab2](https://github.com/google/draco/commit/4e12ab27d0fe690cf98e96dc33c2bd52e1485163)
- Environment:Ubuntu 20.04.6 LTS, Clang 18.1.8

## Steps to reproduce

```bash
export CC="clang"
export CXX="clang++"
export CFLAGS="-fsanitize=address -g -O0 -fno-omit-frame-pointer"
export CXXFLAGS="-fsanitize=address -g -O0 -fno-omit-frame-pointer -stdlib=libc++"
export LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
export SRC=$PWD
export WORK=$SRC/build
mkdir -p $WORK
git clone https://github.com/google/draco
cd draco && git checkout 4e12ab2
cd $WORK
cmake ../draco
make -j$(nproc)

for fuzzer in $(find $SRC/draco/src/draco/tools/fuzz -name '*.cc'); do
fuzzer_basename=$(basename -s .cc $fuzzer)
$CXX $CXXFLAGS \
-I $SRC/ \
-I $SRC/draco/src \
-I $WORK/ \
$LIB_FUZZING_ENGINE \
$fuzzer \
$WORK/libdraco.a \
-o $WORK/$fuzzer_basename
done

wget https://github.com/user-attachments/files/19824948/draco_crash_2.txt -O draco_crash_2.in
$WORK/draco_pc_decoder_without_dequantization_fuzzer draco_crash_2.in
```

## Sanitizer output

```
==31==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe463befe0 at pc 0x000000bc5cec bp 0x7ffe463be620 sp 0x7ffe463bdde8
WRITE of size 17 at 0x7ffe463befe0 thread T0
#0 0xbc5ceb in __asan_memset (/out/draco_pc_decoder_without_dequantization_fuzzer.fuzz+0xbc5ceb)
#1 0x80262c in draco::RAnsBitDecoder::RAnsBitDecoder() /src/draco/src/draco/compression/bit_coders/rans_bit_decoder.cc:23:36
#2 0x80262c in std::__1::array::array() /usr/lib/llvm-12/bin/../include/c++/v1/array:132:29
#3 0x7dd513 in draco::FoldedBit32Decoder::FoldedBit32Decoder() /src/draco/src/draco/compression/bit_coders/folded_integer_bit_decoder.h:29:3
#4 0x7dd513 in draco::DynamicIntegerPointsKdTreeDecoder<5>::DynamicIntegerPointsKdTreeDecoder(unsigned int) /src/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h:85:12

Address 0x7ffe463befe0 is located in stack of thread T0 at offset 1056 in frame
#0 0x796eff in draco::KdTreeAttributesDecoder::DecodePortableAttributes(draco::DecoderBuffer*) /src/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc:135

This frame has 12 object(s):
[32, 1056) 'decoder.i408' (line 265) <== Memory access at offset 1056 overflows this variable
[1184, 1440) 'decoder.i397' (line 265)
[1504, 1760) 'decoder.i386' (line 265)
[1824, 2096) 'decoder.i375' (line 265)
[2160, 2432) 'decoder.i341' (line 265)
[2496, 3520) 'decoder.i328' (line 265)
[3648, 4672) 'decoder.i' (line 265)
[4800, 4824) 'atts' (line 154)
[4864, 4868) 'ref.tmp' (line 174)
[4880, 4944) 'va' (line 181)
[4976, 4984) 'port_att' (line 184)
[5008, 5072) 'out_it' (line 202)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/out/draco_pc_decoder_without_dequantization_fuzzer.fuzz+0xbc5ceb) in __asan_memset
Shadow bytes around the buggy address:
0x100048c6fda0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100048c6fdb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100048c6fdc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100048c6fdd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100048c6fde0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100048c6fdf0: 00 00 00 00 00 00 00 00 00 00 00 00[f2]f2 f2 f2
0x100048c6fe00: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f8 f8 f8 f8
0x100048c6fe10: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
0x100048c6fe20: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2
0x100048c6fe30: f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
0x100048c6fe40: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
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
Shadow gap: cc
==31==ABORTING

```

## POC

[draco_crash_2.txt](https://github.com/user-attachments/files/19824948/draco_crash_2.txt)

## Credit

Reported by Yifan Zhang, [PLL](https://pl.cs.pku.edu.cn/en/)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.