ANNOUNCEMENT: Live Wireshark University & Allegro Packets online APAC Wireshark Training Session
April 17th, 2024 | 14:30-16:00 SGT (UTC+8) | Online

Wireshark-dev: Re: [Wireshark-dev] OID/BER memory oddness

From: Evan Huus <eapache@xxxxxxxxx>
Date: Sun, 15 Dec 2013 13:10:36 -0500
On Sun, Dec 15, 2013 at 12:33 PM, Ed Beroset <beroset@xxxxxxxxxxxxxx> wrote:
> Evan Huus wrote:
>
>> In one sense the problem is easy to trace: the oid resolution code is
>> returning the resolved string in an ep-allocated buffer, which is then
>> getting freed and subsequently used. However, I'm having trouble
>> tracking down exactly where this resolved oid is being persisted
>> between packets, since the way I've followed the trace makes it look
>> like the oid resolution and subsequent use are happening in the same
>> packet, in which case it shouldn't be freed in the middle.
>>
>> I'm hoping this will be obvious to somebody who actually knows the
>> BER/OID code. If not I'll file a bugzilla and attach the capture.
>
>
> If you're asking what I think you're asking, as names get resolved, they're
> added to a static tree called oid_root in oids.c.  The children of that tree
> are supposed to be in wmem_epan_scope().  There are three oid_add functions
> that add items to that tree.  One thing that may help resolving this is to
> set the environment variable WIRESHARK_DEBUG_MIBS to an integer value in the
> range 1 to 10.  (Higher numbers mean more verbose output.)

Hmm, maybe I misspoke, it doesn't really seem to be *resolution*
exactly. The call I'm looking at is to oid_encoded2string() which
doesn't appear to use the static tree. If you follow the normal path
it ends up in rel_oid_subid2string() which returns an ep-allocated
buffer. This buffer is then being stored somewhere I can't find, and
is showing up in some later packet after being freed.

> I'd like to have eliminated the ep_alloc() calls within oids.c in favor of
> the newer wmem_ calls, but didn't have the time to do that properly and it
> seemed that it might break other things.  That's why I also added the oid
> unit tests a few months ago.

Ya, the usual pattern for this type of conversion seems to be:
1. Add a parameter for a wmem scope, use that instead of ep or se
memory in the function.
2. For calls to the function within packet dissection code, just pass
wmem_packet_scope() and it will behave as it used to.
3. For other calls (from the GUI, etc) figure out what the appropriate
scope actually is and use that. This usually just ends up being
manually managed, so passing NULL for the scope.

Depending on how many callers there are it can be a lot of work.

> If that doesn't help, let me know where I went astray and I can try again.

The part that's confusing me is that somehow
actx->external.direct_reference seems to be getting a pointer to this
stale ep-allocated buffer, but I can't find anywhere in the call stack
that value could be set to such a stale buffer.

Thanks,
Evan