Skip to content

Commit

Permalink
Potential fix for vrouter kernel module crash due to skbuf corruption
Browse files Browse the repository at this point in the history
Support IPv6 MSS adjust, fixing pulllen and header refresh after skb_may_pull

Change-Id: Ibd9d1383d338a43e3fdb315471c7b3bcb78a130f
  • Loading branch information
prabix76 committed Oct 16, 2014
1 parent 350af1e commit 4224f76
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions linux/vrouter_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ static int
lh_pkt_from_vm_tcp_mss_adj(struct vr_packet *pkt, unsigned short overlay_len)
{
struct sk_buff *skb = vp_os_packet(pkt);
int hlen, pull_len, proto;
int hlen, pull_len, proto, opt_len = 0;
struct vr_ip *iph;
struct vr_ip6 *ip6h;
struct tcphdr *tcph;
Expand All @@ -785,10 +785,23 @@ lh_pkt_from_vm_tcp_mss_adj(struct vr_packet *pkt, unsigned short overlay_len)

pull_len = pkt->vp_data - (skb_headroom(skb));

/* Pull in ipv4 header-length */
pull_len += sizeof(struct vr_ip);

if (!pskb_may_pull(skb, pull_len)) {
return VP_DROP_PULL;
}

iph = (struct vr_ip *) (skb->head + pkt->vp_data);

if (vr_ip_is_ip6(iph)) {

ip6h = (struct vr_ip6 *)iph;
pull_len += sizeof(struct vr_ip6);
pull_len += (sizeof(struct vr_ip6) - sizeof(struct vr_ip));
if (!pskb_may_pull(skb, pull_len)) {
return VP_DROP_PULL;
}

ip6h = (struct vr_ip6 *) (skb->head + pkt->vp_data);
proto = ip6h->ip6_nxt;
hlen = sizeof(struct vr_ip6);
} else {
Expand All @@ -799,25 +812,22 @@ lh_pkt_from_vm_tcp_mss_adj(struct vr_packet *pkt, unsigned short overlay_len)
goto out;
}

pull_len += sizeof(struct vr_ip);
proto = iph->ip_proto;
hlen = iph->ip_hl * 4;
}

if (!pskb_may_pull(skb, pull_len)) {
return VP_DROP_PULL;
opt_len = hlen - sizeof(struct vr_ip);
}

if (proto != VR_IP_PROTO_TCP) {
goto out;
}

pull_len += sizeof(struct tcphdr);
pull_len += sizeof(struct tcphdr) + opt_len;

if (!pskb_may_pull(skb, pull_len)) {
return VP_DROP_PULL;
}

iph = (struct vr_ip *) (skb->head + pkt->vp_data);
tcph = (struct tcphdr *) ((char *) iph + hlen);

if ((tcph->doff << 2) <= (sizeof(struct tcphdr))) {
Expand All @@ -833,6 +843,9 @@ lh_pkt_from_vm_tcp_mss_adj(struct vr_packet *pkt, unsigned short overlay_len)
return VP_DROP_PULL;
}

iph = (struct vr_ip *) (skb->head + pkt->vp_data);
tcph = (struct tcphdr *) ((char *) iph + hlen);

lh_adjust_tcp_mss(tcph, skb, overlay_len, hlen);

out:
Expand Down

0 comments on commit 4224f76

Please sign in to comment.