From patchwork Fri Feb 8 13:15:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Alin_N=C4=83stac?= X-Patchwork-Id: 1038637 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="RPo0f3jx"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43wwfF4KLqz9sN6 for ; Sat, 9 Feb 2019 00:15:33 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726624AbfBHNPc (ORCPT ); Fri, 8 Feb 2019 08:15:32 -0500 Received: from mail-wm1-f65.google.com ([209.85.128.65]:55963 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726465AbfBHNPc (ORCPT ); Fri, 8 Feb 2019 08:15:32 -0500 Received: by mail-wm1-f65.google.com with SMTP id r17so3346859wmh.5 for ; Fri, 08 Feb 2019 05:15:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=NjTSEIWawl9M8lMxwFBMB0SNUuwU+Ywx8ap+J1hzs4U=; b=RPo0f3jx3r9HQetyHvhqWw35V1uE9SK5J3cMSr1dh62vSmyikDYqfu/yg+H9mEMz2X cFPHsT4KpcybaPqgwpH6ZoeK7/O0UN+P6baxrjO3cUfjKmtFWK8fvmdfVPVNREeQKI3l +YeNCvk6Ez+HVfTuzNM53mbw2AIow+Q/ntTFvMCeP/e9g/NNRD26kE2hO1NxXH80LVUn lBh1tVtQHZ4DlDolnXSDSzvpnOfPA36FOiI7/SXSqlKS5P4WmfFekRL1a73sxtKQ5ZeE nTYnS0Okq3/iXM9QhRVvx++1j0r0+bNZECgrt2LxibDlNAkB7jStVYJovluiFBjf8SFM 7Ksg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=NjTSEIWawl9M8lMxwFBMB0SNUuwU+Ywx8ap+J1hzs4U=; b=aU8NCw0mJ09xY3VNtGkFSLnm68dYpNcM8JOLIEk2gaaQtjhE0dDks/woKkxEgAyww+ xjaFWvydI4elFogQYh+BCF/xzFIZYDNpv9Y9CCucwMR27TzcEDPLBrNeyDXINgFitR4Y FioDuyGtlX0sf9UvQ/nvIX7zmtOkBYk5uv0d803W4KETDAHMaeEagcap7Uw1xMnQqU3Y b1Tn6ft+6X3vFVsqzdSzGneD7Oms5wgWDGZRtpT47lXuL8zG/1YpUCQYogXgsyawULwT rhO967vVw31+UmqH8fz4uRTEiFsBn+zXNxnOCKq8dR6BhUQ6ONwmmnZwkU8x+CqaMOL7 3E4g== X-Gm-Message-State: AHQUAubL8wJM806zif3snPE5q3Jvzw3LdDbiukn4FUY5LpOZTEdUqsEz ip7qTkqE0ALuMK+d8sw3ValSs3CVJtI= X-Google-Smtp-Source: AHgI3IadIBpJK+oWa5hQPy5kFcYpOXwNmjljB2NlgRwL5uBVt9hV3TFkdqnxLD2XRRcx5n60PxLQlw== X-Received: by 2002:a1c:f20a:: with SMTP id s10mr10233737wmc.123.1549631730340; Fri, 08 Feb 2019 05:15:30 -0800 (PST) Received: from cplx1037.edegem.eu.thmulti.com ([2001:4158:f012:b00:2a10:7bff:fec5:6f08]) by smtp.gmail.com with ESMTPSA id b18sm1638295wrw.83.2019.02.08.05.15.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 08 Feb 2019 05:15:29 -0800 (PST) From: Alin Nastac X-Google-Original-From: Alin Nastac To: Florian Westphal , netfilter-devel@vger.kernel.org Subject: [PATCH] netfilter: reject: skip csum verification for protocols that don't support it Date: Fri, 8 Feb 2019 14:15:24 +0100 Message-Id: <1549631724-20326-1-git-send-email-alin.nastac@technicolor.com> X-Mailer: git-send-email 2.7.4 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org From: Alin Nastac Some protocols have other means to verify the payload integrity (AH, ESP, SCTP) while others are incompatible with nf_ip(6)_checksum implementation because checksum is either optional or might be partial (UDPLITE, DCCP, GRE). Because nf_ip(6)_checksum was used to validate the packets, ip(6)tables REJECT rules were not capable to generate ICMP(v6) errors for the protocols mentioned above. This commit also fixes the incorrect pseudo-header protocol used for IPv4 packets that carry other transport protocols than TCP or UDP (pseudo-header used protocol 0 iso the proper value). Signed-off-by: Alin Nastac Acked-by: Florian Westphal --- net/ipv4/netfilter/nf_reject_ipv4.c | 33 ++++++++++++++++++++++++--------- net/ipv6/netfilter/nf_reject_ipv6.c | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c index aa8304c..9225b7f 100644 --- a/net/ipv4/netfilter/nf_reject_ipv4.c +++ b/net/ipv4/netfilter/nf_reject_ipv4.c @@ -178,18 +178,33 @@ void nf_send_unreach(struct sk_buff *skb_in, int code, int hook) if (iph->frag_off & htons(IP_OFFSET)) return; - if (skb_csum_unnecessary(skb_in)) { - icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0); - return; + if (skb_csum_unnecessary(skb_in)) + goto send_unreach; + + /* Skip checksum verification for protocols that don't use + * 16-bit one's complement checksum of the entire payload. + */ + proto = iph->protocol; + switch (proto) { + /* Protocols with other integrity checks. */ + case IPPROTO_AH: + case IPPROTO_ESP: + case IPPROTO_SCTP: + + /* Protocols with partial checksums. */ + case IPPROTO_UDPLITE: + case IPPROTO_DCCP: + + /* Protocols with optional checksums. */ + case IPPROTO_GRE: + goto send_unreach; } - if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP) - proto = iph->protocol; - else - proto = 0; + if (nf_ip_checksum(skb_in, hook, ip_hdrlen(skb_in), proto)) + return; - if (nf_ip_checksum(skb_in, hook, ip_hdrlen(skb_in), proto) == 0) - icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0); + send_unreach: + icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0); } EXPORT_SYMBOL_GPL(nf_send_unreach); diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c index b9c8a76..2af014e 100644 --- a/net/ipv6/netfilter/nf_reject_ipv6.c +++ b/net/ipv6/netfilter/nf_reject_ipv6.c @@ -233,6 +233,24 @@ static bool reject6_csum_ok(struct sk_buff *skb, int hook) if (thoff < 0 || thoff >= skb->len || (fo & htons(~0x7)) != 0) return false; + /* Skip protocols that don't use 16-bit one's complement checksum + * of the entire payload. + */ + switch (proto) { + /* Protocols with other integrity checks. */ + case IPPROTO_AH: + case IPPROTO_ESP: + case IPPROTO_SCTP: + + /* Protocols with partial checksums. */ + case IPPROTO_UDPLITE: + case IPPROTO_DCCP: + + /* Protocols with optional checksums. */ + case IPPROTO_GRE: + return true; + } + return nf_ip6_checksum(skb, hook, thoff, proto) == 0; }