diff options
author | Jan Vrany <jan.vrany@labware.com> | 2022-12-12 13:16:14 +0000 |
---|---|---|
committer | Jan Vrany <jan.vrany@labware.com> | 2022-12-12 13:16:14 +0000 |
commit | b5661ff24f7111246b9e9b5f1cba5afe9d479daf (patch) | |
tree | aaaf78e1340fc169c3e153358483c31b42d58457 /gdb/top.c | |
parent | x86: further re-work insn/suffix recognition to also cover MOVSX (diff) | |
download | binutils-gdb-b5661ff24f7111246b9e9b5f1cba5afe9d479daf.tar.gz binutils-gdb-b5661ff24f7111246b9e9b5f1cba5afe9d479daf.tar.bz2 binutils-gdb-b5661ff24f7111246b9e9b5f1cba5afe9d479daf.zip |
gdb: fix possible use-after-free when executing commands
In principle, `execute_command()` does following:
struct cmd_list_element *c;
c = lookup_cmd ( ... );
...
/* If this command has been pre-hooked, run the hook first. */
execute_cmd_pre_hook (c);
...
/* ...execute the command `c` ...*/
...
execute_cmd_post_hook (c);
This may lead into use-after-free error. Imagine the command
being executed is a user-defined Python command that redefines
itself. In that case, struct `cmd_list_element` pointed to by
`c` is deallocated during its execution so it is no longer valid
when post hook is executed.
To fix this case, this commit looks up the command once again
after it is executed to get pointer to (possibly newly allocated)
`cmd_list_element`.
Diffstat (limited to 'gdb/top.c')
-rw-r--r-- | gdb/top.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/gdb/top.c b/gdb/top.c index e9794184f07..742997808bd 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -655,6 +655,11 @@ execute_command (const char *p, int from_tty) } } + /* Remember name of the command. This is needed later when + executing command post-hooks to handle the case when command + is redefined or removed during it's execution. See below. */ + std::string c_name (c->name); + /* If this command has been pre-hooked, run the hook first. */ execute_cmd_pre_hook (c); @@ -693,8 +698,13 @@ execute_command (const char *p, int from_tty) maybe_wait_sync_command_done (was_sync); - /* If this command has been post-hooked, run the hook last. */ - execute_cmd_post_hook (c); + /* If this command has been post-hooked, run the hook last. + We need to lookup the command again since during its execution, + a command may redefine itself. In this case, C pointer + becomes invalid so we need to look it up again. */ + c = lookup_cmd_exact (c_name.c_str (), cmdlist); + if (c != nullptr) + execute_cmd_post_hook (c); if (repeat_arguments != NULL && cmd_start == saved_command_line) { |