This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Don't segfault disassembling bad rex prefixes
- From: Daniel Jacobowitz <drow at false dot org>
- To: binutils at sourceware dot org
- Date: Tue, 1 Nov 2005 11:05:09 -0500
- Subject: Don't segfault disassembling bad rex prefixes
A customer noticed that objdump -D on x86_64 tended to crash on bad data.
I have a few more testcases to try, but this appears to be the main culprit:
ckprefix ignores rex followed by any other prefix, including rex. But it
also prints out the prefix. So if you have a long run of rex prefixes in a
row, you'll run out the end of obuf.
This isn't an elegant fix, but I didn't feel like bending over backwards to
use dynamic allocation just to handle an obviously invalid instruction. The
disassembly is still pretty clear about what's going on:
ffffffff80800ec8: 40 rex
ffffffff80800ec9: 40 rex
ffffffff80800eca: 40 rex
ffffffff80800ecb: 40 rex
ffffffff80800ecc: 40 rex
ffffffff80800ecd: 40 rex
ffffffff80800ece: 40 rex
ffffffff80800ecf: 40 rex
ffffffff80800ed0: 40 rex
ffffffff80800ed1: 40 rex
ffffffff80800ed2: 40 rex
ffffffff80800ed3: 40 rex
ffffffff80800ed4: 41 rexZ
ffffffff80800ed5: 41 rexZ
ffffffff80800ed6: 42 rexY
ffffffff80800ed7: 42 rexY
ffffffff80800ed8: 42 rexY
ffffffff80800ed9: 43 rexYZ
ffffffff80800eda: 43 rexYZ
ffffffff80800edb: 43 rexYZ
ffffffff80800edc: 43 43 43 43 43 43 43 rexXY rexYZ cmp %r15d,%ds:(%rax)
ffffffff80800ee3: 43 43 43 42 43 43 43
ffffffff80800eea: 43 44 44 44 41 45 45
ffffffff80800ef1: 3e 46 39 38
OK?
--
Daniel Jacobowitz
CodeSourcery, LLC
2005-11-01 Daniel Jacobowitz <dan@codesourcery.com>
* i386-dis.c (ckprefix): Only print rex once.
Index: opcodes/i386-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/i386-dis.c,v
retrieving revision 1.68
diff -u -p -r1.68 i386-dis.c
--- opcodes/i386-dis.c 28 Sep 2005 15:34:53 -0000 1.68
+++ opcodes/i386-dis.c 1 Nov 2005 16:00:26 -0000
@@ -1745,6 +1745,8 @@ static void
ckprefix (void)
{
int newrex;
+ int printed_rex = 0;
+
rex = 0;
prefixes = 0;
used_prefixes = 0;
@@ -1825,11 +1827,14 @@ ckprefix (void)
default:
return;
}
- /* Rex is ignored when followed by another prefix. */
- if (rex)
+ /* Rex is ignored when followed by another prefix. Print it anyway,
+ but only do this once per instruction (for the benefit of the
+ fixed-size output buffer). */
+ if (rex && !printed_rex)
{
oappend (prefix_name (rex, 0));
oappend (" ");
+ printed_rex = 1;
}
rex = newrex;
codep++;