From patchwork Wed Apr 12 23:24:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 750197 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3w3Kl14Cssz9sN9 for ; Thu, 13 Apr 2017 09:24:45 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="rGxbvalf"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755528AbdDLXYk (ORCPT ); Wed, 12 Apr 2017 19:24:40 -0400 Received: from mail-qt0-f196.google.com ([209.85.216.196]:36438 "EHLO mail-qt0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755360AbdDLXYi (ORCPT ); Wed, 12 Apr 2017 19:24:38 -0400 Received: by mail-qt0-f196.google.com with SMTP id v3so5881081qtd.3 for ; Wed, 12 Apr 2017 16:24:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=8vfAwA/6WSmsIxDzsGiyEZsRq+ENZhpFXEcAZkE4Fsc=; b=rGxbvalfbtsO/Yk8/VV1fWjHaIn94C2p3YYnv6bTHhoDzyBV9SlAxu6taOmgcA4xu4 ataPLSe5TVnzvyVBYV0P12Fa41166vRCXeVHh7+ju0pOpU+axNoLyMgO55FlDhlyK31E dDBH5Ispa03VlXWBiF2c0Zq/SCkCsJBavgQnIJRLiI0Si8Q/3s6JUZ9ZNo+KxZtUDFP2 mJU/g+Gc0U64atldlV9XkFvGQVg6tdMoVrnUYV0Rh40oRh6vHFz6tmw2jyY8moVAkRtY mLZ/RHmOavm7eDCYEnzRkRIQaIUoZ+Rxl+g040w1wuXO94Lz8rOuV/J5mGCTyET77Du8 Iikw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=8vfAwA/6WSmsIxDzsGiyEZsRq+ENZhpFXEcAZkE4Fsc=; b=jhl04ADHSJzZ5hg30o+lJzXZhaJC780E0IOnZzMgO3cM2BENYuRq56TTapfSiOKi1C 0Wr5td1SZF0lXd+tGdJ+9/bdwfZ1ZH8vsOVng9x99IB9Aj0wIMA7vjZqBkBAPSC5qm1P 5kmoraJbvxVWFcQdjvNX3cI2hN8/tn7bRjX6MB5JCBIvPQbidEVX2T7FDKaal/6IE+fS 700hQmBny6I8n2jlC70MQGlOyf6WcbkKYr7thuRyoSokz9cH7VBQ6sZC25uaAXNs37po zhah9z5yiugZc7JYFt1aB6IqMzKFZBDN1IoRNhsgvI4FC1yn5AfJe+FjflGUHPko6wdm hb5w== X-Gm-Message-State: AN3rC/7vvT+C3IseEYG6eksZwW4GyRVPFLGGDPpbRt6FriXvFQJv78v0 AYbsZJmRssDDrA== X-Received: by 10.200.50.179 with SMTP id z48mr189906qta.194.1492039477675; Wed, 12 Apr 2017 16:24:37 -0700 (PDT) Received: from willemb1.nyc.corp.google.com ([100.101.212.72]) by smtp.gmail.com with ESMTPSA id x33sm7964356qtc.22.2017.04.12.16.24.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 12 Apr 2017 16:24:37 -0700 (PDT) From: Willem de Bruijn To: netdev@vger.kernel.org Cc: andreyknvl@google.com, davem@davemloft.net, eric.dumazet@gmail.com, xiyou.wangcong@gmail.com, Willem de Bruijn Subject: [PATCH net] net-timestamp: avoid use-after-free in ip_recv_error Date: Wed, 12 Apr 2017 19:24:35 -0400 Message-Id: <20170412232435.80455-1-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.12.2.715.g7642488e1d-goog Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Willem de Bruijn Syzkaller reported a use-after-free in ip_recv_error at line info->ipi_ifindex = skb->dev->ifindex; This function is called on dequeue from the error queue, at which point the device pointer may no longer be valid. Save ifindex on enqueue in __skb_complete_tx_timestamp, when the pointer is valid or NULL. Store it in temporary storage skb->cb. It is safe to reference skb->dev here, as called from device drivers or dev_queue_xmit. The exception is when called from tcp_ack_tstamp; in that case it is NULL and ifindex is set to 0 (invalid). Do not return a pktinfo cmsg if ifindex is 0. This maintains the current behavior of not returning a cmsg if skb->dev was NULL. On dequeue, the ipv4 path will cast from sock_exterr_skb to in_pktinfo. Both have ifindex as their first element, so no explicit conversion is needed. This is by design, introduced in commit 0b922b7a829c ("net: original ingress device index in PKTINFO"). For ipv6 ip6_datagram_support_cmsg converts to in6_pktinfo. Fixes: 829ae9d61165 ("net-timestamp: allow reading recv cmsg on errqueue with origin tstamp") Reported-by: Andrey Konovalov Signed-off-by: Willem de Bruijn --- net/core/skbuff.c | 1 + net/ipv4/ip_sockglue.c | 9 ++++----- net/ipv6/datagram.c | 10 +--------- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 9f781092fda9..35c1e2460206 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3807,6 +3807,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb, serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; serr->ee.ee_info = tstype; serr->opt_stats = opt_stats; + serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0; if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) { serr->ee.ee_data = skb_shinfo(skb)->tskey; if (sk->sk_protocol == IPPROTO_TCP && diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ebd953bc5607..35076792caa5 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -488,16 +488,15 @@ static bool ipv4_datagram_support_cmsg(const struct sock *sk, return false; /* Support IP_PKTINFO on tstamp packets if requested, to correlate - * timestamp with egress dev. Not possible for packets without dev + * timestamp with egress dev. Not possible for packets without iif * or without payload (SOF_TIMESTAMPING_OPT_TSONLY). */ - if ((!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) || - (!skb->dev)) + info = PKTINFO_SKB_CB(skb); + if (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG) || + !info->ipi_ifindex) return false; - info = PKTINFO_SKB_CB(skb); info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr; - info->ipi_ifindex = skb->dev->ifindex; return true; } diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index eec27f87efac..e011122ebd43 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -405,9 +405,6 @@ static inline bool ipv6_datagram_support_addr(struct sock_exterr_skb *serr) * At one point, excluding local errors was a quick test to identify icmp/icmp6 * errors. This is no longer true, but the test remained, so the v6 stack, * unlike v4, also honors cmsg requests on all wifi and timestamp errors. - * - * Timestamp code paths do not initialize the fields expected by cmsg: - * the PKTINFO fields in skb->cb[]. Fill those in here. */ static bool ip6_datagram_support_cmsg(struct sk_buff *skb, struct sock_exterr_skb *serr) @@ -419,14 +416,9 @@ static bool ip6_datagram_support_cmsg(struct sk_buff *skb, if (serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL) return false; - if (!skb->dev) + if (!IP6CB(skb)->iif) return false; - if (skb->protocol == htons(ETH_P_IPV6)) - IP6CB(skb)->iif = skb->dev->ifindex; - else - PKTINFO_SKB_CB(skb)->ipi_ifindex = skb->dev->ifindex; - return true; }