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.
pgpuFXOh966l4.pgp
Description: PGP signature

