Project: assimp (assimp/assimp), language: c++
Vulnerability instance: assimp.cve-2022-38528
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/assimp/assimp/issues/4662
## Description:
Issue: assimp/assimp#4662
Title: Bug: SEGV on unknown address still exists in Assimp::XFileImporter::CreateMeshes
State: open
Created by: 0xdd96
Created at: 2022-07-26 13:16:46+00:00
Labels: Bug, Security Risk

Issue Body:
# Describe the bug
SEGV on unknown address still exists in Assimp::XFileImporter::CreateMeshes. 

***This is similar to issue https://github.com/assimp/assimp/issues/1728. Note that #1728 reported wrong type of the vulnerability, as it is not a NULL pointer dereference. Patch https://github.com/assimp/assimp/commit/39ce3e1309b50681ea24b3109971582003fa83d5 was misguided by #1728, leaving this vulnerability unfixed.***


# To Reproduce
Steps to reproduce the behavior:
**version:** latest commit https://github.com/assimp/assimp/commit/3c253ca3e5be69dc0eb7e9120278cd0a74deb9ac
**poc:**[null_CreateMeshes.zip](https://github.com/assimp/assimp/files/9190065/null_CreateMeshes.zip)

```
git clone https://github.com/assimp/assimp.git
cd assimp
mkdir build
cd build
CFLAGS="-g -O0" CXXFLAGS="-g -O0" cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=OFF  -DASSIMP_BUILD_ASSIMP_TOOLS=ON  ..
./assimp info $POC
```

# Expected behavior
```
user@c3ae4d510abb:$ ./bin/assimp info poc
Launching asset import ...           OK
Validating postprocessing flags ...  OK
0 %
Segmentation fault (core dumped)
```

```
user@c3ae4d510abb:$ ./bin/assimp info poc
Launching asset import ...           OK
Validating postprocessing flags ...  OK
0 %
AddressSanitizer:DEADLYSIGNAL
=================================================================
==20088==ERROR: AddressSanitizer: SEGV on unknown address 0x6120000301c0 (pc 0x555556872ed9 bp 0x7fffffffb4d0 sp 0x7fffffffb100 T0)
==20088==The signal is caused by a READ memory access.
    #0 0x555556872ed8  (bin/assimp+0x131eed8)
    #1 0x55555687151a  (bin/assimp+0x131d51a)
    #2 0x5555568716a0  (bin/assimp+0x131d6a0)
    #3 0x555556870ba0  (bin/assimp+0x131cba0)
    #4 0x555556870829  (bin/assimp+0x131c829)
    #5 0x555555c56ab5  (bin/assimp+0x702ab5)
    #6 0x55555580ecf2  (bin/assimp+0x2bacf2)
    #7 0x5555557f89af  (bin/assimp+0x2a49af)
    #8 0x5555557f5f42  (bin/assimp+0x2a1f42)
    #9 0x555555801399  (bin/assimp+0x2ad399)
    #10 0x5555557f59c8  (bin/assimp+0x2a19c8)
    #11 0x7ffff7070082  (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
    #12 0x5555557cda7d  (bin/assimp+0x279a7d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (bin/assimp+0x131eed8)
==20088==ABORTING
Aborted
```
# Vulnerability analysis
Using gdb to trace this PoC, the vulnerability occurs in line 340 of XFileImporter.cpp, due to `idx=16256` is larger than the capacity of  `sourceMesh->mNormals` (24).


https://github.com/assimp/assimp/blob/3c253ca3e5be69dc0eb7e9120278cd0a74deb9ac/code/AssetLib/X/XFileImporter.cpp#L337-L342

After tracing it, I found that `pMesh->mNormals` assigned `numNormals` elements in line 514-519 of `XFileParser.cpp`, then line 535-536  saved the result of `ReadInt` to `pMesh->mNormFaces[a].mIndices` without checking if it is in the correct boundary (`<numNormals`). This eventually leads to the bug above.

https://github.com/assimp/assimp/blob/3c253ca3e5be69dc0eb7e9120278cd0a74deb9ac/code/AssetLib/X/XFileParser.cpp#L513-L541

# Suggested fix

Add a boundary check after `ReadInt` following the convention in line 410 below. Line 410 ensures the number read by `ReadInt` does not exceed the size of the vector.

https://github.com/assimp/assimp/blob/3c253ca3e5be69dc0eb7e9120278cd0a74deb9ac/code/AssetLib/X/XFileParser.cpp#L394-L415




Comments:
Comment by krop on 2022-09-07 06:59:23+00:00:
[CVE-2022-38528](https://nvd.nist.gov/vuln/detail/CVE-2022-38528) was published yesterday and references this bug report.

Attachments:
https://github.com/assimp/assimp/files/9190065/null_CreateMeshes.zip

Commit References:
39ce3e1309b50681ea24b3109971582003fa83d5
3c253ca3e5be69dc0eb7e9120278cd0a74deb9ac

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
cmake CMakeLists.txt -G "Ninja" -DBUILD_SHARED_LIBS=OFF -DASSIMP_BUILD_ZLIB=ON \
                                -DASSIMP_BUILD_TESTS=OFF -DASSIMP_BUILD_ASSIMP_TOOLS=OFF \
                                -DASSIMP_BUILD_SAMPLES=OFF
cmake --build .

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y cmake ninja-build
RUN git clone https://github.com/assimp/assimp assimp
RUN git -C assimp checkout 9519a62dd20799c5493c638d1ef5a6f484e5faf1
WORKDIR $SRC/assimp
COPY build.sh $SRC/

Additional files: