Date: Fri, 10 Dec 2010 04:49:54 +0800 From: rozhuk.im@gmail.com To: "'Chuck Swiger'" <cswiger@mac.com> Cc: freebsd-net@freebsd.org Subject: RE: [arp] possible DoS, fixes and improvements Message-ID: <4d0140f7.4b02e30a.7efb.7963@mx.google.com> In-Reply-To: <D0DD90EC-F7CE-4704-8167-34CBA4D631B3@mac.com> References: <4cfe88b6.1cedd80a.33f5.119d@mx.google.com> <D0DD90EC-F7CE-4704-8167-34CBA4D631B3@mac.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi! > I wonder which version of netinet/if_ether.c you are working from? uname -a FreeBSD firewall 9.0-CURRENT FreeBSD 9.0-CURRENT #2: Wed Dec 8 02:53:50 IRKT 2010 root@firewall:/usr/obj/usr/src/sys/RIMx64 amd64 =A0 -- Rozhuk Ivan =A0=20 > -----Original Message----- > From: Chuck Swiger [mailto:cswiger@mac.com] > Sent: Wednesday, December 08, 2010 4:54 AM > To: Rozhuk.IM@gmail.com > Cc: freebsd-net@freebsd.org > Subject: Re: [arp] possible DoS, fixes and improvements >=20 > Hi, Rozhuk-- >=20 > On Dec 7, 2010, at 11:19 AM, rozhuk.im@gmail.com wrote: > > Hi! > > > > 1. ah->ar_hln - is depend from ar_hrd? > > Yes, and for ARPHRD_ETHER is 6 (ETHER_ADDR_LEN) > > For ARPHRD_IEEE1394 - sizeof(struct fw_hwaddr) > > ah->ar_hln ignored in ether_output: bcopy(ar_tha(ah), edst, > ETHER_ADDR_LEN); >=20 > If you know that ar_hrd is ARPHRD_ETHER, then you can either assume = the > length is ETHER_ADDR_LEN, or optionally check it, per RFC 826: >=20 > "When an address resolution packet is received, the receiving > Ethernet module gives the packet to the Address Resolution module > which goes through an algorithm similar to the following. > Negative conditionals indicate an end of processing and a > discarding of the packet. >=20 > ?Do I have the hardware type in ar$hrd? > Yes: (almost definitely) > [optionally check the hardware length ar$hln] > ?Do I speak the protocol in ar$pro? > Yes: > [optionally check the protocol length ar$pln]" >=20 > > check in in_arpinput: > > if (ifp->if_addrlen !=3D ah->ar_hln) { > > LLE_WUNLOCK(la); > > log(LOG_WARNING, > > "arp from %*D: addr len: new %d, i/f %d > (ignored)", > > ifp->if_addrlen, (u_char *) ar_sha(ah), ":", > > ah->ar_hln, ifp->if_addrlen); > > goto reply; > > } > > NO DROP!!!! >=20 > I wonder which version of netinet/if_ether.c you are working from? > In 7-STABLE sources, it breaks rather than going to generate a reply: >=20 > if (ifp->if_addrlen !=3D ah->ar_hln) { > log(LOG_WARNING, > "arp from %*D: addr len: " > "new %d, i/f %d (ignored)", > ifp->if_addrlen, (u_char *) > ar_sha(ah), > ":", ah->ar_hln, ifp->if_addrlen); > RT_UNLOCK(rt); > break; > } >=20 > > In reply we get: > > (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); > > (void)memcpy(ar_sha(ah), enaddr, ah->ar_hln); > > Or > > (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); > > (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln); > > > > How to use it see below. > > > > > > 2. ah->ar_pln - does not checked! > > We can make big arp request (512 nulls after struct arphdr + 2*6 + > 2*4) , > > valid for host, set ar_plt =3D 255 > > And in reply will receive part of stack or core panic: > > in_arpinput: > > (void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln); > > ... > > m->m_len =3D sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln); > > ( eq arphdr_len(ah) ) >=20 > I think I agree that this is not being checked for properly.... >=20 > Regards, > -- > -Chuck
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4d0140f7.4b02e30a.7efb.7963>