Skip to content

Commit

Permalink
xfrm4: Fix header checks in _decode_session4.
Browse files Browse the repository at this point in the history
We skip the header informations if the data pointer points
already behind the header in question for some protocols.
This is because we call pskb_may_pull with a negative value
converted to unsigened int from pskb_may_pull in this case.
Skipping the header informations can lead to incorrect policy
lookups, so fix it by a check of the data pointer position
before we call pskb_may_pull.

Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
  • Loading branch information
klassert committed Oct 23, 2015
1 parent e33d4f1 commit 1a14f1e
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions net/ipv4/xfrm4_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
break;

case IPPROTO_ICMP:
if (pskb_may_pull(skb, xprth + 2 - skb->data)) {
if (xprth + 2 < skb->data ||
pskb_may_pull(skb, xprth + 2 - skb->data)) {
u8 *icmp = xprth;

fl4->fl4_icmp_type = icmp[0];
Expand All @@ -146,31 +147,35 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
break;

case IPPROTO_ESP:
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
if (xprth + 4 < skb->data ||
pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be32 *ehdr = (__be32 *)xprth;

fl4->fl4_ipsec_spi = ehdr[0];
}
break;

case IPPROTO_AH:
if (pskb_may_pull(skb, xprth + 8 - skb->data)) {
if (xprth + 8 < skb->data ||
pskb_may_pull(skb, xprth + 8 - skb->data)) {
__be32 *ah_hdr = (__be32 *)xprth;

fl4->fl4_ipsec_spi = ah_hdr[1];
}
break;

case IPPROTO_COMP:
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
if (xprth + 4 < skb->data ||
pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ipcomp_hdr = (__be16 *)xprth;

fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
}
break;

case IPPROTO_GRE:
if (pskb_may_pull(skb, xprth + 12 - skb->data)) {
if (xprth + 12 < skb->data ||
pskb_may_pull(skb, xprth + 12 - skb->data)) {
__be16 *greflags = (__be16 *)xprth;
__be32 *gre_hdr = (__be32 *)xprth;

Expand Down

0 comments on commit 1a14f1e

Please sign in to comment.