public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
* [PATCH 0/2] Fix buffer overrun in UDP setup (bug 80)
@ 2024-02-20  2:48 David Gibson
  2024-02-20  2:48 ` [PATCH 1/2] udp: Assertion in udp_invert_portmap() can be calculated at compile time David Gibson
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: David Gibson @ 2024-02-20  2:48 UTC (permalink / raw)
  To: passt-dev, Stefano Brivio; +Cc: jk, David Gibson

Laurent Jacquot pointed out another bug in UDP forwarding that turned
out to also be a nasty buffer overrun.  Fix that, and make a minor
cleanup alongside while we're at it.

Link: https://bugs.passt.top/show_bug.cgi?id=80

David Gibson (2):
  udp: Assertion in udp_invert_portmap() can be calculated at compile
    time
  udp: Fix 16-bit overflow in udp_invert_portmap()

 udp.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

-- 
2.43.2


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

* [PATCH 1/2] udp: Assertion in udp_invert_portmap() can be calculated at compile time
  2024-02-20  2:48 [PATCH 0/2] Fix buffer overrun in UDP setup (bug 80) David Gibson
@ 2024-02-20  2:48 ` David Gibson
  2024-02-20  2:48 ` [PATCH 2/2] udp: Fix 16-bit overflow in udp_invert_portmap() David Gibson
  2024-02-20  7:55 ` [PATCH 0/2] Fix buffer overrun in UDP setup (bug 80) Stefano Brivio
  2 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2024-02-20  2:48 UTC (permalink / raw)
  To: passt-dev, Stefano Brivio; +Cc: jk, David Gibson

All the values in this ASSERT() are known at compile time, so this can be
converted to a static_assert().

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 udp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/udp.c b/udp.c
index 933f24b8..c031a053 100644
--- a/udp.c
+++ b/udp.c
@@ -260,7 +260,8 @@ static void udp_invert_portmap(struct udp_port_fwd *fwd)
 {
 	int i;
 
-	ASSERT(ARRAY_SIZE(fwd->f.delta) == ARRAY_SIZE(fwd->rdelta));
+	static_assert(ARRAY_SIZE(fwd->f.delta) == ARRAY_SIZE(fwd->rdelta),
+		      "Forward and reverse delta arrays must have same size");
 	for (i = 0; i < ARRAY_SIZE(fwd->f.delta); i++) {
 		in_port_t delta = fwd->f.delta[i];
 
-- 
@@ -260,7 +260,8 @@ static void udp_invert_portmap(struct udp_port_fwd *fwd)
 {
 	int i;
 
-	ASSERT(ARRAY_SIZE(fwd->f.delta) == ARRAY_SIZE(fwd->rdelta));
+	static_assert(ARRAY_SIZE(fwd->f.delta) == ARRAY_SIZE(fwd->rdelta),
+		      "Forward and reverse delta arrays must have same size");
 	for (i = 0; i < ARRAY_SIZE(fwd->f.delta); i++) {
 		in_port_t delta = fwd->f.delta[i];
 
-- 
2.43.2


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

* [PATCH 2/2] udp: Fix 16-bit overflow in udp_invert_portmap()
  2024-02-20  2:48 [PATCH 0/2] Fix buffer overrun in UDP setup (bug 80) David Gibson
  2024-02-20  2:48 ` [PATCH 1/2] udp: Assertion in udp_invert_portmap() can be calculated at compile time David Gibson
@ 2024-02-20  2:48 ` David Gibson
  2024-02-20  7:55 ` [PATCH 0/2] Fix buffer overrun in UDP setup (bug 80) Stefano Brivio
  2 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2024-02-20  2:48 UTC (permalink / raw)
  To: passt-dev, Stefano Brivio; +Cc: jk, David Gibson

The code in udp_invert_portmap() is written based on an incorrect
understanding of C's (arcane) integer promotion rules.  We calculate
'(in_port_t)i + delta' expecting the result to be of type in_port_t (16
bits).  However "small integer types" (those narrower than 'int') are
always promoted to int for expressions, meaning this calculation can
overrun the rdelta[] array.

Fix this, and use a new intermediate for the index, to make it very clear
what it's type is.  We also change i to unsigned, to avoid any possible
confusion from mixing signed and unsigned types.

Link: https://bugs.passt.top/show_bug.cgi?id=80
Reported-by: Laurent Jacquot <jk@lutty.net>
Suggested-by: Laurent Jacquot <jk@lutty.net>

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 udp.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/udp.c b/udp.c
index c031a053..a3961bfd 100644
--- a/udp.c
+++ b/udp.c
@@ -258,15 +258,16 @@ void udp_portmap_clear(void)
  */
 static void udp_invert_portmap(struct udp_port_fwd *fwd)
 {
-	int i;
+	unsigned int i;
 
 	static_assert(ARRAY_SIZE(fwd->f.delta) == ARRAY_SIZE(fwd->rdelta),
 		      "Forward and reverse delta arrays must have same size");
 	for (i = 0; i < ARRAY_SIZE(fwd->f.delta); i++) {
 		in_port_t delta = fwd->f.delta[i];
+		in_port_t rport = i + delta;
 
 		if (delta)
-			fwd->rdelta[(in_port_t)i + delta] = NUM_PORTS - delta;
+			fwd->rdelta[rport] = NUM_PORTS - delta;
 	}
 }
 
-- 
@@ -258,15 +258,16 @@ void udp_portmap_clear(void)
  */
 static void udp_invert_portmap(struct udp_port_fwd *fwd)
 {
-	int i;
+	unsigned int i;
 
 	static_assert(ARRAY_SIZE(fwd->f.delta) == ARRAY_SIZE(fwd->rdelta),
 		      "Forward and reverse delta arrays must have same size");
 	for (i = 0; i < ARRAY_SIZE(fwd->f.delta); i++) {
 		in_port_t delta = fwd->f.delta[i];
+		in_port_t rport = i + delta;
 
 		if (delta)
-			fwd->rdelta[(in_port_t)i + delta] = NUM_PORTS - delta;
+			fwd->rdelta[rport] = NUM_PORTS - delta;
 	}
 }
 
-- 
2.43.2


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

* Re: [PATCH 0/2] Fix buffer overrun in UDP setup (bug 80)
  2024-02-20  2:48 [PATCH 0/2] Fix buffer overrun in UDP setup (bug 80) David Gibson
  2024-02-20  2:48 ` [PATCH 1/2] udp: Assertion in udp_invert_portmap() can be calculated at compile time David Gibson
  2024-02-20  2:48 ` [PATCH 2/2] udp: Fix 16-bit overflow in udp_invert_portmap() David Gibson
@ 2024-02-20  7:55 ` Stefano Brivio
  2 siblings, 0 replies; 4+ messages in thread
From: Stefano Brivio @ 2024-02-20  7:55 UTC (permalink / raw)
  To: David Gibson; +Cc: passt-dev, jk

On Tue, 20 Feb 2024 13:48:22 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> Laurent Jacquot pointed out another bug in UDP forwarding that turned
> out to also be a nasty buffer overrun.  Fix that, and make a minor
> cleanup alongside while we're at it.
> 
> Link: https://bugs.passt.top/show_bug.cgi?id=80
> 
> David Gibson (2):
>   udp: Assertion in udp_invert_portmap() can be calculated at compile
>     time
>   udp: Fix 16-bit overflow in udp_invert_portmap()

Applied.

-- 
Stefano


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

end of thread, other threads:[~2024-02-20  7:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-20  2:48 [PATCH 0/2] Fix buffer overrun in UDP setup (bug 80) David Gibson
2024-02-20  2:48 ` [PATCH 1/2] udp: Assertion in udp_invert_portmap() can be calculated at compile time David Gibson
2024-02-20  2:48 ` [PATCH 2/2] udp: Fix 16-bit overflow in udp_invert_portmap() David Gibson
2024-02-20  7:55 ` [PATCH 0/2] Fix buffer overrun in UDP setup (bug 80) Stefano Brivio

Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

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 IMAP folder(s).