The sdas8051
8051 assembler is in the Small Device C Compiler
suite for targeting 8051 and derivatives. A relocation buffer overflow
occurred while assembling ACALL instructions.
SDCC version:
$ sdcc -v SDCC : mcs51 TD- 4.5.2 #15323 (Linux)
This is the code to be assembled:
FP_BASE .equ 0x1993 .area BOOT (ABS) .org 0x194c GET_NUM:ACALL FP_BASE+10 JNC FP_BASE+12 ACALL FP_BASE+18
Run the 8051 assembler:
sdas8051 -los j11.s
The relocatable output j11.rel
is corrupted on the line T FF 19 4C:
XH3 H 3 areas 1 global symbols S .__.ABS. Def000000 A _CODE size 0 flags 0 addr 0 A BOOT size 0 flags 8 addr 0 A BOOT0 size 6 flags 8 addr 194C T 00 19 4C R 00 00 00 02 T FF 19 4C 19 9D 11 50 00 19 9F 19 A5 11 R 00 00 00 02 08 03 FF FF F1 07 07 00 00 08 0A FF FF
Apart from the anomalous address 0xff194c, which should be 0x00194c, the last
R relocation line is more than 16 bytes long.
gdb
reveals buffer overflow from the 16 bytes rel
(R) buffer into the
txt
T buffer, as sdas8051
appends the relocation information for ACALL to 0x19a5:
(gdb) s out_rw (v=65535) at ../asxxsrc/asout.c:1568 1568 return ((int) ((v>>8)&0377)); (gdb) s 1489 *relp++ = lobyte(v); (gdb) p relp $3 = 0x4181d0 <txt> "" (gdb)
There is a buffer check for txt
and rel
in outchk()
,
so the bounds check could be wrong. Here is the patch for the fixed bounds check:
Index: sdas/asxxsrc/asout.c =================================================================== --- sdas/asxxsrc/asout.c (revision 15324) +++ sdas/asxxsrc/asout.c (working copy) @@ -1674,7 +1674,7 @@ */ out_lw(esp->e_addr,0); if (oflag) { - outchk(3, 0); + outchk(3, 5); out_txb(2, esp->e_addr); *txtp++ = v;
After recompiling sdas8051
, here is the rel
file:
XH3 H 3 areas 1 global symbols S .__.ABS. Def000000 A _CODE size 0 flags 0 addr 0 A BOOT size 0 flags 8 addr 0 A BOOT0 size 6 flags 8 addr 194C T 00 19 4C R 00 00 00 02 T 00 19 4C 19 9D 11 50 00 19 9F R 00 00 00 02 08 03 FF FF F1 07 07 00 00 T 00 19 50 19 A5 11 R 00 00 00 02 08 03 FF FF
The address is now a normal 0x00194c on the line starting with T 00 19 4C, and the relocation record is kept to a maximum of 16 bytes.