qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] fix gdbserver_state pointer validation


From: Philippe Mathieu-Daudé
Subject: Re: [Qemu-devel] [PATCH] fix gdbserver_state pointer validation
Date: Tue, 10 Jul 2018 18:14:47 -0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0

On 07/10/2018 08:44 AM, stephane duverger wrote:
> Hi Alex,
> 
> There don't seem to be any other patches attached? I would NACK a patch
>> that isn't actually used in-tree.
> 
> 
> No there isn't ! I should have not been so prolix. Actually the patch
> corrects a
> possible null pointer dereference in the gdbserver code. That's all folks.
> 
> Below is how I discovered it and why it matters, imho, to be fixed
> (out of a pending issue).
> 
> This null deref does not happen in normal operation because of the way
> gdbserver is initialized. However what I was telling you, is that it may be
> really interesting to be able to take benefit of some gdb features
> internally
> without starting a gdbserver and the overhead of the gdb protocol when
> there is no need for a client/server interaction while debugging.

To reach gdb_set_stop_cpu() with gdbserver_state == NULL, you previously
entered gdb_vm_state_change() with and use CPUState *cpu =
gdbserver_state->c_cpu = NULL deref, which shouldn't happen.
Also in gdb_set_stop_cpu() you finally call cpu_single_step(cpu=crap)
which then deref crap->singlestep_enabled.

So I think this is not the correct fix.

Since this shouldn't happen, I'd add an assert(gdbserver_state) in
gdb_set_stop_cpu(), and clean gdb_vm_state_change()'s code flow to not
reach this.

> For instance, I developed a special purpose x86 board where I needed to
> break at some instructions, do some automation (snapshots, vm memory
> access, cpu analysis) and then resume the VM. Implementing a
> "vm_change_state handler" and dealing with RUN_STATE_DEBUG was
> perfect for my need.

I recommend you to use "configure --enable-sanitizers" to build your
special purpose board, that will show up those issues.

> The debug events (#BP, #DB) are tied to the gdbserver stub, at some point
> when "cpu_handle_guest_debug()" is called, a call to "gdb_set_stop_cpu()"
> triggers the NULL deref because the gdbserver is not initialized.
> 
> My little fix addresses this error and allows to make use of the following
> Qemu
> breakpoint functions without touching "cpus.c" or "exec.c":
> - cpu_breakpoint_remove/insert()
> - kvm_remove/insert_breakpoint()
> 
> Notice, that in the particular case of KVM, I had to async_run_on_cpu() my
> debug handler instead of directly executing it in the context of
> vm_change_state(). The vCPU started to significantly slow down
> (low irq rate), while this never happens with the TCG.
> 
> Is that more clear to you Alex ? (and hopefully lead to patch ACK :)
> 
> Regards,
> 
> stephane
> 
>> Signed-off-by: Stephane Duverger <address@hidden>
>>> ---
>>>  gdbstub.c | 3 +++
>>>  1 file changed, 3 insertions(+)
>>>
>>> diff --git a/gdbstub.c b/gdbstub.c
>>> index d6ab95006c..788fd625ab 100644
>>> --- a/gdbstub.c
>>> +++ b/gdbstub.c
>>> @@ -1412,6 +1412,9 @@ static int gdb_handle_packet(GDBState *s, const
>> char *line_buf)
>>>
>>>  void gdb_set_stop_cpu(CPUState *cpu)
>>>  {
>>> +    if (!gdbserver_state) {
>>> +        return;
>>> +    }
>>>      gdbserver_state->c_cpu = cpu;
>>>      gdbserver_state->g_cpu = cpu;

I find it safer the opposite way, if (s) { s-> ... }

>>>  }

Regards,

Phil.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]