ARM:LE:32:v7 and v8 segfault translating a coprocessor STC word (v6 raises BadDataError)
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 48/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Área
- reverse-engineering
Línea de trabajo
Comience reproduciendo el fallo mediante pypcode.Context("ARM:LE:32:v7").translate con 746b69cd y, a continuación, compare las rutas de traducción de ARM v6, v7 y v8 en el decodificador respaldado por SLEIGH. Rastree por qué v7 y v8 terminan con SIGSEGV en lugar de generar BadDataError y verifique que el reproductor de errores finaliza con la excepción esperada sin bloquearse.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
ARM:LE:32:v7 and ARM:LE:32:v8 segfault translating a single 4-byte word.
ARM:LE:32:v6 rejects the same word cleanly with BadDataError, so the correct
failure mode already exists next door in the same processor family.
Reproducer
import pypcode
pypcode.Context("ARM:LE:32:v7").translate(bytes.fromhex("746b69cd"), 0x1000)
Four bytes, one call, no flags, no other state. Deterministic: 10/10 runs,
SIGSEGV (exit 139). Same for ARM:LE:32:v8.
Expected behaviour
A raised exception, not a crash. BadDataError is the right outcome here — the
word is not valid code for this language, and ARM:LE:32:v6 already returns
exactly that for the identical input:
BadDataError: r0x00001000: Unable to resolve constructor
The distinction matters to a caller, not just aesthetically. An exception is
catchable: a tool sweeping an image can skip the offending block and carry on.
SIGSEGV takes the process out with no opportunity to recover, no partial
results, and no indication of which address was responsible. So the ask is that
v7/v8 fail the way v6 does, whatever the underlying cause turns out to be.
Behaviour across the ARM variants
Each in its own child process, so the matrix survives:
import subprocess, sys, pypcode
WORD = "746b69cd" # little-endian 0xcd696b74
CHILD = "import pypcode,sys; pypcode.Context(sys.argv[1]).translate(bytes.fromhex(sys.argv[2]), 0x1000)"
print(f"pypcode {pypcode.__version__}")
for lang in ("ARM:LE:32:v5", "ARM:LE:32:v6", "ARM:LE:32:v7",
"ARM:LE:32:v8", "ARM:LE:32:Cortex", "ARM:BE:32:v7"):
rc = subprocess.run([sys.executable, "-c", CHILD, lang, WORD], capture_output=True).returncode
print(f" {lang:18} {'SIGSEGV' if rc in (-11, 139) else f'ok (rc={rc})'}")
| language | result |
|---|---|
ARM:LE:32:v5 |
ok — decodes as stclgt p11,cr6,[r9,#-0x1d0]! |
ARM:LE:32:v6 |
BadDataError: r0x00001000: Unable to resolve constructor |
ARM:LE:32:v7 |
SIGSEGV |
ARM:LE:32:v8 |
SIGSEGV |
ARM:LE:32:Cortex |
ok — decodes as Thumb (ldr / ldmia) |
ARM:BE:32:v7 |
ok — different word under the other byte order |
The word
0xcd696b74 decodes (per ARM:LE:32:v5) as:
stclgt p11, cr6, [r9, #-0x1d0]!
A coprocessor store, predicated GT, pre-indexed with writeback, targeting
p11 — the VFP double-precision coprocessor. Field breakdown:
cond=0xc(GT) op=0b110 P=1 U=0 D=1 W=1 L=0
Rn=r9 CRd=c6 coproc=p11 imm8=116 (byte offset 464)
The split lines up with VFP modelling: v5 has no VFP model and takes it as a
plain STCL; v6 refuses it; v7/v8 model VFP/NEON and die. That v6 raises
where v7 crashes is the part I would weight most — it suggests something in the
newer VFP/NEON decode path rather than a general gap in coprocessor handling.
Where the bytes came from
Not synthesised. The word occurs five times inside kallsyms_names — the
compressed kallsyms symbol-name table — in Debian's linux-image-2.6.37-2-versatile
(armel). The crashing decode is at 0xc02b6410, kallsyms_names + 0x8e70. That
build's System.map types kallsyms_names as T, so the table sits in the text
region, and a sweep of executable ranges decodes it as instructions.
To be exact about the artifact: Debian's regular (non-dbg) armel package ships a
compressed /boot/vmlinuz, not an ELF, so the bytes were read from the
decompressed kernel image out of that zImage — stock Debian content, in a
container rebuilt locally. The word does not appear in the armhf -dbg images I
also have (4.9.0-19-armmp, 4.18.0-3-armmp), so this is specific to that
build, and I would not want to overstate how common it is.
That is the practical impact: a consumer pointed at an arbitrary ARM binary
cannot know whether a given word is code before lifting it, and a segfault gives
no opportunity to skip the block. Refusing invalid input is fine — v6 already
does exactly that.
Environment
pypcode 4.0.0 (PyPI wheel, cp313-cp313-manylinux_2_27_x86_64)
python 3.13.7
platform Linux-5.10.16.3-microsoft-standard-WSL2-x86_64-with-glibc2.35
machine x86_64
Tested against the 4.0.0 release wheel, not against master — happy to
retest there or against a candidate fix if that is useful.
Related
Same class as #293 (segfaults on short inputs for JVM, NDS32, SPARC) and #292
(PowerPC vaddubm heap corruption), but a different language and not covered by
either, so filing separately. Unlike the three in #293, this word is not a
synthetic sequence — it occurs in a real distribution kernel.
- Lenguaje dominante
- C++
- Estrellas
- 222
- Forks
- 33
- Merge medio
- 7 h 13 min
- PR fusionados (30 d)
- 7
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de angr/pypcode
-
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 28/100
-
Update to Ghidra 12.1.2Quizá libre de nuevo @mborgerson la tomó hace 125 días y no hay ningún pull request abierto. Abiertoenhancement
-
Build with freethreadingAbiertoenhancement
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
Todos los issues de angr/pypcode
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 83/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
-
[BUG] Clipboard History: Buffer over-read in WideCharToMultiByte on double-click pastePosiblemente ocupada @softmgr la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
notepad-plus-plus/notepad-plus-plus#18519 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
justcallmekoko/ESP32Marauder#1635 ·
Los mantenedores suelen responder en 1 día
-
3.7.6-dev commit 80481ea - files not centered when resolution differs and zoom = "pixel-to-pixel"Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
grizzlypeak3d/DJV#931 ·