s390x: keep the EXRL prefetch inside the code buffer - #89
Conversation
s390_irgen_EXRL reads its target straight out of the buffer being translated, at exrl_bytes + offset * 2, with nothing bounding the result. Nothing constrains the displacement field either, so a bogus or truncated EXRL points anywhere within 4GB of the buffer: lifting the seven bytes a75bffff c650ff as s390x is enough to kill the process. The field is also read as unsigned, unlike every other RIL-b handler, which turns a negative displacement into a read about 8GB ahead of the buffer and puts that address in the emitted lookup as well. Record the buffer base in disInstr_S390, sign-extend the displacement, and prefetch only when the whole six-byte target lies inside the buffer. Leaving last_execute_target at zero makes s390_irgen_EX emit the generic run-time lookup, which is what it already does when the target is unknown. The buffer is normally larger than the block being translated, so VexControl gains guest_bytes_size for the client to say how much of it may be read; without it only guest_max_bytes counts.
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Validation record for head
EXRL survey over the 67 s390x ELFs in angr/binaries
Other front ends are untouched by construction, and measured so: 27,918 lifts over X86, AMD64, ARMEL, AARCH64, MIPS32, MIPS64, PPC32, PPC64 and S390X from the same angr/binaries revision are byte-identical on baseline and head. Caveats: no s390x hardware was involved; this is translation evidence only. A target inside the code buffer but before |
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
s390_irgen_EXRLreads its target straight out of the buffer being translated, atexrl_bytes + offset * 2, with nothing bounding the result — and it reads the displacement as unsigned, unlike every other RIL-b handler. A bogus or truncated EXRL therefore reads far outside the buffer: lifting the seven bytesa75bffff c650ffas s390x is enough to segfault the process.Record the buffer base in
disInstr_S390, sign-extend the displacement, and prefetch only when the whole six-byte target lies inside the buffer. Otherwises390_irgen_EXemits the run-time lookup it already emits for an unknown target.VexControlgainsguest_bytes_sizeso a client whose buffer is larger than the block being translated can say how much of it may be read.Consumed by angr/pyvex#564, which carries the regression tests. Validation: #89 (comment)