lkml.org 
[lkml]   [2019]   [May]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 089/114] xfrm4: Fix uninitialized memory read in _decode_session4
    Date
    [ Upstream commit 8742dc86d0c7a9628117a989c11f04a9b6b898f3 ]

    We currently don't reload pointers pointing into skb header
    after doing pskb_may_pull() in _decode_session4(). So in case
    pskb_may_pull() changed the pointers, we read from random
    memory. Fix this by putting all the needed infos on the
    stack, so that we don't need to access the header pointers
    after doing pskb_may_pull().

    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/ipv4/xfrm4_policy.c | 24 +++++++++++++-----------
    1 file changed, 13 insertions(+), 11 deletions(-)

    diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
    index d73a6d6652f60..2b144b92ae46a 100644
    --- a/net/ipv4/xfrm4_policy.c
    +++ b/net/ipv4/xfrm4_policy.c
    @@ -111,7 +111,8 @@ static void
    _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
    {
    const struct iphdr *iph = ip_hdr(skb);
    - u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
    + int ihl = iph->ihl;
    + u8 *xprth = skb_network_header(skb) + ihl * 4;
    struct flowi4 *fl4 = &fl->u.ip4;
    int oif = 0;

    @@ -122,6 +123,11 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
    fl4->flowi4_mark = skb->mark;
    fl4->flowi4_oif = reverse ? skb->skb_iif : oif;

    + fl4->flowi4_proto = iph->protocol;
    + fl4->daddr = reverse ? iph->saddr : iph->daddr;
    + fl4->saddr = reverse ? iph->daddr : iph->saddr;
    + fl4->flowi4_tos = iph->tos;
    +
    if (!ip_is_fragment(iph)) {
    switch (iph->protocol) {
    case IPPROTO_UDP:
    @@ -133,7 +139,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
    pskb_may_pull(skb, xprth + 4 - skb->data)) {
    __be16 *ports;

    - xprth = skb_network_header(skb) + iph->ihl * 4;
    + xprth = skb_network_header(skb) + ihl * 4;
    ports = (__be16 *)xprth;

    fl4->fl4_sport = ports[!!reverse];
    @@ -146,7 +152,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
    pskb_may_pull(skb, xprth + 2 - skb->data)) {
    u8 *icmp;

    - xprth = skb_network_header(skb) + iph->ihl * 4;
    + xprth = skb_network_header(skb) + ihl * 4;
    icmp = xprth;

    fl4->fl4_icmp_type = icmp[0];
    @@ -159,7 +165,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
    pskb_may_pull(skb, xprth + 4 - skb->data)) {
    __be32 *ehdr;

    - xprth = skb_network_header(skb) + iph->ihl * 4;
    + xprth = skb_network_header(skb) + ihl * 4;
    ehdr = (__be32 *)xprth;

    fl4->fl4_ipsec_spi = ehdr[0];
    @@ -171,7 +177,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
    pskb_may_pull(skb, xprth + 8 - skb->data)) {
    __be32 *ah_hdr;

    - xprth = skb_network_header(skb) + iph->ihl * 4;
    + xprth = skb_network_header(skb) + ihl * 4;
    ah_hdr = (__be32 *)xprth;

    fl4->fl4_ipsec_spi = ah_hdr[1];
    @@ -183,7 +189,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
    pskb_may_pull(skb, xprth + 4 - skb->data)) {
    __be16 *ipcomp_hdr;

    - xprth = skb_network_header(skb) + iph->ihl * 4;
    + xprth = skb_network_header(skb) + ihl * 4;
    ipcomp_hdr = (__be16 *)xprth;

    fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
    @@ -196,7 +202,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
    __be16 *greflags;
    __be32 *gre_hdr;

    - xprth = skb_network_header(skb) + iph->ihl * 4;
    + xprth = skb_network_header(skb) + ihl * 4;
    greflags = (__be16 *)xprth;
    gre_hdr = (__be32 *)xprth;

    @@ -213,10 +219,6 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
    break;
    }
    }
    - fl4->flowi4_proto = iph->protocol;
    - fl4->daddr = reverse ? iph->saddr : iph->daddr;
    - fl4->saddr = reverse ? iph->daddr : iph->saddr;
    - fl4->flowi4_tos = iph->tos;
    }

    static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk,
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-05-23 21:39    [W:2.333 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site