Bug 2819

Summary: autoroute patch introduces new bug
Product: [Retired] Red Hat Linux Reporter: roganov
Component: tracerouteAssignee: Jay Turner <jturner>
Severity: medium Docs Contact:
Priority: medium    
Version: 6.0CC: mikepery, srevivo
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 1999-05-14 15:11:06 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description roganov 1999-05-14 14:16:13 UTC
Dear Friends !

We found a bug in a traceroute package, linked with a last
patch --
so called autoroute addition.

This bug involves 'Segmentation fault' when traceroute is
at computer having few network interfaces in a following

	traceroute host_not_in_eth2_inet -i eth2

The reason of this bug is a different representation of
code and new autoroute addition: new code assumes that 'al'
variable always contains a list of all interfaces, obtained
via call:
    (see file traceroute.c after all patch being applied)

	ifaddrlist(&al, errbuf);

But really original code changes 'al' pointer below, looking
for pointed device:

	/* Look for a specific device */
	if (device != NULL) {
		for (i = n; i > 0; --i, ++al)
			if (strcmp(device, al->device) == 0)
		if (i <= 0) {
			Fprintf(stderr, "%s: Can't find interface %s\n",
			    prog, device);

As a result routine 'search_routing_table' is called of
inproper data
what leads to program crash.

We are currently using following changes for code:

--- traceroute.c.old    Fri May 14 14:13:02 1999
+++ traceroute.c        Fri May 14 14:21:41 1999
@@ -348,7 +348,7 @@
        int tos = 0, settos = 0;
        register int lsrr = 0;
        register u_short off = 0;
-       struct ifaddrlist *al;
+       struct ifaddrlist *al, *al_orig;
        char errbuf[132];

        if ((cp = strrchr(argv[0], '/')) != NULL)
@@ -670,6 +670,7 @@

        /* Get the interface address list */
        n = ifaddrlist(&al, errbuf);
+       al_orig = al;
        if (n < 0) {
                Fprintf(stderr, "%s: ifaddrlist: %s\n",
prog, errbuf);
@@ -700,7 +701,7 @@
                 * there is no match, default to using the
                 * interface found.
-               al = search_routing_table(to, al, n);
+               al = search_routing_table(to, al_orig, n);
                setsin(from, al->addr);

what is currently used in our
added to traceroute.spec file.

Comment 1 Jeff Johnson 1999-05-14 15:11:59 UTC
Fixed in traceroute-1.4a5-15. Thanks for the analysis and patch!

Comment 2 Jeff Johnson 1999-06-07 10:27:59 UTC
*** Bug 3295 has been marked as a duplicate of this bug. ***

The USE_KERNEL_ROUTING_TABLE patch to traceroute causes it
to segfault with used with -i. This is because the
ifaddrlist is searched for the interface you specify, but
then the search_routing_table() call continues the search at
the position in the list found by the previous search.
Consequently, the second search eventually runs right past
the end of the array in a vain attempt to find a unique
interface. This unintialized memory (zeroed in my case)
causes a segfault when a field of the run away pointer is
passed to a strcmp.

Because all this red tape sickens me, and because I have
better things to do than to wait around for a BUG ID to
submit a one line patch, I'm going to describe the fix here.
Right around line 703 you add:
if(device == NULL && n > 1)
 right before the call to search_routing_table()