kern/72217: Bug in calculation of the parameter for the in6_rtqtimo and in6_mtutimo timeout functions

Richard Andrades richard.andrades at utstar.com
Thu Sep 30 16:20:25 PDT 2004


>Number:         72217
>Category:       kern
>Synopsis:       Bug in calculation of the parameter for the in6_rtqtimo and in6_mtutimo timeout functions
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Sep 30 23:20:24 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Richard Andrades
>Release:        FreeBSD 4.9 RELEASE
>Organization:
UTStarcom
>Environment:
FreeBSD mobo14 4.9-RELEASE FreeBSD 4.9-RELEASE #0   root at rainier.nj.us.utstar.com:/usr/home/build/richard/main/os/freebsd/kernel/DISKLESS  i386
>Description:
The current time is not subtracted from the calculated (future) absolute
time for the timeout function before calling timeout() - which expects a
relative time. This results in the function getting called after a (much)
larger than expected timeout time interval.

>How-To-Repeat:
These timeouts are not used very often so it is not easy to notice this
problem. It does not show up normally. Only found them by accident while
debugging the timer code for an unrelated problem.

>Fix:
FILE: src/sys/netinet6/in6_rmx.c

The bug is present in two separate functions in this file.

static void
in6_rtqtimo(void *rock)
{
..
..
..
        atv.tv_usec = 0;
	atv.tv_sec = arg.nextstop; /* BUG: Must subtract current time */
	timeout(in6_rtqtimo, rock, tvtohz(&atv));
}

AND:

static void
in6_mtutimo(void *rock)
{
..
..
..
        atv.tv_usec = 0;
	atv.tv_sec = arg.nextstop;
	if (atv.tv_sec < time_second) {
		printf("invalid mtu expiration time on routing table\n");
		arg.nextstop = time_second + 30;	/* last resort */
	}
        /* BUG: Must subtract surrent time */
	timeout(in6_mtutimo, rock, tvtohz(&atv));
}



Change to:

static void
in6_rtqtimo(void *rock)
{
..
..
..
        atv.tv_usec = 0;
	atv.tv_sec = arg.nextstop - time_second; /* Fix: Subtract current time */
	timeout(in6_rtqtimo, rock, tvtohz(&atv));
}

AND:

static void
in6_mtutimo(void *rock)
{
..
..
..
        atv.tv_usec = 0;
	atv.tv_sec = arg.nextstop;
	if (atv.tv_sec < time_second) {
		printf("invalid mtu expiration time on routing table\n");
		arg.nextstop = time_second + 30;	/* last resort */
	}
	atv.tv_sec = arg.nextstop - time_second; /* Fix: Subtract current time */
	timeout(in6_mtutimo, rock, tvtohz(&atv));
}


Note:

These problems are still present in newer versions of FreeBSD
although the code is now using callout_reset() instead of timeout().

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list