Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3718913pxv; Mon, 26 Jul 2021 10:10:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzK6kcwvqIzF9hEfDG5z1CU+9RuPjGU9Mp88IxqjELyIY5IxP+7oeozoKMNbBoqpmTZRqe1 X-Received: by 2002:a17:906:1f82:: with SMTP id t2mr17691583ejr.499.1627319402770; Mon, 26 Jul 2021 10:10:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627319402; cv=none; d=google.com; s=arc-20160816; b=mqS9SJcm9DXkHW2X3oS5LU4f8DQf5lASEQM/e498YHfJRtF37RFfIDlS26Q6P9XbI9 9+Cazcn7iO7MM1d47xz6amu1EHof/QAc5yhyvgppd3csUapBQg5tVydPodOt+y7wBJiw F1qANE++D6G7yXeN0fJ6hmuG8CHFEfRRBvNio4akB1WkP395HD7+2r9Ch7Ztv1uxpGbz Q9P8gEA6FrvZIoMcYt1c3hVWVq50xyLhEiY9EtC0sHvQGSXw2qS8jf1TxN8DoCCqbXFs lEJSflHCRok83lmLkQgB0rCQkBFX8kaVJg1f7XJVztMLb44dGr+/QS9IOGo072EtHQL0 o0mg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Vj8ZC2H/yZTtt9TTHVn+FRZ73tvTbIxw3togRjTwrII=; b=Qn/vagTPaF0i7wJnCCdb0CKcSNc64TAov3FkSs8oYy0zTF+eyR2s5eC9LElaEU6DCG K1pPz2dkUQaFNVzpqSoGo9KiQql8GKMfv/ICBO4NPSTc22bA2ifXI08i95ZsaIaQGyFi jNR7jev3LsVmqPqSyzLhEdni5RAsD1sNFWXcl6nbC1xKUwiFc8MtSzlzq3jK5h6Tak/M s401OVyBaF34YRqv5PJZnIt5wibQWwUXOjhISOZQ+znmRATQlrqZcvrCqk0XzCeKftZE rT/0+iYR1rCGMOa+U9UQiIFGu/4mmsJgmhBQBzkcs3DAcyb/NCNKErjuHJprZtbI3S/b jn+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=sCXWKFzk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id gg17si444804ejb.431.2021.07.26.10.09.36; Mon, 26 Jul 2021 10:10:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=sCXWKFzk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239494AbhGZPwx (ORCPT + 99 others); Mon, 26 Jul 2021 11:52:53 -0400 Received: from mail.kernel.org ([198.145.29.99]:48250 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233454AbhGZPcV (ORCPT ); Mon, 26 Jul 2021 11:32:21 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 3B0E36101B; Mon, 26 Jul 2021 16:12:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1627315954; bh=I+j1R7JFes5EQdh/y4KW7KPcG3dh0Su3NbH2GfjzllU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sCXWKFzkDgpce5jG6DfPGU1XSHLXUg/Dw3kVz5CV2Av6sW3vDklzC86Ie8a0Wh/cV aPYFXMBqnVk6oBzsHxe8OrZRTrP2nMfOgP7RWXap1AecRerUUSbcSNcoUXpwdhxGrl x6e98JUpcnVCoCErDauxhhIsYRSdJC5ptvNGAITQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Vadim Fedorenko , Xin Long , "David S. Miller" , Sasha Levin Subject: [PATCH 5.13 131/223] udp: check encap socket in __udp_lib_err Date: Mon, 26 Jul 2021 17:38:43 +0200 Message-Id: <20210726153850.535441761@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210726153846.245305071@linuxfoundation.org> References: <20210726153846.245305071@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vadim Fedorenko [ Upstream commit 9bfce73c8921c92a9565562e6e7d458d37b7ce80 ] Commit d26796ae5894 ("udp: check udp sock encap_type in __udp_lib_err") added checks for encapsulated sockets but it broke cases when there is no implementation of encap_err_lookup for encapsulation, i.e. ESP in UDP encapsulation. Fix it by calling encap_err_lookup only if socket implements this method otherwise treat it as legal socket. Fixes: d26796ae5894 ("udp: check udp sock encap_type in __udp_lib_err") Signed-off-by: Vadim Fedorenko Reviewed-by: Xin Long Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv4/udp.c | 25 +++++++++++++++++++------ net/ipv6/udp.c | 25 +++++++++++++++++++------ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ca9cf1051b1e..568dc31a0467 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -645,10 +645,12 @@ static struct sock *__udp4_lib_err_encap(struct net *net, const struct iphdr *iph, struct udphdr *uh, struct udp_table *udptable, + struct sock *sk, struct sk_buff *skb, u32 info) { + int (*lookup)(struct sock *sk, struct sk_buff *skb); int network_offset, transport_offset; - struct sock *sk; + struct udp_sock *up; network_offset = skb_network_offset(skb); transport_offset = skb_transport_offset(skb); @@ -659,18 +661,28 @@ static struct sock *__udp4_lib_err_encap(struct net *net, /* Transport header needs to point to the UDP header */ skb_set_transport_header(skb, iph->ihl << 2); + if (sk) { + up = udp_sk(sk); + + lookup = READ_ONCE(up->encap_err_lookup); + if (lookup && lookup(sk, skb)) + sk = NULL; + + goto out; + } + sk = __udp4_lib_lookup(net, iph->daddr, uh->source, iph->saddr, uh->dest, skb->dev->ifindex, 0, udptable, NULL); if (sk) { - int (*lookup)(struct sock *sk, struct sk_buff *skb); - struct udp_sock *up = udp_sk(sk); + up = udp_sk(sk); lookup = READ_ONCE(up->encap_err_lookup); if (!lookup || lookup(sk, skb)) sk = NULL; } +out: if (!sk) sk = ERR_PTR(__udp4_lib_err_encap_no_sk(skb, info)); @@ -707,15 +719,16 @@ int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) sk = __udp4_lib_lookup(net, iph->daddr, uh->dest, iph->saddr, uh->source, skb->dev->ifindex, inet_sdif(skb), udptable, NULL); + if (!sk || udp_sk(sk)->encap_type) { /* No socket for error: try tunnels before discarding */ - sk = ERR_PTR(-ENOENT); if (static_branch_unlikely(&udp_encap_needed_key)) { - sk = __udp4_lib_err_encap(net, iph, uh, udptable, skb, + sk = __udp4_lib_err_encap(net, iph, uh, udptable, sk, skb, info); if (!sk) return 0; - } + } else + sk = ERR_PTR(-ENOENT); if (IS_ERR(sk)) { __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 6774e776228c..2d3bd4a9b0d0 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -502,12 +502,14 @@ static struct sock *__udp6_lib_err_encap(struct net *net, const struct ipv6hdr *hdr, int offset, struct udphdr *uh, struct udp_table *udptable, + struct sock *sk, struct sk_buff *skb, struct inet6_skb_parm *opt, u8 type, u8 code, __be32 info) { + int (*lookup)(struct sock *sk, struct sk_buff *skb); int network_offset, transport_offset; - struct sock *sk; + struct udp_sock *up; network_offset = skb_network_offset(skb); transport_offset = skb_transport_offset(skb); @@ -518,18 +520,28 @@ static struct sock *__udp6_lib_err_encap(struct net *net, /* Transport header needs to point to the UDP header */ skb_set_transport_header(skb, offset); + if (sk) { + up = udp_sk(sk); + + lookup = READ_ONCE(up->encap_err_lookup); + if (lookup && lookup(sk, skb)) + sk = NULL; + + goto out; + } + sk = __udp6_lib_lookup(net, &hdr->daddr, uh->source, &hdr->saddr, uh->dest, inet6_iif(skb), 0, udptable, skb); if (sk) { - int (*lookup)(struct sock *sk, struct sk_buff *skb); - struct udp_sock *up = udp_sk(sk); + up = udp_sk(sk); lookup = READ_ONCE(up->encap_err_lookup); if (!lookup || lookup(sk, skb)) sk = NULL; } +out: if (!sk) { sk = ERR_PTR(__udp6_lib_err_encap_no_sk(skb, opt, type, code, offset, info)); @@ -558,16 +570,17 @@ int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, inet6_iif(skb), inet6_sdif(skb), udptable, NULL); + if (!sk || udp_sk(sk)->encap_type) { /* No socket for error: try tunnels before discarding */ - sk = ERR_PTR(-ENOENT); if (static_branch_unlikely(&udpv6_encap_needed_key)) { sk = __udp6_lib_err_encap(net, hdr, offset, uh, - udptable, skb, + udptable, sk, skb, opt, type, code, info); if (!sk) return 0; - } + } else + sk = ERR_PTR(-ENOENT); if (IS_ERR(sk)) { __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), -- 2.30.2