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