diff options
author | Nick Clifton <nickc@redhat.com> | 2019-10-28 16:15:34 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2019-10-28 16:15:34 +0000 |
commit | bbf9a0b5eef3599a1c6a7a3bea40da9f2c37df83 (patch) | |
tree | 6b215c99843eb341366c52988e4933ef192f730e /opcodes | |
parent | Stop potential illegal memory access in the NS32K disassembler. (diff) | |
download | binutils-gdb-bbf9a0b5eef3599a1c6a7a3bea40da9f2c37df83.tar.gz binutils-gdb-bbf9a0b5eef3599a1c6a7a3bea40da9f2c37df83.tar.bz2 binutils-gdb-bbf9a0b5eef3599a1c6a7a3bea40da9f2c37df83.zip |
Fix buffer overrun in TIC30 disassembler.
* tic30-dis.c (OPERAND_BUFFER_LEN): Define. Use as length of
operand buffer. Set value to 15 not 13.
(get_register_operand): Use OPERAND_BUFFER_LEN.
(get_indirect_operand): Likewise.
(print_two_operand): Likewise.
(print_three_operand): Likewise.
(print_oar_insn): Likewise.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 10 | ||||
-rw-r--r-- | opcodes/tic30-dis.c | 24 |
2 files changed, 27 insertions, 7 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index fe0f2402d7c..8489b407882 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,5 +1,15 @@ 2019-10-28 Nick Clifton <nickc@redhat.com> + * tic30-dis.c (OPERAND_BUFFER_LEN): Define. Use as length of + operand buffer. Set value to 15 not 13. + (get_register_operand): Use OPERAND_BUFFER_LEN. + (get_indirect_operand): Likewise. + (print_two_operand): Likewise. + (print_three_operand): Likewise. + (print_oar_insn): Likewise. + +2019-10-28 Nick Clifton <nickc@redhat.com> + * ns32k-dis.c (bit_extract): Add sanitiy check of parameters. (bit_extract_simple): Likewise. (bit_copy): Likewise. diff --git a/opcodes/tic30-dis.c b/opcodes/tic30-dis.c index 668c519df87..a28be8307f8 100644 --- a/opcodes/tic30-dis.c +++ b/opcodes/tic30-dis.c @@ -188,6 +188,8 @@ get_tic30_instruction (unsigned long insn_word, struct instruction *insn) return 1; } +#define OPERAND_BUFFER_LEN 15 + static int get_register_operand (unsigned char fragment, char *buffer) { @@ -199,7 +201,8 @@ get_register_operand (unsigned char fragment, char *buffer) { if ((fragment & 0x1F) == current_reg->opcode) { - strcpy (buffer, current_reg->name); + strncpy (buffer, current_reg->name, OPERAND_BUFFER_LEN); + buffer[OPERAND_BUFFER_LEN - 1] = 0; return 1; } } @@ -250,18 +253,25 @@ get_indirect_operand (unsigned short fragment, int bufcnt; len = strlen (current_ind->syntax); + for (i = 0, bufcnt = 0; i < len; i++, bufcnt++) { buffer[bufcnt] = current_ind->syntax[i]; + if (bufcnt > 0 + && bufcnt < OPERAND_BUFFER_LEN - 1 && buffer[bufcnt - 1] == 'a' && buffer[bufcnt] == 'r') buffer[++bufcnt] = arnum + '0'; - if (buffer[bufcnt] == '(' + + if (bufcnt < OPERAND_BUFFER_LEN - 1 + && buffer[bufcnt] == '(' && current_ind->displacement == DISP_REQUIRED) { - sprintf (&buffer[bufcnt + 1], "%u", disp); - bufcnt += strlen (&buffer[bufcnt + 1]); + snprintf (buffer + (bufcnt + 1), + OPERAND_BUFFER_LEN - (bufcnt + 1), + "%u", disp); + bufcnt += strlen (buffer + (bufcnt + 1)); } } buffer[bufcnt + 1] = '\0'; @@ -342,7 +352,7 @@ print_two_operand (disassemble_info *info, struct instruction *insn) { char name[12]; - char operand[2][13] = + char operand[2][OPERAND_BUFFER_LEN] = { {0}, {0} @@ -429,7 +439,7 @@ print_three_operand (disassemble_info *info, unsigned long insn_word, struct instruction *insn) { - char operand[3][13] = + char operand[3][OPERAND_BUFFER_LEN] = { {0}, {0}, @@ -475,7 +485,7 @@ print_par_insn (disassemble_info *info, { size_t i, len; char *name1, *name2; - char operand[2][3][13] = + char operand[2][3][OPERAND_BUFFER_LEN] = { { {0}, |