diff options
author | Pedro Alves <palves@redhat.com> | 2013-10-22 15:02:28 +0100 |
---|---|---|
committer | Tom Tromey <tromey@sourceware.org> | 2013-10-25 14:02:59 +0000 |
commit | 3a09da41027b75ccbe852bd0e0460638d66db6d1 (patch) | |
tree | 3ea072db1e5cfc6501d52d530c055e860ed064b8 /gdb/remote.c | |
parent | 4e2250753386b308ed148b39a4a3bac00f69f198 (diff) | |
download | gdb-3a09da41027b75ccbe852bd0e0460638d66db6d1.zip gdb-3a09da41027b75ccbe852bd0e0460638d66db6d1.tar.gz gdb-3a09da41027b75ccbe852bd0e0460638d66db6d1.tar.bz2 |
remote: Map invalid signal numbers to GDB_SIGNAL_UNKNOWN.
I realized that remote.c is not validating input here. Currently, if
a remote stub sends in an invalid signal number (or put another way,
if a future stub sends a new signal an old GDB doesn't know about),
GDB will do out of bounds accesses in the
signal_pass/signal_stop/signal_program arrays. It'll probably be a
long while before we add another signal number (and buggy stubs should
just be fixed), but can't hurt to be defensive.
Tested on x86_64 Fedora 17, native gdbserver.
gdb/
2013-10-22 Pedro Alves <palves@redhat.com>
* remote.c (remote_parse_stop_reply) <'T'/'S'/'X' replies>: Map
invalid signal numbers to GDB_SIGNAL_UNKNOWN.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index a2e8a01..7d8a4de 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -5720,9 +5720,16 @@ Packet: '%s'\n"), /* fall through */ case 'S': /* Old style status, just signal only. */ - event->ws.kind = TARGET_WAITKIND_STOPPED; - event->ws.value.sig = (enum gdb_signal) - (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))); + { + int sig; + + event->ws.kind = TARGET_WAITKIND_STOPPED; + sig = (fromhex (buf[1]) << 4) + fromhex (buf[2]); + if (GDB_SIGNAL_FIRST <= sig && sig < GDB_SIGNAL_LAST) + event->ws.value.sig = (enum gdb_signal) sig; + else + event->ws.value.sig = GDB_SIGNAL_UNKNOWN; + } break; case 'W': /* Target exited. */ case 'X': @@ -5746,7 +5753,10 @@ Packet: '%s'\n"), { /* The remote process exited with a signal. */ event->ws.kind = TARGET_WAITKIND_SIGNALLED; - event->ws.value.sig = (enum gdb_signal) value; + if (GDB_SIGNAL_FIRST <= value && value < GDB_SIGNAL_LAST) + event->ws.value.sig = (enum gdb_signal) value; + else + event->ws.value.sig = GDB_SIGNAL_UNKNOWN; } /* If no process is specified, assume inferior_ptid. */ |