tcpdump mailing list archives

Re: How to check if pcap_t is really free?


From: Nadav Vinik <nadavvin () gmail com>
Date: Fri, 21 Jun 2013 00:42:10 +0300

On 20 June 2013 23:52, Guy Harris <guy () alum mit edu> wrote:


On Jun 20, 2013, at 1:05 PM, Nadav Vinik <nadavvin () gmail com> wrote:



On 20 June 2013 22:47, Guy Harris <guy () alum mit edu> wrote:

On Jun 20, 2013, at 12:36 PM, Nadav Vinik <nadavvin () gmail com> wrote:

Hoever if I change to pcap_close(&handle) I get the following error:

Because code that passes a pointer to a pointer to a pcap_t, rather than
a pointer to a pcap_t, to pcap_close() is erroneous code.

You cannot arrange that libpcap somehow make a pcap_t or a pointer to it
detectably invalid when you close the handle; if you want to know whether a
pcap_t has been closed, you will have to make your code explicitly mark it
as such.  For example, replace all occurrences of

        pcap_close(handle);

in your code with

        pcap_close(handle);
        handle = NULL;

Back to the original question.

Is there a way to check if handle is already free?

No.  If it's freed, what that does to it depends on the implementation of
free() on your platform.

However:

my problem is that it become free even before it reach to pcap_close.

Are you certain that's really the case?

see:
https://mail.gnome.org/archives/vala-list/2013-June/msg00022.html

Which says:

tmp18_ = pcap_next (_tmp16_, &_tmp17_);
     (&header);
    header = _tmp17_;
    _tmp19_ = _tmp18_;
    _tmp19__length1 = -1;
    *//_tmp19_ = (g_free (_tmp19_), NULL);*

If that first line was really

        _tmp18_ = pcap_next (_tmp16_, &_tmp17_);

then that g_free() call is *WRONG WRONG WRONG*.  The return value of
pcap_next() is *NOT* allocated by the pcap_next() call, it may well be a
pointer into the *MIDDLE* of a buffer allocated by libpcap, or might be a
pointer to a buffer that libpcap allocated for its own purposes and will
use in future calls, and you *MUST NOT EVER EVER EVER EVER EVER EVER EVER
EVER EVER EVER EVER* call free() or g_free() or anything else that frees
memory on it; you must leave it up to libpcap to free whatever memory it's
contained in.

In addition, you must not assume a pointer returned by the Nth call to
pcap_next() will be valid after the N+1st call to pcap_next().

If that code was generated by the Vala compiler, either the compiler, or
whatever file caused the compiler to generate code that hands the result of
pcap_next() to g_free(), need to be fixed.

As for printing "handle is null", well, let's look at _pcap_close0():

#define _pcap_close0(var) ((var == NULL) ? NULL : (var = (pcap_close
(var),
NULL)))

That code will set var to NULL if it's not already null; if it's not NULL,
it will set it to the result of the C expression

        (pcap_close (var), NULL)

which evaluates to NULL with a side-effect of pcap_close() being called on
its previous value.

I.e., _pcap_close0() does the exact "explicitly mark it as such" I was
talking about.

On Linux, when libpcap uses the "turbopacket" (memory-mapped) mechanism to
receive packets (which it does by default), pcap_next() copies the packet
from the memory-mapped buffer into a buffer it allocated (because that's
the only way to make sure it'll remain valid after the call that returns
it, due to the way the memory-mapped mechanism works), and pcap_close()
frees that buffer.

If something bogusly frees that buffer before pcap_close() is called,
pcap_close() will attempt to free it, and get a double free error.

The *ONLY* correct way to fix this is *NEVER* to free the result of
pcap_next().  I don't know how, in Vala, you say "this function returns a
pointer to an array of Uint8s, but you must not ever free that what that
pointer points to", but if that needs to be specified in the Vala code for
pcap_next, and it's not being done, it needs to be done, and if it *is*
being done, the Vala compiler is broken.


Thanks you very much :)

I fix the problem. using the keyword "unowned" prevent vala to free the
result.
I open bug on it on the vapi binding:
https://github.com/apmasell/vapis/issues/6

Thanks
Nadav

-- 
הבלוג שלי:
http://nadavvin.com
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers () lists tcpdump org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers

Current thread: