gdb/gdbserver/

Fix overlapping memcpy.
	* mem-break.c (set_raw_breakpoint_at): New variable buf.  Use it for
	the read_inferior_memory transfer.
	(delete_fast_tracepoint_jump): New variable buf.  Use it for the
	write_inferior_memory transfer.
	(set_fast_tracepoint_jump): New variable buf.  Use it for the
	read_inferior_memory and write_inferior_memory transfers.
	(uninsert_fast_tracepoint_jumps_at, reinsert_fast_tracepoint_jumps_at)
	(delete_raw_breakpoint, uninsert_raw_breakpoint): New variable buf.
	Use it for the write_inferior_memory transfer.
	(check_mem_read, check_mem_write): New gdb_asserts for overlapping
	buffers.
This commit is contained in:
Jan Kratochvil 2011-12-06 23:29:47 +00:00
parent 91912e4d08
commit 6bf36717da
2 changed files with 56 additions and 17 deletions

View File

@ -1,3 +1,18 @@
2011-12-06 Jan Kratochvil <jan.kratochvil@redhat.com>
Fix overlapping memcpy.
* mem-break.c (set_raw_breakpoint_at): New variable buf. Use it for
the read_inferior_memory transfer.
(delete_fast_tracepoint_jump): New variable buf. Use it for the
write_inferior_memory transfer.
(set_fast_tracepoint_jump): New variable buf. Use it for the
read_inferior_memory and write_inferior_memory transfers.
(uninsert_fast_tracepoint_jumps_at, reinsert_fast_tracepoint_jumps_at)
(delete_raw_breakpoint, uninsert_raw_breakpoint): New variable buf.
Use it for the write_inferior_memory transfer.
(check_mem_read, check_mem_write): New gdb_asserts for overlapping
buffers.
2011-12-06 Maciej W. Rozycki <macro@codesourcery.com> 2011-12-06 Maciej W. Rozycki <macro@codesourcery.com>
* linux-low.c (fetch_register, store_register): Make code * linux-low.c (fetch_register, store_register): Make code

View File

@ -122,6 +122,7 @@ set_raw_breakpoint_at (CORE_ADDR where)
struct process_info *proc = current_process (); struct process_info *proc = current_process ();
struct raw_breakpoint *bp; struct raw_breakpoint *bp;
int err; int err;
unsigned char buf[MAX_BREAKPOINT_LEN];
if (breakpoint_data == NULL) if (breakpoint_data == NULL)
error ("Target does not support breakpoints."); error ("Target does not support breakpoints.");
@ -140,7 +141,7 @@ set_raw_breakpoint_at (CORE_ADDR where)
/* Note that there can be fast tracepoint jumps installed in the /* Note that there can be fast tracepoint jumps installed in the
same memory range, so to get at the original memory, we need to same memory range, so to get at the original memory, we need to
use read_inferior_memory, which masks those out. */ use read_inferior_memory, which masks those out. */
err = read_inferior_memory (where, bp->old_data, breakpoint_len); err = read_inferior_memory (where, buf, breakpoint_len);
if (err != 0) if (err != 0)
{ {
if (debug_threads) if (debug_threads)
@ -151,6 +152,7 @@ set_raw_breakpoint_at (CORE_ADDR where)
free (bp); free (bp);
return NULL; return NULL;
} }
memcpy (bp->old_data, buf, breakpoint_len);
err = (*the_target->write_memory) (where, breakpoint_data, err = (*the_target->write_memory) (where, breakpoint_data,
breakpoint_len); breakpoint_len);
@ -257,6 +259,7 @@ delete_fast_tracepoint_jump (struct fast_tracepoint_jump *todel)
if (--bp->refcount == 0) if (--bp->refcount == 0)
{ {
struct fast_tracepoint_jump *prev_bp_link = *bp_link; struct fast_tracepoint_jump *prev_bp_link = *bp_link;
unsigned char *buf;
/* Unlink it. */ /* Unlink it. */
*bp_link = bp->next; *bp_link = bp->next;
@ -270,9 +273,9 @@ delete_fast_tracepoint_jump (struct fast_tracepoint_jump *todel)
pass the current shadow contents, because pass the current shadow contents, because
write_inferior_memory updates any shadow memory with write_inferior_memory updates any shadow memory with
what we pass here, and we want that to be a nop. */ what we pass here, and we want that to be a nop. */
ret = write_inferior_memory (bp->pc, buf = alloca (bp->length);
fast_tracepoint_jump_shadow (bp), memcpy (buf, fast_tracepoint_jump_shadow (bp), bp->length);
bp->length); ret = write_inferior_memory (bp->pc, buf, bp->length);
if (ret != 0) if (ret != 0)
{ {
/* Something went wrong, relink the jump. */ /* Something went wrong, relink the jump. */
@ -315,6 +318,7 @@ set_fast_tracepoint_jump (CORE_ADDR where,
struct process_info *proc = current_process (); struct process_info *proc = current_process ();
struct fast_tracepoint_jump *jp; struct fast_tracepoint_jump *jp;
int err; int err;
unsigned char *buf;
/* We refcount fast tracepoint jumps. Check if we already know /* We refcount fast tracepoint jumps. Check if we already know
about a jump at this address. */ about a jump at this address. */
@ -333,12 +337,12 @@ set_fast_tracepoint_jump (CORE_ADDR where,
jp->length = length; jp->length = length;
memcpy (fast_tracepoint_jump_insn (jp), insn, length); memcpy (fast_tracepoint_jump_insn (jp), insn, length);
jp->refcount = 1; jp->refcount = 1;
buf = alloca (length);
/* Note that there can be trap breakpoints inserted in the same /* Note that there can be trap breakpoints inserted in the same
address range. To access the original memory contents, we use address range. To access the original memory contents, we use
`read_inferior_memory', which masks out breakpoints. */ `read_inferior_memory', which masks out breakpoints. */
err = read_inferior_memory (where, err = read_inferior_memory (where, buf, length);
fast_tracepoint_jump_shadow (jp), jp->length);
if (err != 0) if (err != 0)
{ {
if (debug_threads) if (debug_threads)
@ -349,6 +353,7 @@ set_fast_tracepoint_jump (CORE_ADDR where,
free (jp); free (jp);
return NULL; return NULL;
} }
memcpy (fast_tracepoint_jump_shadow (jp), buf, length);
/* Link the jump in. */ /* Link the jump in. */
jp->inserted = 1; jp->inserted = 1;
@ -363,8 +368,7 @@ set_fast_tracepoint_jump (CORE_ADDR where,
the current shadow contents, because write_inferior_memory the current shadow contents, because write_inferior_memory
updates any shadow memory with what we pass here, and we want updates any shadow memory with what we pass here, and we want
that to be a nop. */ that to be a nop. */
err = write_inferior_memory (where, fast_tracepoint_jump_shadow (jp), err = write_inferior_memory (where, buf, length);
length);
if (err != 0) if (err != 0)
{ {
if (debug_threads) if (debug_threads)
@ -403,6 +407,8 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
if (jp->inserted) if (jp->inserted)
{ {
unsigned char *buf;
jp->inserted = 0; jp->inserted = 0;
/* Since there can be trap breakpoints inserted in the same /* Since there can be trap breakpoints inserted in the same
@ -414,9 +420,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
pass the current shadow contents, because pass the current shadow contents, because
write_inferior_memory updates any shadow memory with what we write_inferior_memory updates any shadow memory with what we
pass here, and we want that to be a nop. */ pass here, and we want that to be a nop. */
err = write_inferior_memory (jp->pc, buf = alloca (jp->length);
fast_tracepoint_jump_shadow (jp), memcpy (buf, fast_tracepoint_jump_shadow (jp), jp->length);
jp->length); err = write_inferior_memory (jp->pc, buf, jp->length);
if (err != 0) if (err != 0)
{ {
jp->inserted = 1; jp->inserted = 1;
@ -434,6 +440,7 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
{ {
struct fast_tracepoint_jump *jp; struct fast_tracepoint_jump *jp;
int err; int err;
unsigned char *buf;
jp = find_fast_tracepoint_jump_at (where); jp = find_fast_tracepoint_jump_at (where);
if (jp == NULL) if (jp == NULL)
@ -461,8 +468,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
to pass the current shadow contents, because to pass the current shadow contents, because
write_inferior_memory updates any shadow memory with what we pass write_inferior_memory updates any shadow memory with what we pass
here, and we want that to be a nop. */ here, and we want that to be a nop. */
err = write_inferior_memory (where, buf = alloca (jp->length);
fast_tracepoint_jump_shadow (jp), jp->length); memcpy (buf, fast_tracepoint_jump_shadow (jp), jp->length);
err = write_inferior_memory (where, buf, jp->length);
if (err != 0) if (err != 0)
{ {
jp->inserted = 0; jp->inserted = 0;
@ -517,6 +525,7 @@ delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
if (bp->inserted) if (bp->inserted)
{ {
struct raw_breakpoint *prev_bp_link = *bp_link; struct raw_breakpoint *prev_bp_link = *bp_link;
unsigned char buf[MAX_BREAKPOINT_LEN];
*bp_link = bp->next; *bp_link = bp->next;
@ -529,8 +538,8 @@ delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
to pass the current shadow contents, because to pass the current shadow contents, because
write_inferior_memory updates any shadow memory with write_inferior_memory updates any shadow memory with
what we pass here, and we want that to be a nop. */ what we pass here, and we want that to be a nop. */
ret = write_inferior_memory (bp->pc, bp->old_data, memcpy (buf, bp->old_data, breakpoint_len);
breakpoint_len); ret = write_inferior_memory (bp->pc, buf, breakpoint_len);
if (ret != 0) if (ret != 0)
{ {
/* Something went wrong, relink the breakpoint. */ /* Something went wrong, relink the breakpoint. */
@ -738,6 +747,7 @@ uninsert_raw_breakpoint (struct raw_breakpoint *bp)
if (bp->inserted) if (bp->inserted)
{ {
int err; int err;
unsigned char buf[MAX_BREAKPOINT_LEN];
bp->inserted = 0; bp->inserted = 0;
/* Since there can be fast tracepoint jumps inserted in the same /* Since there can be fast tracepoint jumps inserted in the same
@ -748,8 +758,8 @@ uninsert_raw_breakpoint (struct raw_breakpoint *bp)
that we need to pass the current shadow contents, because that we need to pass the current shadow contents, because
write_inferior_memory updates any shadow memory with what we write_inferior_memory updates any shadow memory with what we
pass here, and we want that to be a nop. */ pass here, and we want that to be a nop. */
err = write_inferior_memory (bp->pc, bp->old_data, memcpy (buf, bp->old_data, breakpoint_len);
breakpoint_len); err = write_inferior_memory (bp->pc, buf, breakpoint_len);
if (err != 0) if (err != 0)
{ {
bp->inserted = 1; bp->inserted = 1;
@ -975,6 +985,9 @@ check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
CORE_ADDR start, end; CORE_ADDR start, end;
int copy_offset, copy_len, buf_offset; int copy_offset, copy_len, buf_offset;
gdb_assert (fast_tracepoint_jump_shadow (jp) >= buf + mem_len
|| buf >= fast_tracepoint_jump_shadow (jp) + (jp)->length);
if (mem_addr >= bp_end) if (mem_addr >= bp_end)
continue; continue;
if (jp->pc >= mem_end) if (jp->pc >= mem_end)
@ -1004,6 +1017,9 @@ check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
CORE_ADDR start, end; CORE_ADDR start, end;
int copy_offset, copy_len, buf_offset; int copy_offset, copy_len, buf_offset;
gdb_assert (bp->old_data >= buf + mem_len
|| buf >= &bp->old_data[sizeof (bp->old_data)]);
if (mem_addr >= bp_end) if (mem_addr >= bp_end)
continue; continue;
if (bp->pc >= mem_end) if (bp->pc >= mem_end)
@ -1052,6 +1068,11 @@ check_mem_write (CORE_ADDR mem_addr, unsigned char *buf,
CORE_ADDR start, end; CORE_ADDR start, end;
int copy_offset, copy_len, buf_offset; int copy_offset, copy_len, buf_offset;
gdb_assert (fast_tracepoint_jump_shadow (jp) >= myaddr + mem_len
|| myaddr >= fast_tracepoint_jump_shadow (jp) + (jp)->length);
gdb_assert (fast_tracepoint_jump_insn (jp) >= buf + mem_len
|| buf >= fast_tracepoint_jump_insn (jp) + (jp)->length);
if (mem_addr >= jp_end) if (mem_addr >= jp_end)
continue; continue;
if (jp->pc >= mem_end) if (jp->pc >= mem_end)
@ -1082,6 +1103,9 @@ check_mem_write (CORE_ADDR mem_addr, unsigned char *buf,
CORE_ADDR start, end; CORE_ADDR start, end;
int copy_offset, copy_len, buf_offset; int copy_offset, copy_len, buf_offset;
gdb_assert (bp->old_data >= myaddr + mem_len
|| myaddr >= &bp->old_data[sizeof (bp->old_data)]);
if (mem_addr >= bp_end) if (mem_addr >= bp_end)
continue; continue;
if (bp->pc >= mem_end) if (bp->pc >= mem_end)