From tejblum@developer.yandex.ru  Mon Jan 10 23:28:06 2005
Return-Path: <tejblum@developer.yandex.ru>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 0FB9216A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 10 Jan 2005 23:28:06 +0000 (GMT)
Received: from developer.yandex.ru (developer.yandex.ru [213.180.193.15])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 4CA9C43D2F
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 10 Jan 2005 23:28:05 +0000 (GMT)
	(envelope-from tejblum@developer.yandex.ru)
Received: from developer.yandex.ru (localhost [127.0.0.1])
	by developer.yandex.ru (8.13.1/8.13.1) with ESMTP id j0ANS3cr051522
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 11 Jan 2005 02:28:04 +0300 (MSK)
	(envelope-from tejblum@developer.yandex.ru)
Received: (from tejblum@localhost)
	by developer.yandex.ru (8.13.1/8.13.1/Submit) id j0ANS3Va051521;
	Tue, 11 Jan 2005 02:28:03 +0300 (MSK)
	(envelope-from tejblum)
Message-Id: <200501102328.j0ANS3Va051521@developer.yandex.ru>
Date: Tue, 11 Jan 2005 02:28:03 +0300 (MSK)
From: Dmitrij Tejblum <tejblum@yandex-team.ru>
Reply-To: Dmitrij Tejblum <tejblum@yandex-team.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: arp program failures due to ARP table growth
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         76075
>Category:       bin
>Synopsis:       arp program failures due to ARP table growth
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    maxim
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 10 23:30:27 GMT 2005
>Closed-Date:    Sun Feb 13 12:47:34 GMT 2005
>Last-Modified:  Sun Feb 13 12:47:34 GMT 2005
>Originator:     Dmitrij Tejblum
>Release:        FreeBSD 5.3-STABLE i386
>Organization:
>Environment:

>Description:

The arp -an command sometimes fail with

arp: actual retrieval of routing table: Cannot allocate memory

if ARP tables has been grown after its size was estimated. 

>How-To-Repeat:
>Fix:

Allocate a bit more memory for ARP table, so the event will be less likely.


--- arp.c	Tue Jan 11 02:00:45 2005
+++ arp.c	Tue Jan 11 02:05:15 2005
@@ -471,10 +471,11 @@
 	mib[5] = RTF_LLINFO;
 	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
 		err(1, "route-sysctl-estimate");
 	if (needed == 0)	/* empty table */
 		return 0;
+	needed += needed / 2;
 	if ((buf = malloc(needed)) == NULL)
 		err(1, "malloc");
 	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
 		err(1, "actual retrieval of routing table");
 	lim = buf + needed;
>Release-Note:
>Audit-Trail:

From: Maxim Konovalov <maxim@macomnet.ru>
To: Dmitrij Tejblum <tejblum@yandex-team.ru>
Cc: bug-followup@freebsd.org
Subject: Re: bin/76075: arp program failures due to ARP table growth
Date: Sun, 23 Jan 2005 05:16:35 +0300 (MSK)

 [...]
 > >Description:
 >
 > The arp -an command sometimes fail with
 >
 > arp: actual retrieval of routing table: Cannot allocate memory
 >
 > if ARP tables has been grown after its size was estimated.
 >
 > >How-To-Repeat:
 > >Fix:
 >
 > Allocate a bit more memory for ARP table, so the event will be less likely.
 >
 >
 > --- arp.c	Tue Jan 11 02:00:45 2005
 > +++ arp.c	Tue Jan 11 02:05:15 2005
 > @@ -471,10 +471,11 @@
 >  	mib[5] = RTF_LLINFO;
 >  	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
 >  		err(1, "route-sysctl-estimate");
 >  	if (needed == 0)	/* empty table */
 >  		return 0;
 > +	needed += needed / 2;
 >  	if ((buf = malloc(needed)) == NULL)
 >  		err(1, "malloc");
 >  	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
 >  		err(1, "actual retrieval of routing table");
 >  	lim = buf + needed;
 
 What is your opinion about an enclosed diff (a bit more adaptable
 algorithm stolen from killall(1))?
 
 Index: arp.c
 ===================================================================
 RCS file: /home/ncvs/src/usr.sbin/arp/arp.c,v
 retrieving revision 1.54
 diff -u -r1.54 arp.c
 --- arp.c	24 Dec 2004 22:16:38 -0000	1.54
 +++ arp.c	23 Jan 2005 02:14:10 -0000
 @@ -456,12 +456,12 @@
  {
  	int mib[6];
  	size_t needed;
 -	char *lim, *buf, *next;
 +	char *lim, *buf, *newbuf, *next;
  	struct rt_msghdr *rtm;
  	struct sockaddr_inarp *sin2;
  	struct sockaddr_dl *sdl;
  	char ifname[IF_NAMESIZE];
 -	int found_entry = 0;
 +	int st, found_entry = 0;
 
  	mib[0] = CTL_NET;
  	mib[1] = PF_ROUTE;
 @@ -475,7 +475,19 @@
  		return 0;
  	if ((buf = malloc(needed)) == NULL)
  		err(1, "malloc");
 -	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
 +	st = sysctl(mib, 6, NULL, &needed, NULL, 0);
 +	do {
 +		needed += needed / 2;
 +		newbuf = realloc(buf, needed);
 +		if (newbuf == NULL) {
 +			if (buf != NULL)
 +				free(buf);
 +			errx(1, "could not reallocate memory");
 +		}
 +		buf = newbuf;
 +		st = sysctl(mib, 6, buf, &needed, NULL, 0);
 +	} while (st == -1 && errno == ENOMEM);
 +	if (st == -1)
  		err(1, "actual retrieval of routing table");
  	lim = buf + needed;
  	for (next = buf; next < lim; next += rtm->rtm_msglen) {
 %%%
 
 --
 Maxim Konovalov

From: Dmitrij Tejblum <tejblum@yandex-team.ru>
To: Maxim Konovalov <maxim@macomnet.ru>
Cc: bug-followup@freebsd.org
Subject: Re: bin/76075: arp program failures due to ARP table growth
Date: Sun, 23 Jan 2005 14:17:16 +0300 (MSK)

 > What is your opinion about an enclosed diff (a bit more adaptable
 > algorithm stolen from killall(1))?
 
 Your patch has a few small mistakes. E.g. it reallocates the buffer right
 after it was allocated without any attempt to fill it. The following variant
 is better in my opinion. But anyway, something like it should be OK.
 
 
 --- arp.c	Tue Jan 11 02:00:45 2005
 +++ arp.c	Sun Jan 23 13:40:36 2005
 @@ -456,12 +456,12 @@
  {
  	int mib[6];
  	size_t needed;
 -	char *lim, *buf, *next;
 +	char *lim, *buf, *newbuf, *next;
  	struct rt_msghdr *rtm;
  	struct sockaddr_inarp *sin2;
  	struct sockaddr_dl *sdl;
  	char ifname[IF_NAMESIZE];
 -	int found_entry = 0;
 +	int st, found_entry = 0;
  
  	mib[0] = CTL_NET;
  	mib[1] = PF_ROUTE;
 @@ -473,9 +473,16 @@
  		err(1, "route-sysctl-estimate");
  	if (needed == 0)	/* empty table */
  		return 0;
 -	if ((buf = malloc(needed)) == NULL)
 -		err(1, "malloc");
 -	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
 +	buf = NULL;
 +	do {
 +		needed += needed / 2;
 +		newbuf = realloc(buf, needed);
 +		if (newbuf == NULL)
 +			err(1, "realloc"); /* also free all allocated memory */
 +		buf = newbuf;
 +		st = sysctl(mib, 6, buf, &needed, NULL, 0);
 +	} while (st == -1 && errno == ENOMEM);
 +	if (st == -1)
  		err(1, "actual retrieval of routing table");
  	lim = buf + needed;
  	for (next = buf; next < lim; next += rtm->rtm_msglen) {
Responsible-Changed-From-To: freebsd-bugs->maxim 
Responsible-Changed-By: maxim 
Responsible-Changed-When: Sun Jan 23 11:39:07 GMT 2005 
Responsible-Changed-Why:  
Working on this issue. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=76075 

From: Maxim Konovalov <maxim@macomnet.ru>
To: Dmitrij Tejblum <tejblum@yandex-team.ru>
Cc: bug-followup@freebsd.org
Subject: Re: bin/76075: arp program failures due to ARP table growth
Date: Sun, 23 Jan 2005 14:38:46 +0300 (MSK)

 On Sun, 23 Jan 2005, 11:20-0000, Dmitrij Tejblum wrote:
 
 > The following reply was made to PR bin/76075; it has been noted by GNATS.
 >
 > From: Dmitrij Tejblum <tejblum@yandex-team.ru>
 > To: Maxim Konovalov <maxim@macomnet.ru>
 > Cc: bug-followup@freebsd.org
 > Subject: Re: bin/76075: arp program failures due to ARP table growth
 > Date: Sun, 23 Jan 2005 14:17:16 +0300 (MSK)
 >
 >  > What is your opinion about an enclosed diff (a bit more adaptable
 >  > algorithm stolen from killall(1))?
 >
 >  Your patch has a few small mistakes. E.g. it reallocates the buffer right
 >  after it was allocated without any attempt to fill it. The following variant
 >  is better in my opinion. But anyway, something like it should be OK.
 
 Agreed, will commit shortly.
 
 -- 
 Maxim Konovalov
State-Changed-From-To: open->patched 
State-Changed-By: maxim 
State-Changed-When: Mon Jan 24 13:04:46 GMT 2005 
State-Changed-Why:  
Fixed in HEAD, thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=76075 
State-Changed-From-To: patched->closed 
State-Changed-By: maxim 
State-Changed-When: Sun Feb 13 12:47:07 GMT 2005 
State-Changed-Why:  
Fixed in RELENG_5 and RELENG_4, thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=76075 
>Unformatted:
