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.
Unified · Split
| @@ -164,6 +164,7 @@ static void loopback_setup(struct net_device *dev) · 163 unmodified lines | ||
| 164 | 164 | { |
| 165 | 165 | dev->mtu = 64 * 1024; |
| 166 | 166 | dev->hard_header_len = ETH_HLEN; /* 14 */ |
| 167 | + dev->min_header_len = ETH_HLEN; /* 14 */ | |
| 167 | 168 | dev->addr_len = ETH_ALEN; /* 6 */ |
| 168 | 169 | dev->type = ARPHRD_LOOPBACK; /* 0x0001*/ |
| 169 | 170 | dev->flags = IFF_LOOPBACK; |
| @@ -1511,6 +1511,7 @@ enum netdev_priv_flags { · 1510 unmodified lines | ||
| 1511 | 1511 | * @max_mtu: Interface Maximum MTU value |
| 1512 | 1512 | * @type: Interface hardware type |
| 1513 | 1513 | * @hard_header_len: Maximum hardware header length. |
| 1514 | + * @min_header_len: Minimum hardware header length | |
| 1514 | 1515 | * |
| 1515 | 1516 | * @needed_headroom: Extra headroom the hardware may need, but not in all |
| 1516 | 1517 | * cases can this be guaranteed |
| @@ -1728,6 +1729,7 @@ struct net_device { · 211 unmodified lines | ||
| 1728 | 1729 | unsigned int max_mtu; |
| 1729 | 1730 | unsigned short type; |
| 1730 | 1731 | unsigned short hard_header_len; |
| 1732 | + unsigned short min_header_len; | |
| 1731 | 1733 | |
| 1732 | 1734 | unsigned short needed_headroom; |
| 1733 | 1735 | unsigned short needed_tailroom; |
| @@ -2694,6 +2696,8 @@ static inline bool dev_validate_header(const struct net_device *dev, · 960 unmodified lines | ||
| 2694 | 2696 | { |
| 2695 | 2697 | if (likely(len >= dev->hard_header_len)) |
| 2696 | 2698 | return true; |
| 2699 | + if (len < dev->min_header_len) | |
| 2700 | + return false; | |
| 2697 | 2701 | |
| 2698 | 2702 | if (capable(CAP_SYS_RAWIO)) { |
| 2699 | 2703 | memset(ll_header + len, 0, dev->hard_header_len - len); |
| @@ -356,6 +356,7 @@ void ether_setup(struct net_device *dev) · 355 unmodified lines | ||
| 356 | 356 | dev->header_ops = ð_header_ops; |
| 357 | 357 | dev->type = ARPHRD_ETHER; |
| 358 | 358 | dev->hard_header_len = ETH_HLEN; |
| 359 | + dev->min_header_len = ETH_HLEN; | |
| 359 | 360 | dev->mtu = ETH_DATA_LEN; |
| 360 | 361 | dev->min_mtu = ETH_MIN_MTU; |
| 361 | 362 | dev->max_mtu = ETH_DATA_LEN; |