net: ethernet: Drop pkt if MAC dst is bcast address but IP is not

Drop packet if it has broadcast destination MAC address but the IPv4
destination address is not multicast or broadcast address.
See RFC 1122 ch 3.3.6 for details.

Fixes #16276

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2019-05-21 13:33:23 +03:00
commit 19b48687ec

View file

@ -145,6 +145,23 @@ static inline bool eth_is_vlan_tag_stripped(struct net_if *iface)
return (api->get_capabilities(dev) & ETHERNET_HW_VLAN_TAG_STRIP);
}
/* Drop packet if it has broadcast destination MAC address but the IP
* address is not multicast or broadcast address. See RFC 1122 ch 3.3.6
*/
static inline
enum net_verdict ethernet_check_ipv4_bcast_addr(struct net_pkt *pkt,
struct net_eth_hdr *hdr)
{
if (net_eth_is_addr_broadcast(&hdr->dst) &&
!(net_ipv4_is_addr_mcast(&NET_IPV4_HDR(pkt)->dst) ||
net_ipv4_is_addr_bcast(net_pkt_iface(pkt),
&NET_IPV4_HDR(pkt)->dst))) {
return NET_DROP;
}
return NET_OK;
}
static enum net_verdict ethernet_recv(struct net_if *iface,
struct net_pkt *pkt)
{
@ -240,10 +257,15 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
goto drop;
}
ethernet_update_rx_stats(iface, pkt, net_pkt_get_len(pkt));
net_buf_pull(pkt->frags, hdr_len);
if (IS_ENABLED(CONFIG_NET_IPV4) && type == NET_ETH_PTYPE_IP &&
ethernet_check_ipv4_bcast_addr(pkt, hdr) == NET_DROP) {
goto drop;
}
ethernet_update_rx_stats(iface, pkt, net_pkt_get_len(pkt) + hdr_len);
#ifdef CONFIG_NET_ARP
if (family == AF_INET && type == NET_ETH_PTYPE_ARP) {
NET_DBG("ARP packet from %s received",