Merge branch 'net-header-length-truncation'
Willem de Bruijn says: ==================== net: Fixes for header length truncation Packets should not enter the stack with truncated link layer headers and link layer headers should always be stored in the skb linear segment. Patch 1 ensures the first for PF_PACKET sockets Patch 2 ensures the second for PF_PACKET GSO sockets without tx_ring ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
9538132a9f
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -356,6 +356,7 @@ void ether_setup(struct net_device *dev)
|
||||||
dev->header_ops = ð_header_ops;
|
dev->header_ops = ð_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;
|
||||||
|
|
|
@ -2755,7 +2755,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
|
||||||
struct virtio_net_hdr vnet_hdr = { 0 };
|
struct virtio_net_hdr vnet_hdr = { 0 };
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
struct packet_sock *po = pkt_sk(sk);
|
struct packet_sock *po = pkt_sk(sk);
|
||||||
int hlen, tlen;
|
int hlen, tlen, linear;
|
||||||
int extra_len = 0;
|
int extra_len = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2816,8 +2816,9 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
|
||||||
err = -ENOBUFS;
|
err = -ENOBUFS;
|
||||||
hlen = LL_RESERVED_SPACE(dev);
|
hlen = LL_RESERVED_SPACE(dev);
|
||||||
tlen = dev->needed_tailroom;
|
tlen = dev->needed_tailroom;
|
||||||
skb = packet_alloc_skb(sk, hlen + tlen, hlen, len,
|
linear = __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len);
|
||||||
__virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len),
|
linear = max(linear, min_t(int, len, dev->hard_header_len));
|
||||||
|
skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, linear,
|
||||||
msg->msg_flags & MSG_DONTWAIT, &err);
|
msg->msg_flags & MSG_DONTWAIT, &err);
|
||||||
if (skb == NULL)
|
if (skb == NULL)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
Loading…
Reference in New Issue