aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@polymtl.ca>2022-12-15 14:06:25 -0500
committerSimon Marchi <simon.marchi@polymtl.ca>2022-12-15 21:49:29 -0500
commitf8631e5e04dbef678323e9be6b7329f39049d2c4 (patch)
treeaaed5236c5d78d30cb74fd0109cf60fec6c08a83 /gdb/python
parentffd894b51dc68c87f88ae0b09fc90e9bb272aa08 (diff)
downloadgdb-f8631e5e04dbef678323e9be6b7329f39049d2c4.zip
gdb-f8631e5e04dbef678323e9be6b7329f39049d2c4.tar.gz
gdb-f8631e5e04dbef678323e9be6b7329f39049d2c4.tar.bz2
gdb: remove static buffer in command_line_input
[I sent this earlier today, but I don't see it in the archives. Resending it through a different computer / SMTP.] The use of the static buffer in command_line_input is becoming problematic, as explained here [1]. In short, with this patch [2] that attempt to fix a post-hook bug, when running gdb.base/commands.exp, we hit a case where we read a "define" command line from a script file using command_command_line_input. The command line is stored in command_line_input's static buffer. Inside the define command's execution, we read the lines inside the define using command_line_input, which overwrites the define command, in command_line_input's static buffer. After the execution of the define command, execute_command does a command look up to see if a post-hook is registered. For that, it uses a now stale pointer that used to point to the define command, in the static buffer, causing a use-after-free. Note that the pointer in execute_command points to the dynamically-allocated buffer help by the static buffer in command_line_input, not to the static object itself, hence why we see a use-after-free. Fix that by removing the static buffer. I initially changed command_line_input and other related functions to return an std::string, which is the obvious but naive solution. The thing is that some callees don't need to return an allocated string, so this this an unnecessary pessimization. I changed it to passing in a reference to an std::string buffer, which the callee can use if it needs to return dynamically-allocated content. It fills the buffer and returns a pointers to the C string inside. The callees that don't need to return dynamically-allocated content simply don't use it. So, it started with modifying command_line_input as described above, all the other changes derive directly from that. One slightly shady thing is in handle_line_of_input, where we now pass a pointer to an std::string's internal buffer to readline's history_value function, which takes a `char *`. I'm pretty sure that this function does not modify the input string, because I was able to change it (with enough massaging) to take a `const char *`. A subtle change is that we now clear a UI's line buffer using a SCOPE_EXIT in command_line_handler, after executing the command. This was previously done by this line in handle_line_of_input: /* We have a complete command line now. Prepare for the next command, but leave ownership of memory to the buffer . */ cmd_line_buffer->used_size = 0; I think the new way is clearer. [1] https://inbox.sourceware.org/gdb-patches/becb8438-81ef-8ad8-cc42-fcbfaea8cddd@simark.ca/ [2] https://inbox.sourceware.org/gdb-patches/20221213112241.621889-1-jan.vrany@labware.com/ Change-Id: I8fc89b1c69870c7fc7ad9c1705724bd493596300 Reviewed-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-breakpoint.c2
-rw-r--r--gdb/python/py-gdb-readline.c3
-rw-r--r--gdb/python/python.c2
3 files changed, 4 insertions, 3 deletions
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 63b18bd..de7b9f4 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -582,7 +582,7 @@ bppy_set_commands (PyObject *self, PyObject *newvalue, void *closure)
bool first = true;
char *save_ptr = nullptr;
auto reader
- = [&] ()
+ = [&] (std::string &buffer)
{
const char *result = strtok_r (first ? commands.get () : nullptr,
"\n", &save_ptr);
diff --git a/gdb/python/py-gdb-readline.c b/gdb/python/py-gdb-readline.c
index af388d5..c82f1c8 100644
--- a/gdb/python/py-gdb-readline.c
+++ b/gdb/python/py-gdb-readline.c
@@ -38,11 +38,12 @@ gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout,
{
int n;
const char *p = NULL;
+ std::string buffer;
char *q;
try
{
- p = command_line_input (prompt, "python");
+ p = command_line_input (buffer, prompt, "python");
}
/* Handle errors by raising Python exceptions. */
catch (const gdb_exception &except)
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 29f2010..4aa2442 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -644,7 +644,7 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
bool first = true;
char *save_ptr = nullptr;
auto reader
- = [&] ()
+ = [&] (std::string &buffer)
{
const char *result = strtok_r (first ? &arg_copy[0] : nullptr,
"\n", &save_ptr);