Opened 15 years ago
Closed 15 years ago
#1048 closed defect (fixed)
Memory leak in enum_ipv4_ipv6_interface (ip_helper_win32.c) (thanks Andrey Mamchur for the report)
Reported by: | bennylp | Owned by: | bennylp |
---|---|---|---|
Priority: | normal | Milestone: | release-1.6 |
Component: | pjlib | Version: | trunk |
Keywords: | Cc: | ||
Backport to 1.x milestone: | Backported: |
Description
When local buffer length is less than what is required by GetAdapterAddresses(), function enum_ipv4_ipv6_interface() does't free the temporary buffer.
Steps to reproduce:
- Make local buffer 1 byte length.
- Call enum_ipv4_ipv6_interface()
static pj_status_t enum_ipv4_ipv6_interface(int af, unsigned *p_cnt, pj_sockaddr ifs[]) { pj_uint8_t buffer[600]; // Change buffer length to 1. IP_ADAPTER_ADDRESSES *adapter = (IP_ADAPTER_ADDRESSES*)buffer; ULONG size = sizeof(buffer); ULONG flags; unsigned i; DWORD rc; flags = GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST; rc = MyGetAdapterAddresses(af, flags, NULL, adapter, &size); if (rc != ERROR_SUCCESS) { if (rc == ERROR_BUFFER_OVERFLOW) { /* Retry with larger memory size */ adapter = (IP_ADAPTER_ADDRESSES*) malloc(size); // <==== Memory allocated if (adapter != NULL) rc = MyGetAdapterAddresses(af, flags, NULL, adapter, &size); } if (rc != ERROR_SUCCESS) { if (adapter != (IP_ADAPTER_ADDRESSES*)buffer) free(adapter); return PJ_RETURN_OS_ERROR(rc); } } /* Reset result */ pj_bzero(ifs, sizeof(ifs[0]) * (*p_cnt)); /* Enumerate interface */ for (i=0; i<*p_cnt && adapter; adapter = adapter->Next) { // <==== Condition adapter == NULL break loop .... } if (adapter != (IP_ADAPTER_ADDRESSES*)buffer) free(adapter); // <==== Leak! adapter == NULL *p_cnt = i; return (*p_cnt) ? PJ_SUCCESS : PJ_ENOTFOUND; }
Thank you Andrey Mamchur for the report
Change History (1)
comment:1 Changed 15 years ago by bennylp
- Resolution set to fixed
- Status changed from new to closed
Note: See
TracTickets for help on using
tickets.
Fixed in r3123