CVE-2022-44451: Open Babel MSI Parser Uninitialized Pointer Dereference
Open Babel's MSI chemistry file parser uses an atom pointer before it is ever assigned, letting an attacker trigger arbitrary code execution by feeding it a crafted MSI file.
The problem
In MSIFormat::ReadMolecule (src/formats/msiformat.cpp), the local variable OBAtom *atom is declared but never initialized to nullptr.
When the parser encounters an XYZ coordinate record before a valid Atom block has completed (so mol.NewAtom() was never called), it still executes atom->SetVector(x, y, z) with a garbage stack pointer. Any application or service that parses untrusted MSI files is affected, including the obabel CLI, the OBConversion C++ API, and all language bindings (Python, Ruby, Java, R, Perl, C#, PHP).
Proof of concept
A working proof-of-concept for CVE-2022-44451 in openbabel, with the exact payload below.
# MSI CERIUS2 DataModel File Version 3 3
(
(1 Model
(A I CG 0)
(A D XYZ ( 1.0 2.0 3.0 ))
)
)
The vulnerability is CWE-824 (Access of Uninitialized Pointer). OBAtom *atom is stack-allocated without a = nullptr initializer. The parser enters the coordinate-handling branch at msiformat.cpp:193 and calls atom->SetVector(x, y, z) while atom still holds whatever happened to be on the stack.
Because _c and _cidx (internal OBAtom members) are read as offsets from that uninitialized pointer and the x/y/z values are attacker-supplied, SetVector becomes an arbitrary read/write primitive. Depending on stack layout and compiler optimization, this can escalate to full code execution.
The payload works by placing an XYZ property record in the top-level Model object before any Atom sub-record is opened, so the atomRecord flag is never set and mol.NewAtom() is never called, leaving atom uninitialized when the coordinate branch fires.
The patch (commit fa9a2d9a) initializes atom = nullptr at declaration and wraps the SetVector call in a null check, so malformed files that skip the Atom section return an error instead of dereferencing garbage.
The fix
Upgrade openbabel to version 3.2.0 or later. The fix is in commit fa9a2d9a2eb75154b7a884dfe679ff41a8f9c547, which initializes OBAtom *atom = nullptr and guards downstream dereferences. A minimized regression test (test/files/fuzz_regress/) is exercised under ASAN+UBSAN on every CI build.
Reported by Claudio Bozzato, Cisco Talos.
Related research
- high · 7.8CVE-2022-42885CVE-2022-42885: Open Babel GRO Parser Uninitialized Pointer Dereference
- high · 7.8CVE-2022-46292CVE-2022-46292: Open Babel MOPAC Output Parser Out-of-Bounds Write (UNIT CELL TRANSLATION)
- high · 7.8CVE-2022-43467CVE-2022-43467: Open Babel PQS Parser Out-of-Bounds Write
- high · 7.8CVE-2022-43607CVE-2022-43607: Open Babel MOL2 Parser Stack Buffer Overflow