mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-12-28 00:15:16 +00:00
ipv4/ipv6: restrict loopback-destined traffic
Generally speaking, packets with a loopback destination address - 127.0.0.1 for IPv4 and ::1 for IPv6 - should not be accepted on non-loopback interfaces. For IPv4, this is implied by RFC 1122 Sec. 3.2.1.3. For IPv6, it is mandated by RFC 4291 Sec. 2.5.3. Failure to perform this filtering may have security implications, as applications that bind sockets to loopback addresses may not expect that nodes on the local external network be able to produce traffic that will arrive at such sockets. With this patch, lwIP drops packets that are sent to a loopback address but do not originate from the interface that has the loopback address assigned to it. This approach works regardless of whether it is lwIP or the system using it that implements a loopback netif. The only exception that must be made is for configurations that enable netif packet loopback but disable the lwIP loopback netif: in that case, loopback packets are routed across non-loopback netifs and would thus be lost by the new filter as well. For IPv6, loopback-destined packets are also no longer forwarded; the IPv4 forwarding code already had a check for that. As a small performance improvement, the IPv6 link-local/loopback address check is now performed only once per packet rather than repeatedly for every candidate netif.
This commit is contained in:
parent
4076b12ee9
commit
68ec20fffc
@ -518,6 +518,15 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
#endif /* LWIP_AUTOIP */
|
||||
}
|
||||
if (first) {
|
||||
#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
|
||||
/* Packets sent to the loopback address must not be accepted on an
|
||||
* interface that does not have the loopback address assigned to it,
|
||||
* unless a non-loopback interface is used for loopback traffic. */
|
||||
if (ip4_addr_isloopback(ip4_current_dest_addr())) {
|
||||
netif = NULL;
|
||||
break;
|
||||
}
|
||||
#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
|
||||
first = 0;
|
||||
netif = netif_list;
|
||||
} else {
|
||||
|
@ -292,8 +292,9 @@ ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
|
||||
{
|
||||
struct netif *netif;
|
||||
|
||||
/* do not forward link-local addresses */
|
||||
if (ip6_addr_islinklocal(ip6_current_dest_addr())) {
|
||||
/* do not forward link-local or loopback addresses */
|
||||
if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
|
||||
ip6_addr_isloopback(ip6_current_dest_addr())) {
|
||||
LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
|
||||
IP6_STATS_INC(ip6.rterr);
|
||||
IP6_STATS_INC(ip6.drop);
|
||||
@ -511,12 +512,21 @@ ip6_input(struct pbuf *p, struct netif *inp)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ip6_addr_islinklocal(ip6_current_dest_addr())) {
|
||||
/* Do not match link-local addresses to other netifs. */
|
||||
netif = NULL;
|
||||
break;
|
||||
}
|
||||
if (first) {
|
||||
if (ip6_addr_islinklocal(ip6_current_dest_addr())
|
||||
#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
|
||||
|| ip6_addr_isloopback(ip6_current_dest_addr())
|
||||
#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
|
||||
) {
|
||||
/* Do not match link-local addresses to other netifs. The loopback
|
||||
* address is to be considered link-local and packets to it should be
|
||||
* dropped on other interfaces, as per RFC 4291 Sec. 2.5.3. This
|
||||
* requirement cannot be implemented in the case that loopback
|
||||
* traffic is sent across a non-loopback interface, however.
|
||||
*/
|
||||
netif = NULL;
|
||||
break;
|
||||
}
|
||||
first = 0;
|
||||
netif = netif_list;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user