Changeset c6bc434


Ignore:
Timestamp:
2016-02-10T03:53:11Z (9 years ago)
Author:
dequis <dx@…>
Parents:
9456255
Message:

Fix a double free when calling proxy_disconnect() inside phb->func()

Fixes trac ticket #1248

proxy_connected() calls phb->func(), then tries to do phb_free() directly
afterwards, but that might have been freed by a proxy_disconnect() call
during the execution of that callback.

This one happened to two different people today, probably because some
AIM server broke.

This commit fixes it by checking the phb hash table again, ensuring that
there's something attached to the same fd, and checking that the value
of the returned pointer is the same as the one we had before.

I'm not a lawyer but I think that relying on the value of the phb
pointer, which may be freed, is undefined behavior. The memory allocator
could reuse that pointer, and the OS could reuse that fd. You could
totally write some code that disconnects then establishes a new
connection that reuses the same fd and memory locations. This fix sucks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/proxy.c

    r9456255 rc6bc434  
    9292        socklen_t len;
    9393        int error = ETIMEDOUT;
     94        int fd;
    9495
    9596        len = sizeof(error);
     
    122123        phb->inpa = 0;
    123124
     125        fd = phb->fd;
     126
    124127        if (phb->proxy_func) {
    125128                phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ);
    126129        } else {
     130                struct PHB *phb_check;
     131
    127132                phb->func(phb->data, source, B_EV_IO_READ);
    128                 phb_free(phb, TRUE);
     133
     134                /* Check the hash table again before touching phb, in case it was freed */
     135                if ((phb_check = g_hash_table_lookup(phb_hash, &fd)) && phb_check == phb) {
     136                        phb_free(phb, TRUE);
     137                }
    129138        }
    130139
Note: See TracChangeset for help on using the changeset viewer.