Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: Tom de Vries <tdevries@suse.de>, gdb-patches@sourceware.org
Subject: Re: [PATCH] [gdb] Fix heap-buffer-overflow in args_complete_p
Date: Wed, 07 Jan 2026 15:01:10 +0000	[thread overview]
Message-ID: <87tswxv555.fsf@redhat.com> (raw)
In-Reply-To: <a1eb10ab-5a8a-4997-9a82-e08ca7ea32e1@suse.de>

Tom de Vries <tdevries@suse.de> writes:

> On 1/7/26 11:46 AM, Andrew Burgess wrote:
>> Tom de Vries <tdevries@suse.de> writes:
>> 
>>> On 1/5/26 8:57 PM, Andrew Burgess wrote:
>>>> Tom de Vries <tdevries@suse.de> writes:
>>>>
>>>>> PR gdb/33754 reports a heap-buffer-overflow here in args_complete_p:
>>>>> ...
>>>>>     while (*input != '\0')
>>>>> ...
>>>>>
>>>>> Fix this by introducing a lambda function at that safely handles all char
>>>>> array accesses.
>>>>
>>>> Sorry to be a bore, but after reading this commit, and the bug report,
>>>> it's still not obvious to me where the overflow actually occurs.
>>>>
>>>> I totally accept that this code is broken, but as I introduced this bug,
>>>> I wanted to learn from this mistake, but this commit doesn't really
>>>> explain what mistake is being fixed.
>>>>
>>>> Do you think you could explain what's actually going wrong here?
>>>>
>>>
>>> Hi Andrew,
>>>
>>> agreed, it's not spelled out, sorry about that.
>>>
>>> So, the heap-buffer-overflow happens with:
>>> ...
>>> (gdb) p args
>>> $1 = "\"first arg\" \"\" \"third-arg\" \"'\" \"\\\"\" \" \" \"\" "
>>> ...
>>> and it's the fact that we don't check for '\0' after skip_spaces that is
>>> the problem.  I think it should be possible to reproduce the problem
>>> with args == " ".
>> 
>> Thanks for breaking it down for me.  I don't really like the original
>> lambda function approach that was proposed, I'd prefer to just see the
>> correct checks added to the loop.  More inline below...
>> 
>>>
>>> So a minimal fix for this problem is:
>>> ...
>>> diff --git a/gdb/infcmd.c b/gdb/infcmd.c
>>> index 1a7daf1461b..fdcd4e4ba96 100644
>>> --- a/gdb/infcmd.c
>>> +++ b/gdb/infcmd.c
>>> @@ -131,6 +131,8 @@ args_complete_p (const std::string &args)
>>>      while (*input != '\0')
>>>        {
>>>          input = skip_spaces (input);
>>> +      if (*input == '\0')
>>> +	break;
>> 
>> I think I prefer this to Tom's proposed 'for' loop, but I don't feel
>> super strongly each way.
>> 
>>>
>>>          if (squote)
>>>    	{
>>> ...
>>>
>>> But the strchr problem is also there, so this:
>>> ...
>>> diff --git a/gdb/infcmd.c b/gdb/infcmd.c
>>> index 1a7daf1461b..4bcd523f79b 100644
>>> --- a/gdb/infcmd.c
>>> +++ b/gdb/infcmd.c
>>> @@ -177,6 +177,8 @@ args_complete_p (const std::string &args)
>>>    	    dquote = true;
>>>    	}
>>>
>>> +      if (*input == '\0')
>>> +	break;
>> 
>> I'd replace this with 'gdb_assert (*input != '\0');', and then use
>> something like the extra check I proposed next to the strchr calls.  Or
>> maybe we should add a new helper function in gdbsupport/ like:
>> 
>>    static char *
>>    strchr_not_null (char *s, int c)
>>    {
>>      if (c == '\0')
>>        return nullptr;
>>    
>>      return strchr (s, c);
>>    }
>>    
>>    static const char *
>>    strchr_not_null (const char *s, int c)
>>    {
>>      return strchr_not_null (const_cast<char *> (s), c);
>>    }
>> 
>> which wraps the null check.  Either would be fine with me.
>> 
>> I also liked the selftests you added, I extended them to:
>> 
>>    static void
>>    check_str (const std::string &str, bool complete_p)
>>    {
>>      const char *end;
>>    
>>      SELF_CHECK (args_complete_p (str, &end) == complete_p);
>>      SELF_CHECK (end == str.data () + str.size ());
>>    }
>>    
>>    static void
>>    infcmd_args_complete_p_tests (void)
>>    {
>>      check_str (" ", true);
>>      check_str ("\\", true);
>>      check_str ("\"\\", false);
>>    }
>> 
>> which covers all the bugs that are being fixed here.
>> 
>
> Hi Andrew,
>
> thanks for the comments.
>
> But by now, a v2 was submitted, approved and committed.
>
> So perhaps you want to submit a refactoring patch addressing some of 
> your insights here.  Otherwise, I can take it further.  Let me know what 
> you prefer.

No, that's fine.  I do with more people would post vN patches as follow
ups to their original messages, it would make tracking revisions so much
easier.

Maybe one day we'll move off the mailing list model.

Thanks,
Andrew


  reply	other threads:[~2026-01-07 15:04 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-03 14:55 Tom de Vries
2026-01-05 16:38 ` Tom Tromey
2026-01-06 14:51   ` Tom de Vries
2026-01-05 19:57 ` Andrew Burgess
2026-01-05 20:02   ` Andrew Burgess
2026-01-05 20:09   ` Tom Tromey
2026-01-06  8:47   ` Tom de Vries
2026-01-06  9:29     ` Tom de Vries
2026-01-06 14:53     ` Tom de Vries
2026-01-07 10:46     ` Andrew Burgess
2026-01-07 11:21       ` Tom de Vries
2026-01-07 15:01         ` Andrew Burgess [this message]
2026-01-07 18:13           ` Tom Tromey
2026-01-12 11:42             ` Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87tswxv555.fsf@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=tdevries@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox