lkml.org 
[lkml]   [2012]   [Mar]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 17/38] ipsec: be careful of non existing mac headers
    3.0-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Eric Dumazet <eric.dumazet@gmail.com>

    [ Upstream commit 03606895cd98c0a628b17324fd7b5ff15db7e3cd ]

    Niccolo Belli reported ipsec crashes in case we handle a frame without
    mac header (atm in his case)

    Before copying mac header, better make sure it is present.

    Bugzilla reference: https://bugzilla.kernel.org/show_bug.cgi?id=42809

    Reported-by: Niccolò Belli <darkbasic@linuxsystems.it>
    Tested-by: Niccolò Belli <darkbasic@linuxsystems.it>
    Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    include/linux/skbuff.h | 10 ++++++++++
    net/ipv4/xfrm4_mode_beet.c | 5 +----
    net/ipv4/xfrm4_mode_tunnel.c | 6 ++----
    net/ipv6/xfrm6_mode_beet.c | 6 +-----
    net/ipv6/xfrm6_mode_tunnel.c | 6 ++----
    5 files changed, 16 insertions(+), 17 deletions(-)
    --- a/include/linux/skbuff.h
    +++ b/include/linux/skbuff.h
    @@ -1370,6 +1370,16 @@ static inline void skb_set_mac_header(st
    }
    #endif /* NET_SKBUFF_DATA_USES_OFFSET */

    +static inline void skb_mac_header_rebuild(struct sk_buff *skb)
    +{
    + if (skb_mac_header_was_set(skb)) {
    + const unsigned char *old_mac = skb_mac_header(skb);
    +
    + skb_set_mac_header(skb, -skb->mac_len);
    + memmove(skb_mac_header(skb), old_mac, skb->mac_len);
    + }
    +}
    +
    static inline int skb_checksum_start_offset(const struct sk_buff *skb)
    {
    return skb->csum_start - skb_headroom(skb);
    --- a/net/ipv4/xfrm4_mode_beet.c
    +++ b/net/ipv4/xfrm4_mode_beet.c
    @@ -110,10 +110,7 @@ static int xfrm4_beet_input(struct xfrm_

    skb_push(skb, sizeof(*iph));
    skb_reset_network_header(skb);
    -
    - memmove(skb->data - skb->mac_len, skb_mac_header(skb),
    - skb->mac_len);
    - skb_set_mac_header(skb, -skb->mac_len);
    + skb_mac_header_rebuild(skb);

    xfrm4_beet_make_header(skb);

    --- a/net/ipv4/xfrm4_mode_tunnel.c
    +++ b/net/ipv4/xfrm4_mode_tunnel.c
    @@ -66,7 +66,6 @@ static int xfrm4_mode_tunnel_output(stru

    static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
    {
    - const unsigned char *old_mac;
    int err = -EINVAL;

    if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
    @@ -84,10 +83,9 @@ static int xfrm4_mode_tunnel_input(struc
    if (!(x->props.flags & XFRM_STATE_NOECN))
    ipip_ecn_decapsulate(skb);

    - old_mac = skb_mac_header(skb);
    - skb_set_mac_header(skb, -skb->mac_len);
    - memmove(skb_mac_header(skb), old_mac, skb->mac_len);
    skb_reset_network_header(skb);
    + skb_mac_header_rebuild(skb);
    +
    err = 0;

    out:
    --- a/net/ipv6/xfrm6_mode_beet.c
    +++ b/net/ipv6/xfrm6_mode_beet.c
    @@ -80,7 +80,6 @@ static int xfrm6_beet_output(struct xfrm
    static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
    {
    struct ipv6hdr *ip6h;
    - const unsigned char *old_mac;
    int size = sizeof(struct ipv6hdr);
    int err;

    @@ -90,10 +89,7 @@ static int xfrm6_beet_input(struct xfrm_

    __skb_push(skb, size);
    skb_reset_network_header(skb);
    -
    - old_mac = skb_mac_header(skb);
    - skb_set_mac_header(skb, -skb->mac_len);
    - memmove(skb_mac_header(skb), old_mac, skb->mac_len);
    + skb_mac_header_rebuild(skb);

    xfrm6_beet_make_header(skb);

    --- a/net/ipv6/xfrm6_mode_tunnel.c
    +++ b/net/ipv6/xfrm6_mode_tunnel.c
    @@ -63,7 +63,6 @@ static int xfrm6_mode_tunnel_output(stru
    static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
    {
    int err = -EINVAL;
    - const unsigned char *old_mac;

    if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
    goto out;
    @@ -80,10 +79,9 @@ static int xfrm6_mode_tunnel_input(struc
    if (!(x->props.flags & XFRM_STATE_NOECN))
    ipip6_ecn_decapsulate(skb);

    - old_mac = skb_mac_header(skb);
    - skb_set_mac_header(skb, -skb->mac_len);
    - memmove(skb_mac_header(skb), old_mac, skb->mac_len);
    skb_reset_network_header(skb);
    + skb_mac_header_rebuild(skb);
    +
    err = 0;

    out:

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2012-03-17 00:41    [from the cache]
    ©2003-2011 Jasper Spaans