]> git.karo-electronics.de Git - linux-beck.git/commitdiff
net: introduce device min_header_len
authorWillem de Bruijn <willemb@google.com>
Tue, 7 Feb 2017 20:57:20 +0000 (15:57 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 18 Feb 2017 14:11:43 +0000 (15:11 +0100)
[ Upstream commit 217e6fa24ce28ec87fca8da93c9016cb78028612 ]

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: 9ed988cd5915 ("packet: validate variable length ll headers")
Reported-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: Willem de Bruijn <willemb@google.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Acked-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/loopback.c
include/linux/netdevice.h
net/ethernet/eth.c

index 6255973e3dda35fd41464ce51f0f9fb9f0b8364b..1b65f0f975cfb2167faf741ba04dd45768f2ff12 100644 (file)
@@ -164,6 +164,7 @@ static void loopback_setup(struct net_device *dev)
 {
        dev->mtu                = 64 * 1024;
        dev->hard_header_len    = ETH_HLEN;     /* 14   */
+       dev->min_header_len     = ETH_HLEN;     /* 14   */
        dev->addr_len           = ETH_ALEN;     /* 6    */
        dev->type               = ARPHRD_LOOPBACK;      /* 0x0001*/
        dev->flags              = IFF_LOOPBACK;
index d83590ef74a15ec6c5526c2130a6ec4cec7b8010..bb9b102c15cdc8b9538c12c6cac830e481f5ec29 100644 (file)
@@ -1508,6 +1508,7 @@ enum netdev_priv_flags {
  *     @mtu:           Interface MTU value
  *     @type:          Interface hardware type
  *     @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
  *                       cases can this be guaranteed
@@ -1728,6 +1729,7 @@ struct net_device {
        unsigned int            mtu;
        unsigned short          type;
        unsigned short          hard_header_len;
+       unsigned short          min_header_len;
 
        unsigned short          needed_headroom;
        unsigned short          needed_tailroom;
@@ -2783,6 +2785,8 @@ static inline bool dev_validate_header(const struct net_device *dev,
 {
        if (likely(len >= dev->hard_header_len))
                return true;
+       if (len < dev->min_header_len)
+               return false;
 
        if (capable(CAP_SYS_RAWIO)) {
                memset(ll_header + len, 0, dev->hard_header_len - len);
index 02acfff36028bfc3260d7568881bb412be312d27..24d7aff8db1ac8afda0d8537fe0b84fe316bde06 100644 (file)
@@ -356,6 +356,7 @@ void ether_setup(struct net_device *dev)
        dev->header_ops         = &eth_header_ops;
        dev->type               = ARPHRD_ETHER;
        dev->hard_header_len    = ETH_HLEN;
+       dev->min_header_len     = ETH_HLEN;
        dev->mtu                = ETH_DATA_LEN;
        dev->addr_len           = ETH_ALEN;
        dev->tx_queue_len       = 1000; /* Ethernet wants good queues */