[arp] possible DoS, fixes and improvements

rozhuk.im at gmail.com rozhuk.im at gmail.com
Tue Dec 7 19:19:21 UTC 2010


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);

check in in_arpinput:
		if (ifp->if_addrlen != 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!!!!
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 = 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 = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
( eq arphdr_len(ah) )



3. ar_sha(ah) - does not checked for multicast!
Answers to request my be send to multicast addrs
Only broadcast and host addr are checked.
No check is ar_sha(ah) equal to Ethernet.ether_shost
As result:
arp -an
? (172.16.0.2) at 01:80:c2:00:00:01 on em0 expires in 118 seconds [ethernet]



4. holded packet my be sended without any locks

Current:
		if (la->la_hold != NULL) {
			struct mbuf *m_hold, *m_hold_next;

			bcopy(L3_ADDR(la), &sa, sizeof(sa));
			LLE_WUNLOCK(la);
			for (m_hold = la->la_hold, la->la_hold = NULL;
			     m_hold != NULL; m_hold = m_hold_next) {
				m_hold_next = m_hold->m_nextpkt;
				m_hold->m_nextpkt = NULL;
				(*ifp->if_output)(ifp, m_hold, &sa, NULL);
			}
		} else
			LLE_WUNLOCK(la);
		la->la_hold = NULL;
		la->la_numheld = 0;

Here we unlock la and then modify them - this is bad idea!
Patched - see in attached patch.


This sample will work only for Ethernet without locks
if_output -> call arplookup again for every packet for sa_family = AF_INET
AF_UNSPEC - just copy ether_type/arc_type/... and L2 addr from dst->sa_data

		struct mbuf *m_hold, *m_hold_next;
		struct sockaddr dst;

		m_hold = la->la_hold;
		if (m_hold != NULL) {
			dst.sa_len = sizeof(dst);
			dst.sa_family = AF_UNSPEC;	/* prevent call
arpresolve, we know L2 addr dst */

			switch (ntohs(ah->ar_hrd)){
			case ARPHRD_ETHER:
				((struct
ether_header*)&dst.sa_data)->ether_type = ah->ar_pro;
				bcopy(ar_sha(ah), ((struct
ether_header*)&dst.sa_data)->ether_dhost, ah->ar_hln);
				break;
			//case ARPHRD_IEEE802:
			//	break;
			//case ARPHRD_ARCNET:
			//	((struct arc_header
*)&dst.sa_data)->arc_type = ah->ar_pro;
			//	bcopy(ar_sha(ah), ((struct arc_header
*)&dst.sa_data)->arc_dhost, ah->ar_hln);
			//	break;
			//case ARPHRD_FRELAY:
			//	break;
			//case ARPHRD_IEEE1394:
			//	break;
			default:
				bcopy(L3_ADDR(la), &dst, sizeof(dst));
			}
		}
		la->la_hold = NULL;
		la->la_numheld = 0;

		LLE_WUNLOCK(la);

		for (; m_hold != NULL; m_hold = m_hold_next) {
			m_hold_next = m_hold->m_nextpkt;
			m_hold->m_nextpkt = NULL;
			(*ifp->if_output)(ifp, m_hold, &dst, NULL);
		}

Do I need include this improvement in next patch?


Will attached patch included in mainstream code?



PS: patch contain fixes and some code cleanup and improvements.
Only basics tests done, not tested in production.


PPS: tests for 1 and 2
Part of code to generate arp packet

	struct arphdr *ah;
	u_char buff[2048];
	u_int32_t src, dst;

	bzero(buff, sizeof(buff));
	ah = (struct arphdr *)buff;

	src = INET_ADDR(172,16,0,2);
	dst = INET_ADDR(172,16,0,254);// - target!

	ah->ar_hrd = htons(ARPHRD_ETHER);
	ah->ar_pro = htons(ETHERTYPE_IP);
	ah->ar_op = htons(ARPOP_REQUEST);
	ah->ar_hln = 255;//ETHER_ADDR_LEN;
	ah->ar_pln = 255;//INET_ADDR_LEN;
	ETHER_ADDR_COPY(ar_sha(ah), ether_shost);
	INET_ADDR_COPY(ar_spa(ah), &src);
	INET_ADDR_COPY(ar_tpa(ah), &dst);

send_ether(bpf, ether_dhost, ether_shost, ETHERTYPE_ARP, (u_char*)ah, 1200);

returned answer is 1042 bytes size, no core panic
tested on my home freebsd box (i386, 8.2 @ E5300), with custom kernel


0x0030 x 0000 0000 0018 0000 0000 0000 00ff ffff x ................
0x0040 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0050 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0060 x 0000 0000 0000 0000 0000 0000 0000 6a2f x ..............j/
0x0070 x c5a0 522f c580 552f c500 412f c500 0008 x ..R/..U/..A/....
0x0080 x f100 0000 f101 b000 0000 000a f100 0000 x ................
0x0090 x 0000 0000 0000 0000 0086 801f a086 80d3 x ................
0x00A0 x 1007 0010 0002 0000 0000 0801 1100 0000 x ................
0x00B0 x 0006 0000 0000 0000 0002 0000 0022 c8cc x ............."..
0x00C0 x cecf 0000 0000 0000 0000 0000 0000 0000 x ................
0x00D0 x 0000 0000 0000 0000 0000 0000 0080 00d0 x ................
0x00E0 x 0100 0000 0000 0000 0000 0000 0000 0000 x ................
0x00F0 x 0000 0000 0004 8005 00a0 1c1c 0000 0000 x ................
0x0100 x 0000 2000 0003 00ac 1000 feac 1000 0210 x ................
0x0110 x 0200 00ac 1000 0200 0000 0000 0000 00a0 x ................
0x0120 x 3520 c570 3820 c5a0 3520 c5a0 3520 c502 x 5..p8...5...5...
0x0130 x e249 fb00 0000 0000 8121 c900 58c2 c07c x .I.......!..X..|
0x0140 x 7cdb c4ea 6856 c000 8121 c9c0 066c c001 x |...hV...!...l..
0x0150 x 0000 0002 0000 0060 7cdb c4a0 3520 c5a0 x .......`|...5...
0x0160 x 3520 c5c4 0000 007f ffff ff80 0000 00cc x 5...............
0x0170 x 59c2 c001 0000 0007 0000 00c0 c31e c500 x Y...............
0x0180 x 5e1c c5a0 3520 c5ac 7cdb c49e 0d49 c000 x ^...5...|....I..
0x0190 x 58c2 c0ec e64b c000 0000 0009 0100 0047 x X....K.........G
0x01A0 x d152 e8a0 3520 c500 0000 0000 5e1c c530 x .R..5.......^..0
0x01B0 x d11e c5a0 3520 c5dc 7cdb c43e 2649 c0a0 x ....5...|..>&I..
0x01C0 x 1a20 c500 5e1c c57d c565 c02d 0500 0070 x ....^..}.e.-...p
0x01D0 x 5e1c c56c 5e1c c5a0 1a20 c530 d11e c5a0 x ^..l^......0....
0x01E0 x 3520 c500 0000 0014 7ddb c4fd e948 c030 x 5.......}....H.0
0x01F0 x d11e c528 7ddb c400 0000 0000 0000 0000 x ...(}...........
0x0200 x 0000 0000 0000 001d 0ff2 4b4a 0000 0000 x ..........KJ....
0x0210 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0220 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0230 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0240 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0250 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0260 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0270 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0280 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0290 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x02A0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x02B0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x02C0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x02D0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x02E0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x02F0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0300 x 0000 0000 00ac 1000 0200 0000 0000 0000 x ................
0x0310 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0320 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0330 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0340 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0350 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0360 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0370 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0380 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0390 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x03A0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x03B0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x03C0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x03D0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x03E0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x03F0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0400 x 0000 0000                               x ....




ah->ar_hln = ETHER_ADDR_LEN; // = 6
ah->ar_pln = 255;//INET_ADDR_LEN;

0x0000 x 0001 0800 06ff 0002 001b 214f f5b3 ac10 x ..........!O....
0x0010 x 00fe ac10 0002 1002 0000 ac10 0002 0000 x ................
0x0020 x 0000 0000 0000 a035 20c5 0000 0000 a035 x .......5.......5
0x0030 x 20c5 a035 20c5 02e2 49fb 0000 0000 00c4 x ...5....I.......
0x0040 x 26c9 0058 c2c0 7c7c dbc4 ea68 56c0 00c4 x &..X..||...hV...
0x0050 x 26c9 c006 6cc0 0100 0000 0200 0000 607c x &...l.........`|
0x0060 x dbc4 a035 20c5 a035 20c5 c400 0000 7fff x ...5...5........
0x0070 x ffff 8000 0000 cc59 c2c0 0100 0000 0700 x .......Y........
0x0080 x 0000 c0c3 1ec5 005e 1cc5 a035 20c5 ac7c x .......^...5...|
0x0090 x dbc4 9e0d 49c0 0058 c2c0 ece6 4bc0 0000 x ....I..X....K...
0x00A0 x 0000 0901 0000 dedc 6b6f a035 20c5 0000 x ........ko.5....
0x00B0 x 0000 005e 1cc5 30d1 1ec5 a035 20c5 dc7c x ...^..0....5...|
0x00C0 x dbc4 3e26 49c0 a01a 20c5 005e 1cc5 7dc5 x ..>&I......^..}.
0x00D0 x 65c0 2d05 0000 705e 1cc5 6c5e 1cc5 a01a x e.-...p^..l^....
0x00E0 x 20c5 30d1 1ec5 a035 20c5 0000 0000 147d x ..0....5.......}
0x00F0 x dbc4 fde9 48c0 30d1 1ec5 287d dbc4 0000 x ....H.0...(}....
0x0100 x 0000 0000 0000 0000 0000 0000 0000 1d0f x ................
0x0110 x f24b 4aac 1000 0200 0000 0000 0000 0000 x .KJ.............
0x0120 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0130 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0140 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0150 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0160 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0170 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0180 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0190 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x01A0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x01B0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x01C0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x01D0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x01E0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x01F0 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0200 x 0000 0000 0000 0000 0000 0000 0000 0000 x ................
0x0210 x 0000                                    x ..


 
--
Rozhuk Ivan
  


-------------- next part --------------
A non-text attachment was scrubbed...
Name: if_ether.patch
Type: application/octet-stream
Size: 8834 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-net/attachments/20101207/779cdb0a/if_ether.obj


More information about the freebsd-net mailing list