netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Netfilter fixes for net
@ 2020-04-29 21:48 Pablo Neira Ayuso
  2020-04-29 21:48 ` [PATCH 1/2] netfilter: nat: never update the UDP checksum when it's 0 Pablo Neira Ayuso
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2020-04-29 21:48 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Hi David,

The following patchset contains Netfilter fixes for net:

1) Do not update the UDP checksum when it's zero, from Guillaume Nault.

2) Fix return of local variable in nf_osf, from Arnd Bergmann.

You can pull these changes from:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git

Thank you.

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

The following changes since commit 52a90612fa6108d20cffd3cf6a2c228e2f3619f7:

  net: remove obsolete comment (2020-04-25 20:49:32 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD

for you to fetch changes up to c165d57b552aaca607fa5daf3fb524a6efe3c5a3:

  netfilter: nf_osf: avoid passing pointer to local var (2020-04-29 21:17:57 +0200)

----------------------------------------------------------------
Arnd Bergmann (1):
      netfilter: nf_osf: avoid passing pointer to local var

Guillaume Nault (1):
      netfilter: nat: never update the UDP checksum when it's 0

 net/netfilter/nf_nat_proto.c  |  4 +---
 net/netfilter/nfnetlink_osf.c | 12 +++++++-----
 2 files changed, 8 insertions(+), 8 deletions(-)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] netfilter: nat: never update the UDP checksum when it's 0
  2020-04-29 21:48 [PATCH 0/2] Netfilter fixes for net Pablo Neira Ayuso
@ 2020-04-29 21:48 ` Pablo Neira Ayuso
  2020-04-29 21:48 ` [PATCH 2/2] netfilter: nf_osf: avoid passing pointer to local var Pablo Neira Ayuso
  2020-05-01  1:07 ` [PATCH 0/2] Netfilter fixes for net David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2020-04-29 21:48 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Guillaume Nault <gnault@redhat.com>

If the UDP header of a local VXLAN endpoint is NAT-ed, and the VXLAN
device has disabled UDP checksums and enabled Tx checksum offloading,
then the skb passed to udp_manip_pkt() has hdr->check == 0 (outer
checksum disabled) and skb->ip_summed == CHECKSUM_PARTIAL (inner packet
checksum offloaded).

Because of the ->ip_summed value, udp_manip_pkt() tries to update the
outer checksum with the new address and port, leading to an invalid
checksum sent on the wire, as the original null checksum obviously
didn't take the old address and port into account.

So, we can't take ->ip_summed into account in udp_manip_pkt(), as it
might not refer to the checksum we're acting on. Instead, we can base
the decision to update the UDP checksum entirely on the value of
hdr->check, because it's null if and only if checksum is disabled:

  * A fully computed checksum can't be 0, since a 0 checksum is
    represented by the CSUM_MANGLED_0 value instead.

  * A partial checksum can't be 0, since the pseudo-header always adds
    at least one non-zero value (the UDP protocol type 0x11) and adding
    more values to the sum can't make it wrap to 0 as the carry is then
    added to the wrapped number.

  * A disabled checksum uses the special value 0.

The problem seems to be there from day one, although it was probably
not visible before UDP tunnels were implemented.

Fixes: 5b1158e909ec ("[NETFILTER]: Add NAT support for nf_conntrack")
Signed-off-by: Guillaume Nault <gnault@redhat.com>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_nat_proto.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/netfilter/nf_nat_proto.c b/net/netfilter/nf_nat_proto.c
index 3d816a1e5442..59151dc07fdc 100644
--- a/net/netfilter/nf_nat_proto.c
+++ b/net/netfilter/nf_nat_proto.c
@@ -68,15 +68,13 @@ static bool udp_manip_pkt(struct sk_buff *skb,
 			  enum nf_nat_manip_type maniptype)
 {
 	struct udphdr *hdr;
-	bool do_csum;
 
 	if (skb_ensure_writable(skb, hdroff + sizeof(*hdr)))
 		return false;
 
 	hdr = (struct udphdr *)(skb->data + hdroff);
-	do_csum = hdr->check || skb->ip_summed == CHECKSUM_PARTIAL;
+	__udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, !!hdr->check);
 
-	__udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, do_csum);
 	return true;
 }
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] netfilter: nf_osf: avoid passing pointer to local var
  2020-04-29 21:48 [PATCH 0/2] Netfilter fixes for net Pablo Neira Ayuso
  2020-04-29 21:48 ` [PATCH 1/2] netfilter: nat: never update the UDP checksum when it's 0 Pablo Neira Ayuso
@ 2020-04-29 21:48 ` Pablo Neira Ayuso
  2020-05-01  1:07 ` [PATCH 0/2] Netfilter fixes for net David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2020-04-29 21:48 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Arnd Bergmann <arnd@arndb.de>

gcc-10 points out that a code path exists where a pointer to a stack
variable may be passed back to the caller:

net/netfilter/nfnetlink_osf.c: In function 'nf_osf_hdr_ctx_init':
cc1: warning: function may return address of local variable [-Wreturn-local-addr]
net/netfilter/nfnetlink_osf.c:171:16: note: declared here
  171 |  struct tcphdr _tcph;
      |                ^~~~~

I am not sure whether this can happen in practice, but moving the
variable declaration into the callers avoids the problem.

Fixes: 31a9c29210e2 ("netfilter: nf_osf: add struct nf_osf_hdr_ctx")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nfnetlink_osf.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index 9f5dea0064ea..916a3c7f9eaf 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -165,12 +165,12 @@ static bool nf_osf_match_one(const struct sk_buff *skb,
 static const struct tcphdr *nf_osf_hdr_ctx_init(struct nf_osf_hdr_ctx *ctx,
 						const struct sk_buff *skb,
 						const struct iphdr *ip,
-						unsigned char *opts)
+						unsigned char *opts,
+						struct tcphdr *_tcph)
 {
 	const struct tcphdr *tcp;
-	struct tcphdr _tcph;
 
-	tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &_tcph);
+	tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), _tcph);
 	if (!tcp)
 		return NULL;
 
@@ -205,10 +205,11 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
 	int fmatch = FMATCH_WRONG;
 	struct nf_osf_hdr_ctx ctx;
 	const struct tcphdr *tcp;
+	struct tcphdr _tcph;
 
 	memset(&ctx, 0, sizeof(ctx));
 
-	tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts);
+	tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts, &_tcph);
 	if (!tcp)
 		return false;
 
@@ -265,10 +266,11 @@ bool nf_osf_find(const struct sk_buff *skb,
 	const struct nf_osf_finger *kf;
 	struct nf_osf_hdr_ctx ctx;
 	const struct tcphdr *tcp;
+	struct tcphdr _tcph;
 
 	memset(&ctx, 0, sizeof(ctx));
 
-	tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts);
+	tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts, &_tcph);
 	if (!tcp)
 		return false;
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] Netfilter fixes for net
  2020-04-29 21:48 [PATCH 0/2] Netfilter fixes for net Pablo Neira Ayuso
  2020-04-29 21:48 ` [PATCH 1/2] netfilter: nat: never update the UDP checksum when it's 0 Pablo Neira Ayuso
  2020-04-29 21:48 ` [PATCH 2/2] netfilter: nf_osf: avoid passing pointer to local var Pablo Neira Ayuso
@ 2020-05-01  1:07 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2020-05-01  1:07 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed, 29 Apr 2020 23:48:09 +0200

> The following patchset contains Netfilter fixes for net:
> 
> 1) Do not update the UDP checksum when it's zero, from Guillaume Nault.
> 
> 2) Fix return of local variable in nf_osf, from Arnd Bergmann.
> 
> You can pull these changes from:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git

Pulled, thanks Pablo.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-01  1:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-29 21:48 [PATCH 0/2] Netfilter fixes for net Pablo Neira Ayuso
2020-04-29 21:48 ` [PATCH 1/2] netfilter: nat: never update the UDP checksum when it's 0 Pablo Neira Ayuso
2020-04-29 21:48 ` [PATCH 2/2] netfilter: nf_osf: avoid passing pointer to local var Pablo Neira Ayuso
2020-05-01  1:07 ` [PATCH 0/2] Netfilter fixes for net David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).