high · 7.8CVE-2022-42885Jul 1, 2026

CVE-2022-42885: Open Babel GRO Parser Uninitialized Pointer Dereference

Rohit Hatagale
AI Security Researcher, SecureLayer7

A crafted GROMACS .gro file can make Open Babel dereference an uninitialized residue pointer while parsing atom records, crashing the process and potentially enabling arbitrary code execution.

Packageopenbabel
Ecosystempip
Affected< 3.2.0
Fixed in3.2.0

The problem

Open Babel's GRO format reader in `src/formats/groformat.cpp` declared a local `OBResidue* res` pointer but never initialized it before the atom-parsing loop. When a new residue number was encountered in the atom records, the code path that should have called `mol->NewResidue()` could be skipped under malformed input, leaving `res` pointing at garbage stack memory.

The first call to `res->AddAtom(atom)` at line 278 then dereferenced that garbage pointer, crashing inside `OBResidue::AddAtom` and, depending on stack layout, giving an attacker influence over the instruction pointer. Any application that passes untrusted files to `obabel`, `OBConversion`, or any language binding (Python, Ruby, Java, R, Perl, C#, PHP) is affected.

Proof of concept

A working proof-of-concept for CVE-2022-42885 in openbabel, with the exact payload below.

bash
Minimized malformed GRO file (save as res.uninit.gro, then run):

$ obabel -i gro res.uninit.gro -o sdf

--- res.uninit.gro ---
Malformed GRO trigger
1
    1CRASH    CA    1   0.000   0.000   0.000
   0.00000   0.00000   0.00000

The atom count header says 1 atom, but the residue-change logic is entered with `res` still uninitialized, causing AddressSanitizer to report:

AddressSanitizer: SEGV on unknown address 0x00000078
  #0 OBResidue::AddAtom(OBAtom*)  residue.cpp:891
  #1 GROFormat::ReadMolecule(...)  groformat.cpp:278

The root cause is CWE-824: the local variable `OBResidue* res` was declared but never set to `nullptr`, so it held whatever value was on the stack at that point. The parser only assigned `res` inside a conditional branch that compared the current residue ID to the previous one; a crafted input that bypasses that branch reaches `res->AddAtom(atom)` with a wild pointer.

The Talos crash trace confirms the fault inside `std::vector::push_back` called from `OBResidue::AddAtom` via `groformat.cpp:278`, with ASAN reporting a read of address `0x00000078` (a small offset from a near-zero or stack-garbage base). Because `res` lives on the stack and the attacker controls the file content that shapes stack layout, the pointer value can be influenced toward code execution.

The fix (commit fa9a2d9a) initializes `res = nullptr` at declaration and adds a null check before any method call on it, ensuring a malformed record is rejected rather than dereferenced.

The fix

Upgrade to Open Babel 3.2.0, which includes the fix in commit fa9a2d9a. The patch initializes `OBResidue* res = nullptr` and guards every subsequent use with a null check. No workaround exists for older versions; avoid passing untrusted .gro files to any Open Babel interface until the upgrade is applied.

Reported by Cisco Talos.

References: [1][2][3][4][5][6]

Related research