lkml.org 
[lkml]   [2015]   [Feb]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.12 076/122] ip: zero sockaddr returned on error queue
    Date
    From: Willem de Bruijn <willemb@google.com>

    3.12-stable review patch. If anyone has any objections, please let me know.

    ===============

    [ Upstream commit f812116b174e59a350acc8e4856213a166a91222 ]

    The sockaddr is returned in IP(V6)_RECVERR as part of errhdr. That
    structure is defined and allocated on the stack as

    struct {
    struct sock_extended_err ee;
    struct sockaddr_in(6) offender;
    } errhdr;

    The second part is only initialized for certain SO_EE_ORIGIN values.
    Always initialize it completely.

    An MTU exceeded error on a SOCK_RAW/IPPROTO_RAW is one example that
    would return uninitialized bytes.

    Signed-off-by: Willem de Bruijn <willemb@google.com>

    ----

    Also verified that there is no padding between errhdr.ee and
    errhdr.offender that could leak additional kernel data.
    Acked-by: Eric Dumazet <edumazet@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Jiri Slaby <jslaby@suse.cz>
    ---
    net/ipv4/ip_sockglue.c | 8 ++------
    net/ipv6/datagram.c | 10 +++-------
    2 files changed, 5 insertions(+), 13 deletions(-)

    diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
    index 23e6ab0a2dc0..f6603142cb33 100644
    --- a/net/ipv4/ip_sockglue.c
    +++ b/net/ipv4/ip_sockglue.c
    @@ -410,15 +410,11 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)

    memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
    sin = &errhdr.offender;
    - sin->sin_family = AF_UNSPEC;
    + memset(sin, 0, sizeof(*sin));
    if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP) {
    - struct inet_sock *inet = inet_sk(sk);
    -
    sin->sin_family = AF_INET;
    sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
    - sin->sin_port = 0;
    - memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
    - if (inet->cmsg_flags)
    + if (inet_sk(sk)->cmsg_flags)
    ip_cmsg_recv(msg, skb);
    }

    diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
    index c66c6df6e881..9f9ad99fcfdd 100644
    --- a/net/ipv6/datagram.c
    +++ b/net/ipv6/datagram.c
    @@ -374,11 +374,10 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)

    memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
    sin = &errhdr.offender;
    - sin->sin6_family = AF_UNSPEC;
    + memset(sin, 0, sizeof(*sin));
    +
    if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
    sin->sin6_family = AF_INET6;
    - sin->sin6_flowinfo = 0;
    - sin->sin6_port = 0;
    if (skb->protocol == htons(ETH_P_IPV6)) {
    sin->sin6_addr = ipv6_hdr(skb)->saddr;
    if (np->rxopt.all)
    @@ -387,12 +386,9 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
    ipv6_iface_scope_id(&sin->sin6_addr,
    IP6CB(skb)->iif);
    } else {
    - struct inet_sock *inet = inet_sk(sk);
    -
    ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr,
    &sin->sin6_addr);
    - sin->sin6_scope_id = 0;
    - if (inet->cmsg_flags)
    + if (inet_sk(sk)->cmsg_flags)
    ip_cmsg_recv(msg, skb);
    }
    }
    --
    2.2.2


    \
     
     \ /
      Last update: 2015-02-17 13:01    [W:4.069 / U:0.292 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site