-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Description
AngrDB fails to load a previously saved database due to a memory buffer overflow during the relocation process. The error occurs when perform_relocations=True
(default) is used during the loading phase, even though the original project was saved with perform_relocations=False
.
Steps to reproduce the bug
Script to reproduce:
import angr
from angr.angrdb import AngrDB
import os
# Use any ELF binary, particularly kernel modules
ko_file = "/path/to/your/binary.ko" # Replace with actual binary path
load_options = {
'auto_load_libs': False,
'main_opts': {
'base_addr': 0x0,
'backend': 'elf',
},
'perform_relocations': False, # Key: disable relocations during save
}
db_dir = '/tmp/angr_db/'
os.makedirs(db_dir, exist_ok=True)
db_path = os.path.join(db_dir, 'test.adb')
# Step 1: Create project with perform_relocations=False
proj = angr.Project(thing=ko_file, load_options=load_options)
proj.analyses.CFGFast(normalize=True)
# Step 2: Save to AngrDB
angrdb = AngrDB(project=proj)
angrdb.dump(db_path, kbs=[proj.kb])
# Step 3: Attempt to load (this fails)
db = AngrDB()
proj = db.load(db_path) # KeyError: 1105312
Binary used: The issue occurs with aarch64 kernel modules (.ko
files), but likely affects other ELF binaries as well.
Environment
angr environment report
angr environment report
=============================
Date: 2025-08-21 11:17:10.714541
Running in virtual environment at .venv
Platform: linux-x86_64
Python version: 3.13.5 (main, Jun 26 2025, 21:20:04) [Clang 20.1.4 ]
######## angr #########
Python found it in .venv/lib/python3.13/site-packages/angr/__init__.py
Pip version 9.2.170
Error Log:
Creating project took 30.720 seconds
Saving angrdb took 7.215 seconds
Traceback (most recent call last):
File ".venv/lib/python3.13/site-packages/cle/memory.py", line 126, in pack
return struct.pack_into(fmt, backer, addr - start, *data)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct.error: pack_into requires a buffer of at least 820 bytes for packing 8 bytes at offset 812 (actual buffer size is 816)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".venv/lib/python3.13/site-packages/angr/angrdb/db.py", line 42, in open_db
yield Session
File ".venv/lib/python3.13/site-packages/angr/angrdb/db.py", line 184, in load
loader = LoaderSerializer.load(session)
File ".venv/lib/python3.13/site-packages/angr/angrdb/serializers/loader.py", line 157, in load
loader = cle.Loader(BytesIO(main_object.content), main_opts=load_args[main_object])
File ".venv/lib/python3.13/site-packages/cle/loader.py", line 185, in __init__
self.initial_load_objects = self._internal_load(
~~~~~~~~~~~~~~~~~~~^
main_binary, *preload_libs, *force_load_libs, preloading=(main_binary, *preload_libs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File ".venv/lib/python3.13/site-packages/cle/loader.py", line 940, in _internal_load
obj.relocate()
~~~~~~~~~~~~^^
File ".venv/lib/python3.13/site-packages/cle/backends/backend.py", line 388, in relocate
reloc.relocate()
~~~~~~~~~~~~~~^^
File ".venv/lib/python3.13/site-packages/cle/backends/relocation.py", line 137, in relocate
self.owner.memory.pack_word(self.dest_addr, self.value)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.13/site-packages/cle/memory.py", line 145, in pack_word
return self.pack(addr, self._arch.struct_fmt(size=size, signed=signed, endness=endness), data)
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.13/site-packages/cle/memory.py", line 130, in pack
raise KeyError(addr) # pylint: disable=raise-missing-from
^^^^^^^^^^^^^^^^^^^^
KeyError: 1105312
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "tests/test_angr_db.py", line 50, in <module>
proj = db.load(db_path)
File ".venv/lib/python3.13/site-packages/angr/angrdb/db.py", line 175, in load
with self.open_db(db_str) as Session, self.session_scope(Session) as session:
~~~~~~~~~~~~^^^^^^^^
File "/usr/lib/python3.13/contextlib.py", line 162, in __exit__
self.gen.throw(value)
~~~~~~~~~~~~~~^^^^^^^
File ".venv/lib/python3.13/site-packages/angr/angrdb/db.py", line 46, in open_db
raise AngrDBError from ex
angr.errors.AngrDBError
Additional context
Root Cause Analysis:
The issue stems from inconsistency between save and load behavior:
-
During Save: Project created with
perform_relocations=False
, so relocations are not performed and memory layout is preserved as-is. -
During Load:
cle.Loader
constructor defaults toperform_relocations=True
(seecle/loader.py:77
), attempting to perform relocations on binary data that was saved without relocations.
Call Chain:
db.load()
→ LoaderSerializer.load(session)
→ cle.Loader(BytesIO(main_object.content), main_opts=load_args[main_object])
→ obj.relocate()
Technical Details:
The LoaderSerializer.load()
method at angr/angrdb/serializers/loader.py:157
doesn't preserve the original perform_relocations
setting:
loader = cle.Loader(BytesIO(main_object.content), main_opts=load_args[main_object])
The main_opts
doesn't include the original perform_relocations=False
setting, causing the loader to default to perform_relocations=True
and attempt relocations on data that wasn't designed for it.
Impact:
This prevents using AngrDB for projects requiring perform_relocations=False
, which is common for:
- Kernel modules analysis
- Embedded binaries
- Cases requiring precise memory layout preservation
Suggested Fix:
The AngrDB serialization should preserve and restore the original loader options, particularly the perform_relocations
setting. This could be implemented by:
- Storing the complete loader configuration in the database
- Restoring all original loader options during deserialization
- Adding explicit handling for the
perform_relocations
parameter inLoaderSerializer