From 8326546ebb46bba75a01e441960f408dd7ccdf2c Mon Sep 17 00:00:00 2001 From: Sergey Belyashov Date: Tue, 3 Mar 2020 13:09:19 +0000 Subject: [PATCH] Fix a potential illegal memory access in the Z80 assembler. PR 25604 * config/tc-z80.c (contains_register): Prevent an illegal memory access when checking an expression for a register name. --- gas/ChangeLog | 6 ++++++ gas/config/tc-z80.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 932acdcae51..00c56238cd7 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2020-03-03 Sergey Belyashov + + PR 25604 + * config/tc-z80.c (contains_register): Prevent an illegal memory + access when checking an expression for a register name. + 2020-03-03 Alan Modra * config/obj-coff.h: Remove vestiges of coff-m68k and pe-mips diff --git a/gas/config/tc-z80.c b/gas/config/tc-z80.c index 8f92d9f3062..312a0fc034d 100644 --- a/gas/config/tc-z80.c +++ b/gas/config/tc-z80.c @@ -825,19 +825,35 @@ is_indir (const char *s) } /* Check whether a symbol involves a register. */ -static int +static bfd_boolean contains_register (symbolS *sym) { if (sym) { - expressionS * ex = symbol_get_value_expression(sym); + expressionS * ex = symbol_get_value_expression (sym); + + switch (ex->X_op) + { + case O_register: + return TRUE; + + case O_add: + case O_subtract: + if (ex->X_op_symbol && contains_register (ex->X_op_symbol)) + return TRUE; + /* Fall through. */ + case O_uminus: + case O_symbol: + if (ex->X_add_symbol && contains_register (ex->X_add_symbol)) + return TRUE; + break; - return (O_register == ex->X_op) - || (ex->X_add_symbol && contains_register(ex->X_add_symbol)) - || (ex->X_op_symbol && contains_register(ex->X_op_symbol)); + default: + break; + } } - return 0; + return FALSE; } /* Parse general expression, not looking for indexed addressing. */ @@ -1168,7 +1184,7 @@ emit_byte (expressionS * val, bfd_reloc_code_real_type r_type) } p = frag_more (1); *p = val->X_add_number; - if ( contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol) ) + if (contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol)) { ill_op (); } @@ -1188,7 +1204,7 @@ emit_byte (expressionS * val, bfd_reloc_code_real_type r_type) } else { - /* For symbols only, constants are stored at begin of function */ + /* For symbols only, constants are stored at begin of function. */ fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val, (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type); } -- 2.30.2