From owner-freebsd-bugs Fri Mar 10 23:20: 9 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id C4AB737B794 for ; Fri, 10 Mar 2000 23:20:01 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id XAA56129; Fri, 10 Mar 2000 23:20:01 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from modemcable127.61-201-24.mtl.mc.videotron.net (modemcable127.61-201-24.mtl.mc.videotron.net [24.201.61.127]) by hub.freebsd.org (Postfix) with SMTP id 2F05F37B5CB for ; Fri, 10 Mar 2000 23:14:26 -0800 (PST) (envelope-from patrick@mindstep.com) Received: (qmail 26795 invoked by alias); 11 Mar 2000 07:14:17 -0000 Received: (qmail 26790 invoked by uid 1002); 11 Mar 2000 07:14:15 -0000 Message-Id: <20000311071415.26789.qmail@modemcable127.61-201-24.mtl.mc.videotron.net> Date: 11 Mar 2000 07:14:15 -0000 From: patrick@mindstep.com Reply-To: patrick@mindstep.com To: freefall-gnats@mindstep.com X-Send-Pr-Version: 3.2 Subject: kern/17311: bug in the code handling ioctl SIOCGIFCONF Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 17311 >Category: kern >Synopsis: bug in the code handling ioctl SIOCGIFCONF >Confidential: no >Severity: critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Mar 10 23:20:01 PST 2000 >Closed-Date: >Last-Modified: >Originator: Patrick Bihan-Faou >Release: FreeBSD 3.4-STABLE i386 >Organization: MindStep Corporation >Environment: FreeBSD 3.4-STABLE and FreeBSD 4.0-CURRENT >Description: When invoked with a small buffer size, the ioctl SIOCGIFCONF may return more information than can fit in the provided buffer. This problem has been partially fixed in FreeBSD 4.0 (if.c rev 1.85). It does not write outside the boundary of the provided buffer but the returned buffer size is incorrect. This in turn can lead to problems in the calling code. This only happens if the system has interfaces for which sa->sa_len is greater than sizeof(*sa), which is the case with most non-IPv4 addresses... This problem has been noted in PR kern/12996 and PR kern/14457 without a good fix yet. >How-To-Repeat: The following piece of code will show the problem. #include #include #include #include #include #include #include #include #include #define VERBOSE_CHECK check55(char *start,char *end) { int startoff=-1,endoff=0; int off=0,c=0; #ifdef VERBOSE_CHECK printf("%03d\t",off); #endif for(;start=33) { printf("\n%03d\t",off); c=1; } printf("%02x ",*(unsigned char*)start); #endif } printf("\n"); if(startoff>=0) { printf(" ** buffer changed from %d to %d => %d bytes modified **\n",startoff,endoff, endoff - startoff + 1); } } main() { struct ifconf ifc; char *x; struct ifreq *ifr; struct sockaddr_in *sin; int len,ret; int s; char buf[1024]; #define END_TEST 300 if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1; for (len=1;len<=END_TEST;len++) { ifc.ifc_buf = buf; ifc.ifc_len = len; memset(buf,0x55,sizeof(buf)); printf("\n"); printf("[Try with len=%d]\n",len); if ((ret=ioctl(s,SIOCGIFCONF,&ifc)) < 0) { printf(" => ioctl failed (returned %d, errno=%d)\n",ret,errno); } printf(" => ioctl succeeded, pretends it wrote %d bytes\n",ifc.ifc_len); printf("\n"); check55(buf,buf+sizeof(buf)); printf("\n"); } return 0; } >Fix: Fix to apply against the HEAD of the CVS Index: if.c =================================================================== RCS file: /cvs/freebsd/src/sys/net/if.c,v retrieving revision 1.85 diff -u -r1.85 if.c --- if.c 2000/02/28 19:30:25 1.85 +++ if.c 2000/03/10 23:29:50 @@ -1086,11 +1086,9 @@ sizeof (ifr)); ifrp++; } else { - if (space < sa->sa_len - sizeof(*sa)) + if (space < sizeof(ifr) + sa->sa_len - sizeof(*sa)) break; space -= sa->sa_len - sizeof(*sa); - if (space < sizeof (ifr)) - break; error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr.ifr_name)); if (error == 0) Fix to apply against the RELENG_3 branch of the CVS Index: if.c =================================================================== RCS file: /cvs/freebsd/src/sys/net/if.c,v retrieving revision 1.64.2.3 diff -u -r1.64.2.3 if.c --- if.c 2000/01/27 16:54:57 1.64.2.3 +++ if.c 2000/03/10 23:29:31 @@ -861,9 +861,9 @@ sizeof (ifr)); ifrp++; } else { - space -= sa->sa_len - sizeof(*sa); - if (space < sizeof (ifr)) + if (space < sizeof(ifr) + sa->sa_len - sizeof(*sa)) break; + space -= sa->sa_len - sizeof(*sa); error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr.ifr_name)); if (error == 0) This PR should close PR kern/12996 and kern/14457 Patrick Bihan-Faou, Herve Masson MindStep Corporation >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message