Hi, John, thanks for the follow-up. I have used gdb but I didn't hit any
failed assertion. I will file a bug with the test sample and reference you
in it so you can have a clearer view of what's going on.

On Sun, Mar 28, 2021 at 1:33 AM John Thacker <johnthac...@gmail.com> wrote:

>
> On Sat, Mar 27, 2021 at 2:57 PM Dario Lombardo <lom...@gmail.com> wrote:
>
>> Hi John,
>> thanks, your explanation helped a lot. However I still don't get why the
>> code crashes. Please let me use the actual buffer sizes since the ones I
>> told before were examples. The packet is 49, the local buffer is 15.
>>
>> When you call tvb_get_nstringz0() you pass in bufsize = 15.
>>> tvb_get_nstringz0() calls _tvb_get_nstringz()
>>> check_offset_len() runs to the end of the packet, setting len to 49.
>>> Since len >= bufsize, it sets limit = bufsize.
>>> stringlen = tvb_strnlen(tvb, abs_offset, limit - 1) looks at the first 9
>>> bytes, doesn't find a NUL, returns -1
>>>
>>
>> That's a point I don't get. This piece of code (stringlen =
>> tvb_strnlen(tvb, 0, 14)) actually returns 49. Despite the fact that NULL is
>> present or not, shouldn't this function fulfill the (limit - 1)? Shouldn't
>> that return 14 at most?
>>
>>
>>> stringlen is -1, tvb_memcpy copies over limit (10) bytes into buffer
>>> from tvb, bytes_copies is set to 10, _tvb_get_nstringz() returns -1.
>>>
>>
>> That's where things start to get hairy: stringlen is 49, then the actual
>> copy starts against buffer, that is only 15 bytes long. Crash.
>>
>
> Huh, that's odd. I just added some lines to packet-http.c near the top of
> dissect_http_tcp() like so:
>
>         guint bufsize = 19;
>         guint8 buffer[19];
>         tvb_get_nstringz0(tvb, 0, bufsize, buffer);
>
> And stepped through with gdb after setting a breakpoint and opening a file
> with a ~480 byte HTTP packet with no nulls in the HTTP layer:
>
> 3578 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
> (gdb) print limit -1
> $12 = 18
> (gdb) n
> 3580 if (stringlen == -1) {
> (gdb) print stringlen
> $14 = -1
> (gdb) print tvb->length
> $15 = 479
>
> And all proceeds as expected.
>
> tvb_strnlen(tvb, offset, maxlength) is supposed to return -1 if
> 'maxlength' (here, 14) is reached before a NULL.
>
> Let's see, tvb_strnlen calls tvb_find_guint8(tvb, abs_offset,
> maxlength=14, 0), and returns -1 if and only if tvb_find_guint8(...)
> returns -1. That looks right, so let's look at tvb_find_guint8():
>
>         DISSECTOR_ASSERT(tvb && tvb->initialized);
>
>         exception = compute_offset_and_remaining(tvb, offset, &abs_offset,
> &limit);
>         if (exception)
>                 THROW(exception);
>
>         /* Only search to end of tvbuff, w/o throwing exception. */
>         if (maxlength >= 0 && limit > (guint) maxlength) {
>                 /* Maximum length doesn't go past end of tvbuff; search
>                    to that value. */
>                 limit = (guint) maxlength;
>         }
>
> Have you tried stepping through it with a debugger? The code looks right
> to me and runs correctly over here. Are you perhaps somehow hitting an
> exception or a failed assertion?
>
> John
>
> ___________________________________________________________________________
> Sent via:    Wireshark-dev mailing list <wireshark-dev@wireshark.org>
> Archives:    https://www.wireshark.org/lists/wireshark-dev
> Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev
>              mailto:wireshark-dev-requ...@wireshark.org
> ?subject=unsubscribe



-- 

Naima is online.
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev@wireshark.org>
Archives:    https://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe

Reply via email to