tags 442132 + patch
thanks

Hi Noèl,
* Noèl Köthe <[EMAIL PROTECTED]> [2007-10-26 18:32]:
> tags 442132 + confirmed upstream
> found 442132 3.2.1-1
> forwarded 442132 http://tcpreplay.synfin.net/trac/ticket/273
> thanks
> 
> Am Donnerstag, den 13.09.2007, 14:42 +0200 schrieb Filippo Giunchedi:
[...] 
> > $ tcpreplay -N
> > 
> > Warning: May need to run as root to get complete list.
> > Available network interfaces:
> > 
> > *** glibc detected *** tcpreplay: double free or corruption (top): 
> > 0x10062040 ***
> 
> Thanks for your report. I forwarded it to the upstream bug tracking
> system.

I looked into this bug and I think I found the reason.
The code where the double free corruption is can be found 
in tcpreplay_opts.c:
 916 static void
 917 doOptListnics(
 918     tOptions*   pOptions,
 919     tOptDesc*   pOptDesc )
 920 {
 921     /* extracted from tcpreplay_opts.def, line 233 */
 922
 923 interface_list_t *list = get_interface_list();
 924 list_interfaces(list);
 925 free(list);
 926     exit(0);
 927
 928 }

Important here is line 925 in which list gets free'd after the interface 
listing.
Now have a look at get_interface_list which returns a pointer to an allocated 
list.
interface.c:

 82 get_interface_list(void)
 83 {
 84     interface_list_t *list_head, *list_ptr;
 85     char ebuf[PCAP_ERRBUF_SIZE];
 86     pcap_if_t *pcap_if, *pcap_if_ptr;
[...] 
 95     if (pcap_findalldevs(&pcap_if, ebuf) < 0)
 96         errx(1, "Error: %s", ebuf);
 97 
 98     pcap_if_ptr = pcap_if;
 99     list_head = (interface_list_t *)safe_malloc(sizeof(interface_list_t));
100     list_ptr = list_head;
101 
102     while (pcap_if_ptr != NULL) {
103         strlcpy(list_ptr->name, pcap_if_ptr->name, sizeof(list_ptr->name));
[filling some data in the list] 
111         pcap_if_ptr = pcap_if_ptr->next;
112         list_ptr->next = (interface_list_t 
*)safe_malloc(sizeof(interface_list_t));
113         list_ptr = list_ptr->next;
114     }
115     safe_free(list_ptr); /* free the last entry which was never used */
116     pcap_freealldevs(pcap_if);
117     return(list_head);

This will create a linked list and return the head of it in 
line 117. Important here is line 115 which is used to free 
the last element in the list since it is never used but 
always allocated before the loop knows that it's the last 
run.

This basically works but if the program is not run as root 
the pcap_findalldevs will not find the devices so you have 
just one element in the list, list_head. So this would be 
the last element and get freed. Since we also free the list 
in 925 tcpreplay_opts.c we have a double free because this 
was already freed.

Solution would be to change line 115 in interface.c to:
115     if(list_ptr != list_head)
116         safe_free(list_ptr); /* free the last entry which was never used */

HTH,
Nico
-- 
Nico Golde - http://www.ngolde.de - [EMAIL PROTECTED] - GPG: 0x73647CFF
For securite reasons, all text in this mail is dnuble-rot13 encrypted.

Attachment: pgpuFXOh966l4.pgp
Description: PGP signature

Reply via email to