Commit 9d3925d7 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Greg Kroah-Hartman

bridge-netfilter: don't overwrite memory outside of skb

The bridge netfilter code needs to check for space at the
front of the skb before overwriting; otherwise if skb from
device doesn't have headroom, then it will cause random
memory corruption.
Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7cadd43d
...@@ -47,18 +47,26 @@ enum nf_br_hook_priorities { ...@@ -47,18 +47,26 @@ enum nf_br_hook_priorities {
#define BRNF_BRIDGED 0x08 #define BRNF_BRIDGED 0x08
#define BRNF_NF_BRIDGE_PREROUTING 0x10 #define BRNF_NF_BRIDGE_PREROUTING 0x10
/* Only used in br_forward.c */ /* Only used in br_forward.c */
static inline static inline int nf_bridge_maybe_copy_header(struct sk_buff *skb)
void nf_bridge_maybe_copy_header(struct sk_buff *skb)
{ {
int err;
if (skb->nf_bridge) { if (skb->nf_bridge) {
if (skb->protocol == __constant_htons(ETH_P_8021Q)) { if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
err = skb_cow(skb, 18);
if (err)
return err;
memcpy(skb->data - 18, skb->nf_bridge->data, 18); memcpy(skb->data - 18, skb->nf_bridge->data, 18);
skb_push(skb, 4); skb_push(skb, 4);
} else } else {
err = skb_cow(skb, 16);
if (err)
return err;
memcpy(skb->data - 16, skb->nf_bridge->data, 16); memcpy(skb->data - 16, skb->nf_bridge->data, 16);
} }
}
return 0;
} }
/* This is called by the IP fragmenting code and it ensures there is /* This is called by the IP fragmenting code and it ensures there is
......
...@@ -43,12 +43,16 @@ int br_dev_queue_push_xmit(struct sk_buff *skb) ...@@ -43,12 +43,16 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
else { else {
#ifdef CONFIG_BRIDGE_NETFILTER #ifdef CONFIG_BRIDGE_NETFILTER
/* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
nf_bridge_maybe_copy_header(skb); if (nf_bridge_maybe_copy_header(skb))
kfree_skb(skb);
else
#endif #endif
{
skb_push(skb, ETH_HLEN); skb_push(skb, ETH_HLEN);
dev_queue_xmit(skb); dev_queue_xmit(skb);
} }
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment