Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 217e6fa2 authored by Willem de Bruijn's avatar Willem de Bruijn Committed by David S. Miller
Browse files

net: introduce device min_header_len



The stack must not pass packets to device drivers that are shorter
than the minimum link layer header length.

Previously, packet sockets would drop packets smaller than or equal
to dev->hard_header_len, but this has false positives. Zero length
payload is used over Ethernet. Other link layer protocols support
variable length headers. Support for validation of these protocols
removed the min length check for all protocols.

Introduce an explicit dev->min_header_len parameter and drop all
packets below this value. Initially, set it to non-zero only for
Ethernet and loopback. Other protocols can follow in a patch to
net-next.

Fixes: 9ed988cd ("packet: validate variable length ll headers")
Reported-by: default avatarSowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: default avatarWillem de Bruijn <willemb@google.com>
Acked-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarSowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d7426c69
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -164,6 +164,7 @@ static void loopback_setup(struct net_device *dev)
{
{
	dev->mtu		= 64 * 1024;
	dev->mtu		= 64 * 1024;
	dev->hard_header_len	= ETH_HLEN;	/* 14	*/
	dev->hard_header_len	= ETH_HLEN;	/* 14	*/
	dev->min_header_len	= ETH_HLEN;	/* 14	*/
	dev->addr_len		= ETH_ALEN;	/* 6	*/
	dev->addr_len		= ETH_ALEN;	/* 6	*/
	dev->type		= ARPHRD_LOOPBACK;	/* 0x0001*/
	dev->type		= ARPHRD_LOOPBACK;	/* 0x0001*/
	dev->flags		= IFF_LOOPBACK;
	dev->flags		= IFF_LOOPBACK;
+4 −0
Original line number Original line Diff line number Diff line
@@ -1511,6 +1511,7 @@ enum netdev_priv_flags {
 *	@max_mtu:	Interface Maximum MTU value
 *	@max_mtu:	Interface Maximum MTU value
 *	@type:		Interface hardware type
 *	@type:		Interface hardware type
 *	@hard_header_len: Maximum hardware header length.
 *	@hard_header_len: Maximum hardware header length.
 *	@min_header_len:  Minimum hardware header length
 *
 *
 *	@needed_headroom: Extra headroom the hardware may need, but not in all
 *	@needed_headroom: Extra headroom the hardware may need, but not in all
 *			  cases can this be guaranteed
 *			  cases can this be guaranteed
@@ -1728,6 +1729,7 @@ struct net_device {
	unsigned int		max_mtu;
	unsigned int		max_mtu;
	unsigned short		type;
	unsigned short		type;
	unsigned short		hard_header_len;
	unsigned short		hard_header_len;
	unsigned short		min_header_len;


	unsigned short		needed_headroom;
	unsigned short		needed_headroom;
	unsigned short		needed_tailroom;
	unsigned short		needed_tailroom;
@@ -2694,6 +2696,8 @@ static inline bool dev_validate_header(const struct net_device *dev,
{
{
	if (likely(len >= dev->hard_header_len))
	if (likely(len >= dev->hard_header_len))
		return true;
		return true;
	if (len < dev->min_header_len)
		return false;


	if (capable(CAP_SYS_RAWIO)) {
	if (capable(CAP_SYS_RAWIO)) {
		memset(ll_header + len, 0, dev->hard_header_len - len);
		memset(ll_header + len, 0, dev->hard_header_len - len);
+1 −0
Original line number Original line Diff line number Diff line
@@ -356,6 +356,7 @@ void ether_setup(struct net_device *dev)
	dev->header_ops		= &eth_header_ops;
	dev->header_ops		= &eth_header_ops;
	dev->type		= ARPHRD_ETHER;
	dev->type		= ARPHRD_ETHER;
	dev->hard_header_len 	= ETH_HLEN;
	dev->hard_header_len 	= ETH_HLEN;
	dev->min_header_len	= ETH_HLEN;
	dev->mtu		= ETH_DATA_LEN;
	dev->mtu		= ETH_DATA_LEN;
	dev->min_mtu		= ETH_MIN_MTU;
	dev->min_mtu		= ETH_MIN_MTU;
	dev->max_mtu		= ETH_DATA_LEN;
	dev->max_mtu		= ETH_DATA_LEN;